mongo_mapper 0.5.6 → 0.5.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. data/.gitignore +3 -1
  2. data/README.rdoc +3 -0
  3. data/VERSION +1 -1
  4. data/lib/mongo_mapper.rb +14 -6
  5. data/lib/mongo_mapper/associations.rb +11 -5
  6. data/lib/mongo_mapper/associations/base.rb +17 -5
  7. data/lib/mongo_mapper/associations/many_documents_as_proxy.rb +0 -2
  8. data/lib/mongo_mapper/associations/many_documents_proxy.rb +15 -15
  9. data/lib/mongo_mapper/associations/many_embedded_polymorphic_proxy.rb +2 -2
  10. data/lib/mongo_mapper/associations/many_polymorphic_proxy.rb +1 -1
  11. data/lib/mongo_mapper/associations/proxy.rb +1 -0
  12. data/lib/mongo_mapper/callbacks.rb +18 -0
  13. data/lib/mongo_mapper/document.rb +206 -89
  14. data/lib/mongo_mapper/dynamic_finder.rb +1 -1
  15. data/lib/mongo_mapper/embedded_document.rb +7 -3
  16. data/lib/mongo_mapper/finder_options.rb +87 -66
  17. data/lib/mongo_mapper/pagination.rb +2 -0
  18. data/lib/mongo_mapper/serialization.rb +2 -3
  19. data/lib/mongo_mapper/serializers/json_serializer.rb +1 -1
  20. data/lib/mongo_mapper/support.rb +9 -0
  21. data/lib/mongo_mapper/validations.rb +3 -1
  22. data/mongo_mapper.gemspec +4 -4
  23. data/test/functional/associations/test_many_documents_as_proxy.rb +2 -2
  24. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +25 -1
  25. data/test/functional/associations/test_many_embedded_proxy.rb +25 -0
  26. data/test/functional/associations/test_many_polymorphic_proxy.rb +48 -6
  27. data/test/functional/associations/test_many_proxy.rb +27 -6
  28. data/test/functional/test_document.rb +49 -29
  29. data/test/functional/test_pagination.rb +17 -17
  30. data/test/functional/test_validations.rb +35 -14
  31. data/test/models.rb +85 -10
  32. data/test/support/{test_timing.rb → timing.rb} +1 -1
  33. data/test/test_helper.rb +8 -8
  34. data/test/unit/test_association_base.rb +17 -0
  35. data/test/unit/test_document.rb +12 -1
  36. data/test/unit/test_embedded_document.rb +13 -4
  37. data/test/unit/test_finder_options.rb +50 -48
  38. data/test/unit/test_pagination.rb +4 -0
  39. metadata +4 -4
@@ -215,7 +215,7 @@ class ManyProxyTest < Test::Unit::TestCase
215
215
  end
216
216
 
217
217
  should "work with conditions" do
218
- statuses = @project1.statuses.find(:all, :conditions => {'name' => 'Complete'})
218
+ statuses = @project1.statuses.find(:all, :name => 'Complete')
219
219
  statuses.should == [@complete]
220
220
  end
221
221
 
@@ -231,7 +231,7 @@ class ManyProxyTest < Test::Unit::TestCase
231
231
  end
232
232
 
233
233
  should "work with conditions" do
234
- statuses = @project1.statuses.all(:conditions => {'name' => 'Complete'})
234
+ statuses = @project1.statuses.all(:name => 'Complete')
235
235
  statuses.should == [@complete]
236
236
  end
237
237
 
@@ -247,7 +247,7 @@ class ManyProxyTest < Test::Unit::TestCase
247
247
  end
248
248
 
249
249
  should "work with conditions" do
250
- status = @project1.statuses.find(:first, :conditions => {:name => 'Complete'})
250
+ status = @project1.statuses.find(:first, :name => 'Complete')
251
251
  status.should == @complete
252
252
  end
253
253
  end
@@ -258,7 +258,7 @@ class ManyProxyTest < Test::Unit::TestCase
258
258
  end
259
259
 
260
260
  should "work with conditions" do
261
- status = @project1.statuses.first(:conditions => {:name => 'Complete'})
261
+ status = @project1.statuses.first(:name => 'Complete')
262
262
  status.should == @complete
263
263
  end
264
264
  end
@@ -269,7 +269,7 @@ class ManyProxyTest < Test::Unit::TestCase
269
269
  end
270
270
 
271
271
  should "work with conditions" do
