mongo_mapper 0.14.0 → 0.15.4
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.
- checksums.yaml +5 -5
- data/LICENSE +1 -1
- data/README.md +72 -0
- data/examples/keys.rb +1 -1
- data/examples/modifiers/set.rb +1 -1
- data/examples/querying.rb +1 -1
- data/examples/safe.rb +2 -2
- data/examples/scopes.rb +1 -1
- data/lib/mongo_mapper.rb +19 -17
- data/lib/mongo_mapper/connection.rb +16 -38
- data/lib/mongo_mapper/extensions/array.rb +1 -1
- data/lib/mongo_mapper/extensions/binary.rb +1 -1
- data/lib/mongo_mapper/extensions/date.rb +1 -1
- data/lib/mongo_mapper/extensions/float.rb +1 -1
- data/lib/mongo_mapper/extensions/hash.rb +1 -1
- data/lib/mongo_mapper/extensions/nil_class.rb +2 -2
- data/lib/mongo_mapper/extensions/object.rb +1 -1
- data/lib/mongo_mapper/extensions/object_id.rb +6 -2
- data/lib/mongo_mapper/extensions/set.rb +1 -1
- data/lib/mongo_mapper/extensions/string.rb +1 -1
- data/lib/mongo_mapper/plugins/accessible.rb +1 -1
- data/lib/mongo_mapper/plugins/associations/base.rb +10 -2
- data/lib/mongo_mapper/plugins/associations/belongs_to_association.rb +1 -1
- data/lib/mongo_mapper/plugins/associations/many_association.rb +6 -5
- data/lib/mongo_mapper/plugins/associations/{belongs_to_polymorphic_proxy.rb → proxy/belongs_to_polymorphic_proxy.rb} +0 -0
- data/lib/mongo_mapper/plugins/associations/{belongs_to_proxy.rb → proxy/belongs_to_proxy.rb} +6 -0
- data/lib/mongo_mapper/plugins/associations/proxy/collection.rb +55 -0
- data/lib/mongo_mapper/plugins/associations/{embedded_collection.rb → proxy/embedded_collection.rb} +0 -0
- data/lib/mongo_mapper/plugins/associations/{in_array_proxy.rb → proxy/in_array_proxy.rb} +36 -6
- data/lib/mongo_mapper/plugins/associations/proxy/in_foreign_array_proxy.rb +136 -0
- data/lib/mongo_mapper/plugins/associations/{many_documents_as_proxy.rb → proxy/many_documents_as_proxy.rb} +0 -0
- data/lib/mongo_mapper/plugins/associations/{many_documents_proxy.rb → proxy/many_documents_proxy.rb} +0 -4
- data/lib/mongo_mapper/plugins/associations/{many_embedded_polymorphic_proxy.rb → proxy/many_embedded_polymorphic_proxy.rb} +0 -0
- data/lib/mongo_mapper/plugins/associations/{many_embedded_proxy.rb → proxy/many_embedded_proxy.rb} +0 -0
- data/lib/mongo_mapper/plugins/associations/{many_polymorphic_proxy.rb → proxy/many_polymorphic_proxy.rb} +0 -0
- data/lib/mongo_mapper/plugins/associations/{one_as_proxy.rb → proxy/one_as_proxy.rb} +0 -0
- data/lib/mongo_mapper/plugins/associations/{one_embedded_polymorphic_proxy.rb → proxy/one_embedded_polymorphic_proxy.rb} +0 -0
- data/lib/mongo_mapper/plugins/associations/{one_embedded_proxy.rb → proxy/one_embedded_proxy.rb} +3 -1
- data/lib/mongo_mapper/plugins/associations/{one_proxy.rb → proxy/one_proxy.rb} +0 -0
- data/lib/mongo_mapper/plugins/associations/proxy/proxy.rb +164 -0
- data/lib/mongo_mapper/plugins/associations/single_association.rb +5 -13
- data/lib/mongo_mapper/plugins/dirty.rb +29 -37
- data/lib/mongo_mapper/plugins/document.rb +1 -1
- data/lib/mongo_mapper/plugins/dynamic_querying/dynamic_finder.rb +1 -1
- data/lib/mongo_mapper/plugins/embedded_callbacks.rb +1 -0
- data/lib/mongo_mapper/plugins/embedded_document.rb +2 -2
- data/lib/mongo_mapper/plugins/identity_map.rb +3 -1
- data/lib/mongo_mapper/plugins/indexes.rb +13 -6
- data/lib/mongo_mapper/plugins/keys.rb +12 -7
- data/lib/mongo_mapper/plugins/keys/key.rb +21 -13
- data/lib/mongo_mapper/plugins/modifiers.rb +39 -14
- data/lib/mongo_mapper/plugins/persistence.rb +6 -2
- data/lib/mongo_mapper/plugins/querying.rb +9 -3
- data/lib/mongo_mapper/plugins/querying/decorated_plucky_query.rb +6 -6
- data/lib/mongo_mapper/plugins/safe.rb +10 -4
- data/lib/mongo_mapper/plugins/scopes.rb +19 -3
- data/lib/mongo_mapper/plugins/stats.rb +1 -3
- data/lib/mongo_mapper/plugins/strong_parameters.rb +26 -0
- data/lib/mongo_mapper/plugins/validations.rb +1 -1
- data/lib/mongo_mapper/railtie.rb +1 -0
- data/lib/mongo_mapper/utils.rb +2 -2
- data/lib/mongo_mapper/version.rb +1 -1
- data/spec/examples.txt +1731 -0
- data/spec/functional/accessible_spec.rb +7 -1
- data/spec/functional/associations/belongs_to_polymorphic_proxy_spec.rb +2 -2
- data/spec/functional/associations/belongs_to_proxy_spec.rb +55 -5
- data/spec/functional/associations/in_array_proxy_spec.rb +149 -14
- data/spec/functional/associations/in_foreign_array_proxy_spec.rb +321 -0
- data/spec/functional/associations/many_documents_as_proxy_spec.rb +6 -6
- data/spec/functional/associations/many_documents_proxy_spec.rb +22 -22
- data/spec/functional/associations/many_embedded_polymorphic_proxy_spec.rb +2 -2
- data/spec/functional/associations/many_polymorphic_proxy_spec.rb +4 -4
- data/spec/functional/associations/one_as_proxy_spec.rb +8 -8
- data/spec/functional/associations/one_embedded_proxy_spec.rb +28 -0
- data/spec/functional/associations/one_proxy_spec.rb +19 -9
- data/spec/functional/associations_spec.rb +3 -3
- data/spec/functional/binary_spec.rb +2 -2
- data/spec/functional/caching_spec.rb +15 -22
- data/spec/functional/callbacks_spec.rb +2 -2
- data/spec/functional/counter_cache_spec.rb +10 -10
- data/spec/functional/dirty_spec.rb +48 -10
- data/spec/functional/dirty_with_callbacks_spec.rb +59 -0
- data/spec/functional/document_spec.rb +5 -8
- data/spec/functional/dumpable_spec.rb +1 -1
- data/spec/functional/embedded_document_spec.rb +5 -5
- data/spec/functional/identity_map_spec.rb +8 -8
- data/spec/functional/indexes_spec.rb +19 -18
- data/spec/functional/keys_spec.rb +64 -33
- data/spec/functional/logger_spec.rb +2 -2
- data/spec/functional/modifiers_spec.rb +81 -19
- data/spec/functional/partial_updates_spec.rb +8 -8
- data/spec/functional/protected_spec.rb +1 -1
- data/spec/functional/querying_spec.rb +70 -22
- data/spec/functional/safe_spec.rb +23 -27
- data/spec/functional/sci_spec.rb +7 -7
- data/spec/functional/scopes_spec.rb +89 -1
- data/spec/functional/static_keys_spec.rb +2 -2
- data/spec/functional/stats_spec.rb +28 -12
- data/spec/functional/strong_parameters_spec.rb +49 -0
- data/spec/functional/validations_spec.rb +8 -16
- data/spec/quality_spec.rb +1 -1
- data/spec/spec_helper.rb +39 -8
- data/spec/support/matchers.rb +1 -1
- data/spec/unit/associations/proxy_spec.rb +18 -10
- data/spec/unit/clone_spec.rb +1 -1
- data/spec/unit/document_spec.rb +3 -3
- data/spec/unit/embedded_document_spec.rb +4 -5
- data/spec/unit/extensions_spec.rb +12 -7
- data/spec/unit/identity_map_middleware_spec.rb +65 -96
- data/spec/unit/inspect_spec.rb +1 -1
- data/spec/unit/key_spec.rb +23 -18
- data/spec/unit/keys_spec.rb +17 -8
- data/spec/unit/mongo_mapper_spec.rb +41 -88
- data/spec/unit/rails_spec.rb +2 -2
- data/spec/unit/validations_spec.rb +18 -18
- metadata +70 -38
- data/README.rdoc +0 -56
- data/lib/mongo_mapper/extensions/ordered_hash.rb +0 -23
- data/lib/mongo_mapper/plugins/associations/collection.rb +0 -29
- data/lib/mongo_mapper/plugins/associations/proxy.rb +0 -141
@@ -91,6 +91,12 @@ describe "Accessible" do
|
|
91
91
|
@doc.admin.should be_falsey
|
92
92
|
end
|
93
93
|
|
94
|
+
it "should ignore inaccessible attribute on #assign_attributes" do
|
95
|
+
@doc.assign_attributes({:name => 'Ren Hoek', :admin => true})
|
96
|
+
@doc.name.should == 'Ren Hoek'
|
97
|
+
@doc.admin.should be_falsey
|
98
|
+
end
|
99
|
+
|
94
100
|
it "should be indifferent to whether the accessible keys are strings or symbols" do
|
95
101
|
@doc.update_attributes!("name" => 'Stimpson J. Cat', "admin" => true)
|
96
102
|
@doc.name.should == 'Stimpson J. Cat'
|
@@ -119,7 +125,7 @@ describe "Accessible" do
|
|
119
125
|
key :name, String
|
120
126
|
key :site_id, ObjectId
|
121
127
|
end
|
122
|
-
GrandParent.collection.
|
128
|
+
GrandParent.collection.drop
|
123
129
|
|
124
130
|
class ::Child < ::GrandParent
|
125
131
|
attr_accessible :position
|
@@ -51,7 +51,7 @@ describe "BelongsToProxy" do
|
|
51
51
|
it "should not reload the association when replacing" do
|
52
52
|
post = @post_class.new(:name => 'mongomapper')
|
53
53
|
comment = @comment_class.new(:name => 'Foo!', :post => post)
|
54
|
-
comment.post.
|
54
|
+
comment.post.object_id.should == post.object_id
|
55
55
|
end
|
56
56
|
|
57
57
|
it "should properly assign the associated object when assigning the association with create" do
|
@@ -121,13 +121,13 @@ describe "BelongsToProxy" do
|
|
121
121
|
class ::Property
|
122
122
|
include MongoMapper::Document
|
123
123
|
end
|
124
|
-
Property.collection.
|
124
|
+
Property.collection.drop
|
125
125
|
|
126
126
|
class ::Thing
|
127
127
|
include MongoMapper::Document
|
128
128
|
key :name, String
|
129
129
|
end
|
130
|
-
Thing.collection.
|
130
|
+
Thing.collection.drop
|
131
131
|
end
|
132
132
|
|
133
133
|
after do
|
@@ -211,7 +211,7 @@ describe "BelongsToProxy" do
|
|
211
211
|
end
|
212
212
|
|
213
213
|
it "should raise exception if invalid" do
|
214
|
-
|
214
|
+
lambda { comment.create_post! }.should raise_error(MongoMapper::DocumentNotValid)
|
215
215
|
end
|
216
216
|
|
217
217
|
it "should work if valid" do
|
@@ -252,4 +252,54 @@ describe "BelongsToProxy" do
|
|
252
252
|
post.reload.title.should == 'Hello, world!'
|
253
253
|
end
|
254
254
|
end
|
255
|
-
|
255
|
+
|
256
|
+
context "regression with reassignment" do
|
257
|
+
it "should not infinite regress (shouldn't raise SystemStackError) when assigned to twice (when the proxy isn't around)" do
|
258
|
+
post = @post_class.create!
|
259
|
+
comment = @comment_class.create!(post: post)
|
260
|
+
|
261
|
+
comment = @comment_class.find(comment.id)
|
262
|
+
|
263
|
+
post = comment.post
|
264
|
+
|
265
|
+
comment.post = post
|
266
|
+
|
267
|
+
lambda do
|
268
|
+
comment.post = post
|
269
|
+
end.should_not raise_error
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
context "foreign_key=" do
|
274
|
+
it "should reset parent when foreign key is changed" do
|
275
|
+
post = @post_class.create!
|
276
|
+
comment = @comment_class.create!(post: post)
|
277
|
+
another_post = @post_class.create!
|
278
|
+
|
279
|
+
comment.post.should == post
|
280
|
+
|
281
|
+
comment.post_id = another_post.id
|
282
|
+
|
283
|
+
comment.post.should == another_post
|
284
|
+
|
285
|
+
comment.post_id = nil
|
286
|
+
|
287
|
+
comment.post.should == nil
|
288
|
+
end
|
289
|
+
|
290
|
+
it "should reset parent when foreign key is changed from nil" do
|
291
|
+
post = @post_class.create!
|
292
|
+
comment = @comment_class.create!(post: nil)
|
293
|
+
|
294
|
+
comment.post.should == nil
|
295
|
+
|
296
|
+
comment.post_id = post.id
|
297
|
+
|
298
|
+
comment.post.should == post
|
299
|
+
|
300
|
+
comment.post_id = nil
|
301
|
+
|
302
|
+
comment.post.should == nil
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
@@ -14,8 +14,8 @@ describe "InArrayProxy" do
|
|
14
14
|
key :list_ids, Array
|
15
15
|
many :lists, :in => :list_ids
|
16
16
|
end
|
17
|
-
User.collection.
|
18
|
-
List.collection.
|
17
|
+
User.collection.drop
|
18
|
+
List.collection.drop
|
19
19
|
end
|
20
20
|
|
21
21
|
after do
|
@@ -112,9 +112,9 @@ describe "InArrayProxy" do
|
|
112
112
|
end
|
113
113
|
|
114
114
|
it "should raise exception if invalid" do
|
115
|
-
|
115
|
+
lambda {
|
116
116
|
@user.lists.create!
|
117
|
-
}.
|
117
|
+
}.should raise_error(MongoMapper::DocumentNotValid)
|
118
118
|
end
|
119
119
|
|
120
120
|
it "should reset cache" do
|
@@ -144,7 +144,7 @@ describe "InArrayProxy" do
|
|
144
144
|
|
145
145
|
it "should not hit the database if ids key is empty" do
|
146
146
|
@user.list_ids = []
|
147
|
-
|
147
|
+
@user.lists.should_receive(:query).never
|
148
148
|
@user.lists.all.should == []
|
149
149
|
end
|
150
150
|
end
|
@@ -160,7 +160,7 @@ describe "InArrayProxy" do
|
|
160
160
|
|
161
161
|
it "should not hit the database if ids key is empty" do
|
162
162
|
@user.list_ids = []
|
163
|
-
|
163
|
+
@user.lists.should_receive(:query).never
|
164
164
|
@user.lists.first.should be_nil
|
165
165
|
end
|
166
166
|
end
|
@@ -176,7 +176,7 @@ describe "InArrayProxy" do
|
|
176
176
|
|
177
177
|
it "should not hit the database if ids key is empty" do
|
178
178
|
@user.list_ids = []
|
179
|
-
|
179
|
+
@user.lists.should_receive(:query).never
|
180
180
|
@user.lists.last.should be_nil
|
181
181
|
end
|
182
182
|
end
|
@@ -195,9 +195,9 @@ describe "InArrayProxy" do
|
|
195
195
|
end
|
196
196
|
|
197
197
|
it "should raise error when using ! and not found" do
|
198
|
-
|
198
|
+
lambda {
|
199
199
|
@user.lists.find!(@list3.id)
|
200
|
-
}.
|
200
|
+
}.should raise_error(MongoMapper::DocumentNotFound)
|
201
201
|
end
|
202
202
|
end
|
203
203
|
|
@@ -230,7 +230,7 @@ describe "InArrayProxy" do
|
|
230
230
|
|
231
231
|
it "should not hit the database if ids key is empty" do
|
232
232
|
@user.list_ids = []
|
233
|
-
|
233
|
+
@user.lists.should_receive(:query).never
|
234
234
|
@user.lists.paginate(:page => 1).should == []
|
235
235
|
end
|
236
236
|
end
|
@@ -249,9 +249,9 @@ describe "InArrayProxy" do
|
|
249
249
|
end
|
250
250
|
|
251
251
|
it "should raise error when using ! and not found" do
|
252
|
-
|
252
|
+
lambda {
|
253
253
|
@user.lists.find_by_name!('Foo 3')
|
254
|
-
}.
|
254
|
+
}.should raise_error(MongoMapper::DocumentNotFound)
|
255
255
|
end
|
256
256
|
|
257
257
|
context "find_or_create_by" do
|
@@ -293,7 +293,7 @@ describe "InArrayProxy" do
|
|
293
293
|
|
294
294
|
it "should not hit the database if ids key is empty" do
|
295
295
|
@user.list_ids = []
|
296
|
-
|
296
|
+
@user.lists.should_receive(:query).never
|
297
297
|
@user.lists.count(:name => 'Foo 1').should == 0
|
298
298
|
end
|
299
299
|
end
|
@@ -346,4 +346,139 @@ describe "InArrayProxy" do
|
|
346
346
|
end
|
347
347
|
end
|
348
348
|
end
|
349
|
-
|
349
|
+
|
350
|
+
describe "ordering" do
|
351
|
+
before do
|
352
|
+
@user_class = Doc("User") do
|
353
|
+
key :list_ids, Array
|
354
|
+
end
|
355
|
+
|
356
|
+
@list_class = Doc("List") do
|
357
|
+
key :name, String, :required => true
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
def create_list_items
|
362
|
+
@user = @user_class.create!
|
363
|
+
@list1 = @list_class.create!(:name => "one")
|
364
|
+
@list2 = @list_class.create!(:name => "two")
|
365
|
+
@list3 = @list_class.create!(:name => "three")
|
366
|
+
|
367
|
+
@user.lists << [@list3, @list2, @list1]
|
368
|
+
@user.save!
|
369
|
+
|
370
|
+
@user.reload
|
371
|
+
end
|
372
|
+
|
373
|
+
shared_examples_for "ordering is on" do
|
374
|
+
it "should have the items ordered according to order of the ids" do
|
375
|
+
@user.lists.should == [@list3, @list2, @list1]
|
376
|
+
end
|
377
|
+
|
378
|
+
it "should have the right item for #first" do
|
379
|
+
@user.lists.first.should == @list3
|
380
|
+
end
|
381
|
+
|
382
|
+
it "should have the right item for #last" do
|
383
|
+
@user.lists.last.should == @list1
|
384
|
+
end
|
385
|
+
|
386
|
+
it "does not work for pagination (but probably should)" do
|
387
|
+
@user.lists.paginate(:per_page => 100).should == [@list1, @list2, @list3]
|
388
|
+
end
|
389
|
+
|
390
|
+
it "should work with find" do
|
391
|
+
@user.lists.find(@list2.id, @list1.id).should == [@list2, @list1]
|
392
|
+
@user.lists.find(@list1.id, @list2.id).should == [@list2, @list1]
|
393
|
+
@user.lists.find(@list1.id).should == @list1
|
394
|
+
end
|
395
|
+
|
396
|
+
it "should work with find!" do
|
397
|
+
@user.lists.find!(@list2.id, @list1.id).should == [@list2, @list1]
|
398
|
+
@user.lists.find!(@list1.id, @list2.id).should == [@list2, @list1]
|
399
|
+
end
|
400
|
+
|
401
|
+
it "should only load one object with first (and no params given)" do
|
402
|
+
@list_class.should_receive(:allocate).once.and_return @list3
|
403
|
+
@user.lists.first
|
404
|
+
end
|
405
|
+
|
406
|
+
it "should only load one object with first (and params given)" do
|
407
|
+
@list_class.should_receive(:allocate).once.and_return @list3
|
408
|
+
@user.lists.first(:name => /^t/)
|
409
|
+
end
|
410
|
+
|
411
|
+
it "should only load one object with last (and no params given)" do
|
412
|
+
@list_class.should_receive(:allocate).once.and_return @list1
|
413
|
+
@user.lists.last
|
414
|
+
end
|
415
|
+
|
416
|
+
it "should only load one object with last (and params given)" do
|
417
|
+
@list_class.should_receive(:allocate).once.and_return @list3
|
418
|
+
@user.lists.last(:name => /^t/)
|
419
|
+
end
|
420
|
+
|
421
|
+
it "should return nil if first with a query matches no objects" do
|
422
|
+
@user.lists.first(:name => "non-existent").should be_nil
|
423
|
+
end
|
424
|
+
|
425
|
+
it "should return nil if last with a query matches no objects" do
|
426
|
+
@user.lists.last(:name => "non-existent").should be_nil
|
427
|
+
end
|
428
|
+
|
429
|
+
it "should work with extra query params to first and last" do
|
430
|
+
@user.lists.first(:name => /^t/).should == @list3
|
431
|
+
@user.lists.first(:name => /^o/).should == @list1
|
432
|
+
|
433
|
+
@user.lists.last(:name => /^t/).should == @list2
|
434
|
+
@user.lists.last(:name => /^o/).should == @list1
|
435
|
+
end
|
436
|
+
end
|
437
|
+
|
438
|
+
shared_examples_for "ordering is off" do
|
439
|
+
it "should include all items" do
|
440
|
+
@user.lists.length == 3
|
441
|
+
@user.lists.should include(@list1)
|
442
|
+
@user.lists.should include(@list2)
|
443
|
+
@user.lists.should include(@list3)
|
444
|
+
end
|
445
|
+
|
446
|
+
it "should return the items in the natural order" do
|
447
|
+
@user.lists.should == [@list1, @list2, @list3]
|
448
|
+
end
|
449
|
+
|
450
|
+
it "should work with find" do
|
451
|
+
@user.lists.find(@list2.id, @list1.id).should == [@list1, @list2]
|
452
|
+
@user.lists.find(@list1.id, @list2.id).should == [@list1, @list2]
|
453
|
+
@user.lists.find(@list1.id).should == @list1
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
describe "without a param" do
|
458
|
+
before do
|
459
|
+
@user_class.many :lists, :in => :list_ids, :class => @list_class
|
460
|
+
create_list_items
|
461
|
+
end
|
462
|
+
|
463
|
+
it_behaves_like "ordering is off"
|
464
|
+
end
|
465
|
+
|
466
|
+
describe "with ordering off" do
|
467
|
+
before do
|
468
|
+
@user_class.many :lists, :in => :list_ids, :class => @list_class, :ordered => false
|
469
|
+
create_list_items
|
470
|
+
end
|
471
|
+
|
472
|
+
it_behaves_like "ordering is off"
|
473
|
+
end
|
474
|
+
|
475
|
+
describe "with ordering on" do
|
476
|
+
before do
|
477
|
+
@user_class.many :lists, :in => :list_ids, :class => @list_class, :ordered => true
|
478
|
+
create_list_items
|
479
|
+
end
|
480
|
+
|
481
|
+
it_behaves_like "ordering is on"
|
482
|
+
end
|
483
|
+
end
|
484
|
+
end
|
@@ -0,0 +1,321 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "InForeignArrayProxyTest" do
|
4
|
+
context "description" do
|
5
|
+
before do
|
6
|
+
class ::List
|
7
|
+
include MongoMapper::Document
|
8
|
+
key :name, String, :required => true
|
9
|
+
key :user_ids, Array
|
10
|
+
many :users, :in => :user_ids
|
11
|
+
end
|
12
|
+
|
13
|
+
class ::User
|
14
|
+
include MongoMapper::Document
|
15
|
+
key :name, String, :required => true
|
16
|
+
many :lists, :from => :user_ids, :as => :user
|
17
|
+
end
|
18
|
+
User.collection.drop
|
19
|
+
List.collection.drop
|
20
|
+
end
|
21
|
+
|
22
|
+
after do
|
23
|
+
Object.send :remove_const, 'List' if defined?(::List)
|
24
|
+
Object.send :remove_const, 'User' if defined?(::User)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should default reader to empty array" do
|
28
|
+
User.new.lists.should == []
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should allow adding to association like it was an array" do
|
32
|
+
user = User.new(:name => 'John')
|
33
|
+
user.lists << List.new(:name => 'Foo1!')
|
34
|
+
user.lists.push List.new(:name => 'Foo2!')
|
35
|
+
user.lists.concat List.new(:name => 'Foo3!')
|
36
|
+
user.lists.size.should == 3
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should ignore adding duplicate ids" do
|
40
|
+
user = User.create(:name => 'John')
|
41
|
+
list = List.create(:name => 'Foo')
|
42
|
+
user.lists << list
|
43
|
+
user.lists << list
|
44
|
+
user.lists << list
|
45
|
+
|
46
|
+
list.reload.user_ids.should == [user.id]
|
47
|
+
user.lists.count.should == 1
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should be able to replace the association" do
|
51
|
+
user = User.new(:name => 'John')
|
52
|
+
list = List.new(:name => 'Foo')
|
53
|
+
user.lists = [list]
|
54
|
+
user.save.should == true
|
55
|
+
|
56
|
+
user.reload
|
57
|
+
list.reload
|
58
|
+
list.user_ids.should == [user.id]
|
59
|
+
user.lists.size.should == 1
|
60
|
+
user.lists[0].name.should == 'Foo'
|
61
|
+
end
|
62
|
+
|
63
|
+
context "create" do
|
64
|
+
before do
|
65
|
+
@user = User.create(:name => 'John')
|
66
|
+
@list = @user.lists.create(:name => 'Foo!')
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should add id to key" do
|
70
|
+
@list.user_ids.should include(@user.id)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should persist id addition to key in database" do
|
74
|
+
@list.reload
|
75
|
+
@list.user_ids.should include(@user.id)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should add doc to association" do
|
79
|
+
@user.lists.should include(@list)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should save doc" do
|
83
|
+
@list.should_not be_new
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should reset cache" do
|
87
|
+
@user.lists.size.should == 1
|
88
|
+
@user.lists.create(:name => 'Moo!')
|
89
|
+
@user.lists.size.should == 2
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context "create!" do
|
94
|
+
before do
|
95
|
+
@user = User.create(:name => 'John')
|
96
|
+
@list = @user.lists.create!(:name => 'Foo!')
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should add id to key" do
|
100
|
+
@list.user_ids.should include(@user.id)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should persist id addition to key in database" do
|
104
|
+
@list.reload
|
105
|
+
@list.user_ids.should include(@user.id)
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should add doc to association" do
|
109
|
+
@user.lists.should include(@list)
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should save doc" do
|
113
|
+
@list.should_not be_new
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should raise exception if invalid" do
|
117
|
+
lambda do
|
118
|
+
@user.lists.create!
|
119
|
+
end.should raise_error(MongoMapper::DocumentNotValid)
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should reset cache" do
|
123
|
+
@user.lists.size.should == 1
|
124
|
+
@user.lists.create!(:name => 'Moo!')
|
125
|
+
@user.lists.size.should == 2
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context "Finding scoped to association" do
|
130
|
+
before do
|
131
|
+
@user = User.create(:name => 'John')
|
132
|
+
@user2 = User.create(:name => 'Brandon')
|
133
|
+
@list1 = @user.lists.create!(:name => 'Foo 1', :position => 1)
|
134
|
+
@list2 = @user.lists.create!(:name => 'Foo 2', :position => 2)
|
135
|
+
@list3 = @user2.lists.create!(:name => 'Foo 3', :position => 1)
|
136
|
+
end
|
137
|
+
|
138
|
+
context "all" do
|
139
|
+
it "should work" do
|
140
|
+
@user.lists.all(:order => :position.asc).should == [@list1, @list2]
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should work with conditions" do
|
144
|
+
@user.lists.all(:name => 'Foo 1').should == [@list1]
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context "first" do
|
149
|
+
it "should work" do
|
150
|
+
@user.lists.first(:order => 'position').should == @list1
|
151
|
+
end
|
152
|
+
|
153
|
+
it "should work with conditions" do
|
154
|
+
@user.lists.first(:position => 2).should == @list2
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
context "last" do
|
159
|
+
it "should work" do
|
160
|
+
@user.lists.last(:order => 'position').should == @list2
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should work with conditions" do
|
164
|
+
@user.lists.last(:position => 2, :order => 'position').should == @list2
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
context "with one id" do
|
169
|
+
it "should work for id in association" do
|
170
|
+
@user.lists.find(@list1.id).should == @list1
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should work with string ids" do
|
174
|
+
@user.lists.find(@list1.id.to_s).should == @list1
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should not work for id not in association" do
|
178
|
+
@user.lists.find(@list3.id).should be_nil
|
179
|
+
end
|
180
|
+
|
181
|
+
it "should raise error when using ! and not found" do
|
182
|
+
lambda do
|
183
|
+
@user.lists.find!(@list3.id)
|
184
|
+
end.should raise_error(MongoMapper::DocumentNotFound)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
context "with multiple ids" do
|
189
|
+
it "should work for ids in association" do
|
190
|
+
@user.lists.find(@list1.id, @list2.id).should == [@list1, @list2]
|
191
|
+
end
|
192
|
+
|
193
|
+
it "should not work for ids not in association" do
|
194
|
+
@user.lists.find(@list1.id, @list2.id, @list3.id).should == [@list1, @list2]
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
context "with #paginate" do
|
199
|
+
before do
|
200
|
+
@lists = @user.lists.paginate(:per_page => 1, :page => 1, :order => 'position')
|
201
|
+
end
|
202
|
+
|
203
|
+
it "should return total pages" do
|
204
|
+
@lists.total_pages.should == 2
|
205
|
+
end
|
206
|
+
|
207
|
+
it "should return total entries" do
|
208
|
+
@lists.total_entries.should == 2
|
209
|
+
end
|
210
|
+
|
211
|
+
it "should return the subject" do
|
212
|
+
@lists.collect(&:name).should == ['Foo 1']
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
context "dynamic finders" do
|
217
|
+
it "should work with single key" do
|
218
|
+
@user.lists.find_by_name('Foo 1').should == @list1
|
219
|
+
@user.lists.find_by_name!('Foo 1').should == @list1
|
220
|
+
@user.lists.find_by_name('Foo 3').should be_nil
|
221
|
+
end
|
222
|
+
|
223
|
+
it "should work with multiple keys" do
|
224
|
+
@user.lists.find_by_name_and_position('Foo 1', 1).should == @list1
|
225
|
+
@user.lists.find_by_name_and_position!('Foo 1', 1).should == @list1
|
226
|
+
@user.lists.find_by_name_and_position('Foo 3', 1).should be_nil
|
227
|
+
end
|
228
|
+
|
229
|
+
it "should raise error when using ! and not found" do
|
230
|
+
lambda do
|
231
|
+
@user.lists.find_by_name!('Foo 3')
|
232
|
+
end.should raise_error(MongoMapper::DocumentNotFound)
|
233
|
+
end
|
234
|
+
|
235
|
+
context "find_or_create_by" do
|
236
|
+
it "should not create document if found" do
|
237
|
+
lambda {
|
238
|
+
list = @user.lists.find_or_create_by_name('Foo 1')
|
239
|
+
list.should == @list1
|
240
|
+
}.should_not change { List.count }
|
241
|
+
end
|
242
|
+
|
243
|
+
it "should create document if not found" do
|
244
|
+
lambda {
|
245
|
+
list = @user.lists.find_or_create_by_name('Home')
|
246
|
+
@user.lists.should include(list)
|
247
|
+
}.should change { List.count }
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
context "count" do
|
254
|
+
before do
|
255
|
+
@user = User.create(:name => 'John')
|
256
|
+
@user2 = User.create(:name => 'Brandon')
|
257
|
+
@list1 = @user.lists.create!(:name => 'Foo 1')
|
258
|
+
@list2 = @user.lists.create!(:name => 'Foo 2')
|
259
|
+
@list3 = @user2.lists.create!(:name => 'Foo 3')
|
260
|
+
end
|
261
|
+
|
262
|
+
it "should return number of ids" do
|
263
|
+
@user.lists.count.should == 2
|
264
|
+
@user2.lists.count.should == 1
|
265
|
+
end
|
266
|
+
|
267
|
+
it "should return correct count when given criteria" do
|
268
|
+
@user.lists.count(:name => 'Foo 1').should == 1
|
269
|
+
@user2.lists.count(:name => 'Foo 1').should == 0
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
context "Removing documents" do
|
274
|
+
before do
|
275
|
+
@user = User.create(:name => 'John')
|
276
|
+
@user2 = User.create(:name => 'Brandon')
|
277
|
+
@list1 = @user.lists.create!(:name => 'Foo 1', :position => 1)
|
278
|
+
@list2 = @user.lists.create!(:name => 'Foo 2', :position => 2)
|
279
|
+
@list3 = @user2.lists.create!(:name => 'Foo 3', :position => 1)
|
280
|
+
end
|
281
|
+
|
282
|
+
context "destroy_all" do
|
283
|
+
it "should work" do
|
284
|
+
@user.lists.count.should == 2
|
285
|
+
@user.lists.destroy_all
|
286
|
+
@user.lists.count.should == 0
|
287
|
+
end
|
288
|
+
|
289
|
+
it "should work with conditions" do
|
290
|
+
@user.lists.count.should == 2
|
291
|
+
@user.lists.destroy_all(:name => 'Foo 1')
|
292
|
+
@user.lists.count.should == 1
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
context "delete_all" do
|
297
|
+
it "should work" do
|
298
|
+
@user.lists.count.should == 2
|
299
|
+
@user.lists.delete_all
|
300
|
+
@user.lists.count.should == 0
|
301
|
+
end
|
302
|
+
|
303
|
+
it "should work with conditions" do
|
304
|
+
@user.lists.count.should == 2
|
305
|
+
@user.lists.delete_all(:name => 'Foo 1')
|
306
|
+
@user.lists.count.should == 1
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
it "should work with nullify" do
|
311
|
+
@user.lists.count.should == 2
|
312
|
+
|
313
|
+
lambda {
|
314
|
+
@user.lists.nullify
|
315
|
+
}.should_not change { List.count }
|
316
|
+
|
317
|
+
@user.lists.count.should == 0
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
321
|
+
end
|