272
- status = @project1.statuses.find(:last, :order => 'position', :conditions => {:name => 'New'})
272
+ status = @project1.statuses.find(:last, :order => 'position', :name => 'New')
273
273
  status.should == @brand_new
274
274
  end
275
275
  end
@@ -280,7 +280,7 @@ class ManyProxyTest < Test::Unit::TestCase
280
280
  end
281
281
 
282
282
  should "work with conditions" do
283
- status = @project1.statuses.last(:order => 'position', :conditions => {:name => 'New'})
283
+ status = @project1.statuses.last(:order => 'position', :name => 'New')
284
284
  status.should == @brand_new
285
285
  end
286
286
  end
@@ -328,4 +328,25 @@ class ManyProxyTest < Test::Unit::TestCase
328
328
  end
329
329
  end
330
330
  end
331
+
332
+ context "extending the association" do
333
+ should "work using a block passed to many" do
334
+ project = Project.new(:name => "Some Project")
335
+ status1 = Status.new(:name => "New")
336
+ status2 = Status.new(:name => "Assigned")
337
+ status3 = Status.new(:name => "Closed")
338
+ project.statuses = [status1, status2, status3]
339
+ project.save
340
+ project.statuses.open.should == [status1, status2]
341
+ end
342
+
343
+ should "work using many's :extend option" do
344
+ project = Project.new(:name => "Some Project")
345
+ collaborator1 = Collaborator.new(:name => "zing")
346
+ collaborator2 = Collaborator.new(:name => "zang")
347
+ project.collaborators = [collaborator1, collaborator2]
348
+ project.save
349
+ project.collaborators.top.should == collaborator1
350
+ end
351
+ end
331
352
  end
@@ -298,7 +298,9 @@ class DocumentTest < Test::Unit::TestCase
298
298
  end
299
299
 
300
300
  should "raise error if document not found" do
301
- lambda { @document.find(123) }.should raise_error(MongoMapper::DocumentNotFound)
301
+ lambda {
302
+ @document.find(123)
303
+ }.should raise_error(MongoMapper::DocumentNotFound)
302
304
  end
303
305
  end
304
306
 
@@ -327,14 +329,14 @@ class DocumentTest < Test::Unit::TestCase
327
329
  end
328
330
 
329
331
  should "be able to add conditions" do
330
- @document.find(:all, :conditions => {:first_name => 'John'}).should == [@doc1]
332
+ @document.find(:all, :first_name => 'John').should == [@doc1]
331
333
  end
332
334
  end
333
335
 
334
336
  context "with #all" do
335
337
  should "find all documents based on criteria" do
336
338
  @document.all(:order => 'first_name').should == [@doc1, @doc3, @doc2]
337
- @document.all(:conditions => {:last_name => 'Nunemaker'}, :order => 'age desc').should == [@doc1, @doc3]
339
+ @document.all(:last_name => 'Nunemaker', :order => 'age desc').should == [@doc1, @doc3]
338
340
  end
339
341
  end
340
342
 
@@ -347,7 +349,7 @@ class DocumentTest < Test::Unit::TestCase
347
349
  context "with #first" do
348
350
  should "find first document based on criteria" do
349
351
  @document.first(:order => 'first_name').should == @doc1
350
- @document.first(:conditions => {:age => 28}).should == @doc2
352
+ @document.first(:age => 28).should == @doc2
351
353
  end
352
354
  end
353
355
 
@@ -360,7 +362,7 @@ class DocumentTest < Test::Unit::TestCase
360
362
  context "with #last" do
361
363
  should "find last document based on criteria" do
362
364
  @document.last(:order => 'age').should == @doc2
363
- @document.last(:order => 'age', :conditions => {:age => 28}).should == @doc2
365
+ @document.last(:order => 'age', :age => 28).should == @doc2
364
366
  end
365
367
 
366
368
  should "raise error if no order provided" do
@@ -735,8 +737,8 @@ class DocumentTest < Test::Unit::TestCase
735
737
  should "allow creating index on multiple keys" do
736
738
  @document.ensure_index [[:first_name, 1], [:last_name, -1]]
737
739
  MongoMapper.ensure_indexes!
738
-
739
- # order is different for different versions of ruby so instead of
740
+
741
+ # order is different for different versions of ruby so instead of
740
742
  # just checking have_index('first_name_1_last_name_-1') I'm checking
741
743
  # the values of the indexes to make sure the index creation was successful
742
744
  @document.collection.index_information.detect do |index|
@@ -951,11 +953,11 @@ class DocumentTest < Test::Unit::TestCase
951
953
  key :name, String
952
954
  end
953
955
  DocParent.collection.clear
954
-
956
+
955
957
  class ::DocDaughter < ::DocParent; end
956
958
  class ::DocSon < ::DocParent; end
957
959
  class ::DocGrandSon < ::DocSon; end
958
-
960
+
959
961
  @parent = DocParent.new({:name => "Daddy Warbucks"})
960
962
  @daughter = DocDaughter.new({:name => "Little Orphan Annie"})
961
963
  end
@@ -979,7 +981,7 @@ class DocumentTest < Test::Unit::TestCase
979
981
  should "load the document with the assigned type" do
980
982
  @parent.save
981
983
  @daughter.save
982
-
984
+
983
985
  collection = DocParent.find(:all)
984
986
  collection.size.should == 2
985
987
  collection.first.should be_kind_of(DocParent)
@@ -997,92 +999,98 @@ class DocumentTest < Test::Unit::TestCase
997
999
  collection.last.should == doc
998
1000
  collection.last.should be_kind_of(DocParent)
999
1001
  end
1000
-
1002
+
1001
1003
  should "find scoped to class" do
1002
1004
  john = DocSon.create(:name => 'John')
1003
1005
  steve = DocSon.create(:name => 'Steve')
1004
1006
  steph = DocDaughter.create(:name => 'Steph')
1005
1007
  carrie = DocDaughter.create(:name => 'Carrie')
1006
-
1008
+
1007
1009
  DocGrandSon.all(:order => 'name').should == []
1008
1010
  DocSon.all(:order => 'name').should == [john, steve]
1009
1011
  DocDaughter.all(:order => 'name').should == [carrie, steph]
1010
1012
  DocParent.all(:order => 'name').should == [carrie, john, steph, steve]
1011
1013
  end
1012
1014
 
1015
+ should "work with nested hash conditions" do
1016
+ john = DocSon.create(:name => 'John')
1017
+ steve = DocSon.create(:name => 'Steve')
1018
+ DocSon.all(:name => {'$ne' => 'Steve'}).should == [john]
1019
+ end
1020
+
1013
1021
  should "raise error if not found scoped to class" do
1014
1022
  john = DocSon.create(:name => 'John')
1015
1023
  steph = DocDaughter.create(:name => 'Steph')
1016
-
1024
+
1017
1025
  lambda {
1018
1026
  DocSon.find(steph.id)
1019
1027
  }.should raise_error(MongoMapper::DocumentNotFound)
1020
1028
  end
1021
-
1029
+
1022
1030
  should "not raise error for find with parent" do
1023
1031
  john = DocSon.create(:name => 'John')
1024
-
1032
+
1025
1033
  DocParent.find(john.id).should == john
1026
1034
  end
1027
-
1035
+
1028
1036
  should "count scoped to class" do
1029
1037
  john = DocSon.create(:name => 'John')
1030
1038
  steve = DocSon.create(:name => 'Steve')
1031
1039
  steph = DocDaughter.create(:name => 'Steph')
1032
1040
  carrie = DocDaughter.create(:name => 'Carrie')
1033
-
1041
+
1034
1042
  DocGrandSon.count.should == 0
1035
1043
  DocSon.count.should == 2
1036
1044
  DocDaughter.count.should == 2
1037
1045
  DocParent.count.should == 4
1038
1046
  end
1039
-
1047
+
1040
1048
  should "know if it is single_collection_inherited?" do
1041
1049
  DocParent.single_collection_inherited?.should be_false
1042
-
1050
+
1043
1051
  DocDaughter.single_collection_inherited?.should be_true
1044
1052
  DocSon.single_collection_inherited?.should be_true
1045
1053
  end
1046
-
1054
+
1047
1055
  should "know if single_collection_inherited_superclass?" do
1048
1056
  DocParent.single_collection_inherited_superclass?.should be_false
1049
-
1057
+
1050
1058
  DocDaughter.single_collection_inherited_superclass?.should be_true
1051
1059
  DocSon.single_collection_inherited_superclass?.should be_true
1052
1060
  DocGrandSon.single_collection_inherited_superclass?.should be_true
1053
1061
  end
1054
-
1062
+
1055
1063
  should "not be able to destroy each other" do
1056
1064
  john = DocSon.create(:name => 'John')
1057
1065
  steph = DocDaughter.create(:name => 'Steph')
1058
-
1066
+
1059
1067
  lambda {
1060
1068
  DocSon.destroy(steph.id)
1061
1069
  }.should raise_error(MongoMapper::DocumentNotFound)
1062
1070
  end
1063
-
1071
+
1064
1072
  should "not be able to delete each other" do
1065
1073
  john = DocSon.create(:name => 'John')
1066
1074
  steph = DocDaughter.create(:name => 'Steph')
1067
-
1075
+
1068
1076
  lambda {
1069
1077
  DocSon.delete(steph.id)
1070
1078
  }.should_not change { DocParent.count }
1071
1079
  end
1072
-
1080
+
1073
1081
  should "be able to destroy using parent" do
1074
1082
  john = DocSon.create(:name => 'John')
1075
1083
  steph = DocDaughter.create(:name => 'Steph')
1076
-
1084
+
1077
1085
  lambda {
1078
1086
  DocParent.destroy_all
1079
1087
  }.should change { DocParent.count }.by(-2)
1080
1088
  end
1081
-
1089
+
1082
1090
  should "be able to delete using parent" do
1083
1091
  john = DocSon.create(:name => 'John')
1084
1092
  steph = DocDaughter.create(:name => 'Steph')
1085
-
1093
+
1086
1094
  lambda {
1087
1095
  DocParent.delete_all
1088
1096
  }.should change { DocParent.count }.by(-2)
@@ -1154,4 +1162,16 @@ class DocumentTest < Test::Unit::TestCase
1154
1162
  @document.exists?(:first_name => "Jean").should == false
1155
1163
  end
1156
1164
  end
1165
+
1166
+ context "reload" do
1167
+ setup do
1168
+ @doc_instance_1 = @document.create({:first_name => 'Ryan', :last_name => 'Koopmans', :age => '37'})
1169
+ @doc_instance_2 = @document.update(@doc_instance_1.id, {:age => '39'})
1170
+ end
1171
+
1172
+ should "load fresh information from the database" do
1173
+ @doc_instance_1.age.should == 37
1174
+ @doc_instance_1.reload.age.should == 39
1175
+ end
1176
+ end
1157
1177
  end
@@ -43,41 +43,41 @@ class PaginationTest < Test::Unit::TestCase
43
43
 
44
44
  should "accept conditions" do
45
45
  result = @document.paginate({
46
- :conditions => {:last_name => 'Nunemaker'},
47
- :order => "age DESC",
48
- :per_page => 2,
49
- :page => 1,
46
+ :last_name => 'Nunemaker',
47
+ :order => "age DESC",
48
+ :per_page => 2,
49
+ :page => 1,
50
50
  })
51
51
  result.should == [@doc1, @doc3]
52
52
  result.first.age.should == 27
53
53
  end
54
54
 
55
- should "withstand rigor" do
55
+ should "withstand rigor" do
56
56
  result = @document.paginate({
57
- :per_page => 1,
58
- :page => 1,
59
- :order => 'age desc',
60
- :conditions => {:last_name => 'Nunemaker'}
57
+ :per_page => 1,
58
+ :page => 1,
59
+ :order => 'age desc',
60
+ :last_name => 'Nunemaker'
61
61
  })
62
62
  result.should == [@doc1]
63
63
  result.total_entries.should == 2
64
64
  result.total_pages.should == 2
65
65
 
66
66
  result = @document.paginate({
67
- :per_page => 1,
68
- :page => 2,
69
- :order => 'age desc',
70
- :conditions => {:last_name => 'Nunemaker'}
67
+ :per_page => 1,
68
+ :page => 2,
69
+ :order => 'age desc',
70
+ :last_name => 'Nunemaker'
71
71
  })
72
72
  result.should == [@doc3]
73
73
  result.total_entries.should == 2
74
74
  result.total_pages.should == 2
75
75
 
76
76
  result = @document.paginate({
77
- :per_page => 2,
78
- :page => 1,
79
- :order => 'age desc',
80
- :conditions => {:last_name => 'Nunemaker'}
77
+ :per_page => 2,
78
+ :page => 1,
79
+ :order => 'age desc',
80
+ :last_name => 'Nunemaker'
81
81
  })
82
82
  result.should == [@doc1, @doc3]
83
83
  result.total_entries.should == 2
@@ -170,8 +170,8 @@ class ValidationsTest < Test::Unit::TestCase
170
170
  doc.save.should be_true
171
171
 
172
172
  @document \
173
- .stubs(:find) \
174
- .with(:first, :conditions => {:name => 'joe'}, :limit => 1) \
173
+ .stubs(:first) \
174
+ .with(:name => 'joe') \
175
175
  .returns(doc)
176
176
 
177
177
  doc.name = "joe"
@@ -184,14 +184,35 @@ class ValidationsTest < Test::Unit::TestCase
184
184
  doc.save.should be_true
185
185
 
186
186
  @document \
187
- .stubs(:find) \
188
- .with(:first, :conditions => {:name => 'joe'}, :limit => 1) \
187
+ .stubs(:first) \
188
+ .with(:name => 'joe') \
189
189
  .returns(doc)
190
190
 
191
191
  doc2 = @document.new("name" => "joe")
192
192
  doc2.should have_error_on(:name)
193
193
  end
194
194
 
195
+ should "allow multiple blank entries if :allow_blank => true" do
196
+ document = Class.new do
197
+ include MongoMapper::Document
198
+ set_collection_name 'test'
199
+
200
+ key :name
201
+ validates_uniqueness_of :name, :allow_blank => :true
202
+ end
203
+
204
+ doc = document.new("name" => "")
205
+ doc.save.should be_true
206
+
207
+ document \
208
+ .stubs(:first) \
209
+ .with(:name => '') \
210
+ .returns(doc)
211
+
212
+ doc2 = document.new("name" => "")
213
+ doc2.should_not have_error_on(:name)
214
+ end
215
+
195
216
  context "scoped by a single attribute" do
196
217
  setup do
197
218
  @document = Class.new do
@@ -210,8 +231,8 @@ class ValidationsTest < Test::Unit::TestCase
210
231
  doc.save.should be_true
211
232
 
212
233
  @document \
213
- .stubs(:find) \
214
- .with(:first, :conditions => {:name => 'joe', :scope => "one"}, :limit => 1) \
234
+ .stubs(:first) \
235
+ .with(:name => 'joe', :scope => "one") \
215
236
  .returns(doc)
216
237
 
217
238
  doc2 = @document.new("name" => "joe", "scope" => "one")
@@ -223,8 +244,8 @@ class ValidationsTest < Test::Unit::TestCase
223
244
  doc.save.should be_true
224
245
 
225
246
  @document \
226
- .stubs(:find) \
227
- .with(:first, :conditions => {:name => 'joe', :scope => "two"}, :limit => 1) \
247
+ .stubs(:first) \
248
+ .with(:name => 'joe', :scope => 'two') \
228
249
  .returns(nil)
229
250
 
230
251
  doc2 = @document.new("name" => "joe", "scope" => "two")
@@ -251,8 +272,8 @@ class ValidationsTest < Test::Unit::TestCase
251
272
  doc.save.should be_true
252
273
 
253
274
  @document \
254
- .stubs(:find) \
255
- .with(:first, :conditions => {:name => 'joe', :first_scope => "one", :second_scope => "two"}, :limit => 1) \
275
+ .stubs(:first) \
276
+ .with(:name => 'joe', :first_scope => 'one', :second_scope => 'two') \
256
277
  .returns(doc)
257
278
 
258
279
  doc2 = @document.new("name" => "joe", "first_scope" => "one", "second_scope" => "two")
@@ -264,8 +285,8 @@ class ValidationsTest < Test::Unit::TestCase
264
285
  doc.save.should be_true
265
286
 
266
287
  @document \
267
- .stubs(:find) \
268
- .with(:first, :conditions => {:name => 'joe', :first_scope => "one", :second_scope => "one"}, :limit => 1) \
288
+ .stubs(:first) \
289
+ .with(:name => 'joe', :first_scope => 'one', :second_scope => 'one') \
269
290
  .returns(nil)
270
291
 
271
292
  doc2 = @document.new("name" => "joe", "first_scope" => "one", "second_scope" => "one")
@@ -288,8 +309,8 @@ class ValidationsTest < Test::Unit::TestCase
288
309
  doc.should_not have_error_on(:name)
289
310
 
290
311
  @document \
291
- .stubs(:find) \
292
- .with(:first, :conditions => {:name => 'John'}, :limit => 1) \
312
+ .stubs(:first) \
313
+ .with(:name => 'John') \
293
314
  .returns(doc)
294
315
 
295
316
  second_john = @document.create(:name => 'John')
@@ -23,14 +23,13 @@ class WindowSize
23
23
  end
24
24
  end
25
25
 
26
-
27
26
  class Post
28
27
  include MongoMapper::Document
29
28
 
30
29
  key :title, String
31
30
  key :body, String
32
31
 
33
- has_many :comments, :as => :commentable, :class_name => 'PostComment'
32
+ many :comments, :as => :commentable, :class_name => 'PostComment'
34
33
 
35
34
  timestamps!
36
35
  end
@@ -72,11 +71,36 @@ class Enter < Message; end
72
71
  class Exit < Message; end
73
72
  class Chat < Message; end
74
73
 
74
+ module AccountsExtensions
75
+ def inactive
76
+ all(:last_logged_in => nil)
77
+ end
78
+ end
79
+
80
+ class Account
81
+ include MongoMapper::Document
82
+
83
+ key :_type, String
84
+ key :room_id, String
85
+ key :last_logged_in, Time
86
+
87
+ belongs_to :room
88
+ end
89
+ class User < Account; end
90
+ class Bot < Account; end
91
+
75
92
  class Room
76
93
  include MongoMapper::Document
77
94
 
78
95
  key :name, String
79
- many :messages, :polymorphic => true
96
+ many :messages, :polymorphic => true do
97
+ def older
98
+ all(:position => {'$gt' => 5})
99
+ end
100
+ end
101
+ many :latest_messages, :class_name => 'Message', :order => 'position desc', :limit => 2
102
+
103
+ many :accounts, :polymorphic => true, :extend => AccountsExtensions
80
104
  end
81
105
 
82
106
  class Answer
@@ -89,8 +113,40 @@ class Project
89
113
  include MongoMapper::Document
90
114
 
91
115
  key :name, String
92
- many :statuses
93
- many :addresses
116
+
117
+ module PeopleExtensions
118
+ def find_by_name(name)
119
+ detect { |p| p.name == name }
120
+ end
121
+ end
122
+ many :people, :extend => PeopleExtensions
123
+
124
+ module CollaboratorsExtensions
125
+ def top
126
+ first
127
+ end
128
+ end
129
+ many :collaborators, :extend => CollaboratorsExtensions
130
+
131
+ many :statuses, :order => 'position' do
132
+ def open
133
+ all(:name => %w(New Assigned))
134
+ end
135
+ end
136
+
137
+ many :addresses do
138
+ def find_all_by_state(state)
139
+ # can't use select here for some reason
140
+ find_all { |a| a.state == state }
141
+ end
142
+ end
143
+ end
144
+
145
+ class Collaborator
146
+ include MongoMapper::Document
147
+ key :project_id, String
148
+ key :name, String
149
+ belongs_to :project
94
150
  end
95
151
 
96
152
  class Status
@@ -109,9 +165,13 @@ end
109
165
  class RealPerson
110
166
  include MongoMapper::Document
111
167
 
112
- many :pets
168
+ key :room_id, String
113
169
  key :name, String
114
-
170
+
171
+ belongs_to :room
172
+
173
+ many :pets
174
+
115
175
  def realname=(n)
116
176
  self.name = n
117
177
  end
@@ -138,6 +198,8 @@ class Media
138
198
 
139
199
  key :_type, String
140
200
  key :file, String
201
+
202
+ key :visible, Boolean
141
203
  end
142
204
 
143
205
  class Video < Media
@@ -155,8 +217,13 @@ end
155
217
 
156
218
  class Catalog
157
219
  include MongoMapper::Document
158
-
159
- many :medias, :polymorphic => true
220
+
221
+ many :medias, :polymorphic => true do
222
+ def visible
223
+ # for some reason we can't use select here
224
+ find_all { |m| m.visible? }
225
+ end
226
+ end
160
227
  end
161
228
 
162
229
  module TrModels
@@ -165,6 +232,7 @@ module TrModels
165
232
 
166
233
  key :_type, String
167
234
  key :license_plate, String
235
+ key :purchased_on, Date
168
236
  end
169
237
 
170
238
  class Car < TrModels::Transport
@@ -189,7 +257,14 @@ module TrModels
189
257
  class Fleet
190
258
  include MongoMapper::Document
191
259
 
192
- many :transports, :polymorphic => true, :class_name => "TrModels::Transport"
260
+ module TransportsExtension
261
+ def to_be_replaced
262
+ # for some reason we can't use select
263
+ find_all { |t| t.purchased_on < 2.years.ago.to_date }
264
+ end
265
+ end
266
+
267
+ many :transports, :polymorphic => true, :class_name => "TrModels::Transport", :extend => TransportsExtension
193
268
  key :name, String
194
269
  end
195
270
  end