mongoid 7.2.0 → 7.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (191) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/Rakefile +16 -0
  4. data/lib/config/locales/en.yml +2 -2
  5. data/lib/mongoid/association/accessors.rb +1 -1
  6. data/lib/mongoid/association/constrainable.rb +1 -1
  7. data/lib/mongoid/association/depending.rb +4 -4
  8. data/lib/mongoid/association/embedded/batchable.rb +1 -1
  9. data/lib/mongoid/association/embedded/embedded_in.rb +1 -1
  10. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +10 -3
  11. data/lib/mongoid/association/nested/many.rb +1 -1
  12. data/lib/mongoid/association/nested/one.rb +4 -2
  13. data/lib/mongoid/association/proxy.rb +6 -1
  14. data/lib/mongoid/association/referenced/auto_save.rb +2 -2
  15. data/lib/mongoid/association/referenced/has_many/enumerable.rb +493 -495
  16. data/lib/mongoid/association/referenced/has_many/proxy.rb +2 -2
  17. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +2 -2
  18. data/lib/mongoid/attributes/projector.rb +120 -0
  19. data/lib/mongoid/attributes.rb +32 -14
  20. data/lib/mongoid/cacheable.rb +2 -2
  21. data/lib/mongoid/clients/factory.rb +22 -8
  22. data/lib/mongoid/clients.rb +1 -1
  23. data/lib/mongoid/config.rb +19 -2
  24. data/lib/mongoid/contextual/aggregable/mongo.rb +10 -8
  25. data/lib/mongoid/copyable.rb +1 -1
  26. data/lib/mongoid/criteria/findable.rb +1 -1
  27. data/lib/mongoid/criteria/queryable/expandable.rb +0 -24
  28. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
  29. data/lib/mongoid/criteria/queryable/extensions.rb +0 -4
  30. data/lib/mongoid/criteria/queryable/mergeable.rb +46 -20
  31. data/lib/mongoid/criteria/queryable/selectable.rb +8 -8
  32. data/lib/mongoid/criteria/queryable/selector.rb +0 -4
  33. data/lib/mongoid/criteria.rb +4 -5
  34. data/lib/mongoid/document.rb +4 -17
  35. data/lib/mongoid/errors/delete_restriction.rb +8 -9
  36. data/lib/mongoid/evolvable.rb +1 -1
  37. data/lib/mongoid/extensions/boolean.rb +1 -2
  38. data/lib/mongoid/extensions/false_class.rb +1 -1
  39. data/lib/mongoid/extensions/hash.rb +2 -2
  40. data/lib/mongoid/extensions/true_class.rb +1 -1
  41. data/lib/mongoid/fields.rb +43 -5
  42. data/lib/mongoid/inspectable.rb +1 -1
  43. data/lib/mongoid/interceptable.rb +3 -1
  44. data/lib/mongoid/matcher/bits.rb +41 -0
  45. data/lib/mongoid/matcher/bits_all_clear.rb +20 -0
  46. data/lib/mongoid/matcher/bits_all_set.rb +20 -0
  47. data/lib/mongoid/matcher/bits_any_clear.rb +20 -0
  48. data/lib/mongoid/matcher/bits_any_set.rb +20 -0
  49. data/lib/mongoid/matcher/elem_match.rb +2 -1
  50. data/lib/mongoid/matcher/expression.rb +9 -14
  51. data/lib/mongoid/matcher/field_expression.rb +4 -5
  52. data/lib/mongoid/matcher/field_operator.rb +13 -11
  53. data/lib/mongoid/matcher/mod.rb +17 -0
  54. data/lib/mongoid/matcher/type.rb +99 -0
  55. data/lib/mongoid/matcher.rb +26 -43
  56. data/lib/mongoid/persistable/deletable.rb +1 -2
  57. data/lib/mongoid/persistable/destroyable.rb +8 -2
  58. data/lib/mongoid/persistable/updatable.rb +27 -2
  59. data/lib/mongoid/query_cache.rb +35 -29
  60. data/lib/mongoid/reloadable.rb +5 -0
  61. data/lib/mongoid/selectable.rb +5 -7
  62. data/lib/mongoid/shardable.rb +21 -5
  63. data/lib/mongoid/touchable.rb +23 -4
  64. data/lib/mongoid/version.rb +1 -1
  65. data/lib/rails/generators/mongoid/config/config_generator.rb +8 -1
  66. data/spec/integration/app_spec.rb +171 -84
  67. data/spec/integration/associations/embeds_many_spec.rb +44 -0
  68. data/spec/integration/associations/has_one_spec.rb +48 -0
  69. data/spec/integration/callbacks_models.rb +49 -0
  70. data/spec/integration/callbacks_spec.rb +216 -0
  71. data/spec/integration/criteria/date_field_spec.rb +1 -1
  72. data/spec/integration/document_spec.rb +30 -0
  73. data/spec/integration/matcher_operator_data/bits_all_clear.yml +159 -0
  74. data/spec/integration/matcher_operator_data/bits_all_set.yml +159 -0
  75. data/spec/integration/matcher_operator_data/bits_any_clear.yml +159 -0
  76. data/spec/integration/matcher_operator_data/bits_any_set.yml +159 -0
  77. data/spec/integration/matcher_operator_data/comment.yml +22 -0
  78. data/spec/integration/matcher_operator_data/elem_match.yml +46 -0
  79. data/spec/integration/matcher_operator_data/gt_types.yml +63 -0
  80. data/spec/integration/matcher_operator_data/gte_types.yml +15 -0
  81. data/spec/integration/matcher_operator_data/implicit_traversal.yml +96 -0
  82. data/spec/integration/matcher_operator_data/in.yml +16 -0
  83. data/spec/integration/matcher_operator_data/lt_types.yml +15 -0
  84. data/spec/integration/matcher_operator_data/lte_types.yml +15 -0
  85. data/spec/integration/matcher_operator_data/mod.yml +55 -0
  86. data/spec/integration/matcher_operator_data/ne_types.yml +15 -0
  87. data/spec/integration/matcher_operator_data/type.yml +70 -0
  88. data/spec/integration/matcher_operator_data/type_array.yml +16 -0
  89. data/spec/integration/matcher_operator_data/type_binary.yml +18 -0
  90. data/spec/integration/matcher_operator_data/type_boolean.yml +39 -0
  91. data/spec/integration/matcher_operator_data/type_code.yml +26 -0
  92. data/spec/integration/matcher_operator_data/type_code_with_scope.yml +26 -0
  93. data/spec/integration/matcher_operator_data/type_date.yml +39 -0
  94. data/spec/integration/matcher_operator_data/type_db_pointer.yml +19 -0
  95. data/spec/integration/matcher_operator_data/type_decimal.yml +40 -0
  96. data/spec/integration/matcher_operator_data/type_double.yml +15 -0
  97. data/spec/integration/matcher_operator_data/type_int32.yml +33 -0
  98. data/spec/integration/matcher_operator_data/type_int64.yml +33 -0
  99. data/spec/integration/matcher_operator_data/type_max_key.yml +17 -0
  100. data/spec/integration/matcher_operator_data/type_min_key.yml +17 -0
  101. data/spec/integration/matcher_operator_data/type_null.yml +23 -0
  102. data/spec/integration/matcher_operator_data/type_object.yml +23 -0
  103. data/spec/integration/matcher_operator_data/type_object_id.yml +25 -0
  104. data/spec/integration/matcher_operator_data/type_regex.yml +44 -0
  105. data/spec/integration/matcher_operator_data/type_string.yml +15 -0
  106. data/spec/integration/matcher_operator_data/type_symbol.yml +32 -0
  107. data/spec/integration/matcher_operator_data/type_timestamp.yml +25 -0
  108. data/spec/integration/matcher_operator_data/type_undefined.yml +17 -0
  109. data/spec/lite_spec_helper.rb +5 -4
  110. data/spec/mongoid/association/depending_spec.rb +391 -352
  111. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +50 -0
  112. data/spec/mongoid/association/nested/one_spec.rb +18 -14
  113. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +25 -8
  114. data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +1 -1
  115. data/spec/mongoid/association/referenced/has_many/binding_spec.rb +1 -1
  116. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +1 -1
  117. data/spec/mongoid/association/referenced/has_one_models.rb +8 -0
  118. data/spec/mongoid/atomic/paths_spec.rb +105 -12
  119. data/spec/mongoid/attributes/projector_data/embedded.yml +105 -0
  120. data/spec/mongoid/attributes/projector_data/fields.yml +93 -0
  121. data/spec/mongoid/attributes/projector_spec.rb +41 -0
  122. data/spec/mongoid/attributes_spec.rb +333 -0
  123. data/spec/mongoid/clients/factory_spec.rb +48 -0
  124. data/spec/mongoid/config_spec.rb +32 -0
  125. data/spec/mongoid/contextual/atomic_spec.rb +17 -4
  126. data/spec/mongoid/contextual/mongo_spec.rb +2 -2
  127. data/spec/mongoid/criteria/modifiable_spec.rb +1 -1
  128. data/spec/mongoid/criteria/queryable/expandable_spec.rb +0 -73
  129. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +1 -1
  130. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +105 -7
  131. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +265 -24
  132. data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +39 -0
  133. data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -565
  134. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +590 -0
  135. data/spec/mongoid/criteria_projection_spec.rb +411 -0
  136. data/spec/mongoid/criteria_spec.rb +0 -275
  137. data/spec/mongoid/document_fields_spec.rb +26 -0
  138. data/spec/mongoid/document_spec.rb +13 -13
  139. data/spec/mongoid/errors/delete_restriction_spec.rb +1 -1
  140. data/spec/mongoid/extensions/false_class_spec.rb +1 -1
  141. data/spec/mongoid/extensions/string_spec.rb +5 -5
  142. data/spec/mongoid/extensions/true_class_spec.rb +1 -1
  143. data/spec/mongoid/fields/localized_spec.rb +4 -4
  144. data/spec/mongoid/fields_spec.rb +4 -4
  145. data/spec/mongoid/inspectable_spec.rb +12 -4
  146. data/spec/mongoid/matcher/extract_attribute_data/numeric_keys.yml +104 -0
  147. data/spec/mongoid/matcher/extract_attribute_data/traversal.yml +68 -88
  148. data/spec/mongoid/matcher/extract_attribute_spec.rb +3 -13
  149. data/spec/mongoid/persistable/deletable_spec.rb +175 -1
  150. data/spec/mongoid/persistable/destroyable_spec.rb +191 -3
  151. data/spec/mongoid/persistable/savable_spec.rb +3 -5
  152. data/spec/mongoid/persistable/settable_spec.rb +30 -0
  153. data/spec/mongoid/persistable/upsertable_spec.rb +1 -1
  154. data/spec/mongoid/query_cache_middleware_spec.rb +8 -0
  155. data/spec/mongoid/reloadable_spec.rb +18 -1
  156. data/spec/mongoid/shardable_spec.rb +44 -0
  157. data/spec/mongoid/touchable_spec.rb +104 -16
  158. data/spec/mongoid/touchable_spec_models.rb +52 -0
  159. data/spec/mongoid/validatable_spec.rb +1 -1
  160. data/spec/shared/bin/get-mongodb-download-url +17 -0
  161. data/spec/shared/lib/mrss/cluster_config.rb +221 -0
  162. data/spec/shared/lib/mrss/constraints.rb +51 -0
  163. data/spec/shared/lib/mrss/docker_runner.rb +265 -0
  164. data/spec/shared/lib/mrss/lite_constraints.rb +16 -0
  165. data/spec/shared/lib/mrss/server_version_registry.rb +115 -0
  166. data/spec/shared/lib/mrss/spec_organizer.rb +14 -1
  167. data/spec/shared/lib/mrss/utils.rb +15 -0
  168. data/spec/shared/share/Dockerfile.erb +231 -0
  169. data/spec/shared/shlib/distro.sh +73 -0
  170. data/spec/shared/shlib/server.sh +290 -0
  171. data/spec/shared/shlib/set_env.sh +128 -0
  172. data/spec/spec_helper.rb +6 -2
  173. data/spec/support/client_registry.rb +9 -0
  174. data/spec/support/models/bolt.rb +8 -0
  175. data/spec/support/models/customer.rb +11 -0
  176. data/spec/support/models/customer_address.rb +12 -0
  177. data/spec/support/models/dictionary.rb +6 -0
  178. data/spec/support/models/hole.rb +13 -0
  179. data/spec/support/models/mop.rb +9 -0
  180. data/spec/support/models/nut.rb +8 -0
  181. data/spec/support/models/person.rb +6 -0
  182. data/spec/support/models/sealer.rb +8 -0
  183. data/spec/support/models/shirt.rb +12 -0
  184. data/spec/support/models/spacer.rb +8 -0
  185. data/spec/support/models/threadlocker.rb +8 -0
  186. data/spec/support/models/washer.rb +8 -0
  187. data/spec/support/spec_config.rb +8 -0
  188. data.tar.gz.sig +0 -0
  189. metadata +146 -14
  190. metadata.gz.sig +5 -2
  191. data/spec/support/cluster_config.rb +0 -158
@@ -5,7 +5,7 @@ require "spec_helper"
5
5
 
6
6
  describe Mongoid::Association::Depending do
7
7
 
8
- describe '#self.included' do
8
+ describe '.included' do
9
9
 
10
10
  context 'when a destroy dependent is defined' do
11
11
 
@@ -264,7 +264,7 @@ describe Mongoid::Association::Depending do
264
264
  Person.relations = relations_before
265
265
  end
266
266
 
267
- describe "#apply_delete_dependencies!" do
267
+ describe "#apply_destroy_dependencies!" do
268
268
 
269
269
  let(:band) do
270
270
  Band.new
@@ -283,7 +283,7 @@ describe Mongoid::Association::Depending do
283
283
  end
284
284
 
285
285
  it "ignores the dependency" do
286
- expect(band.apply_delete_dependencies!).to eq([Band.relations["records"]])
286
+ expect(band.apply_destroy_dependencies!).to eq([Band.relations["records"]])
287
287
  end
288
288
  end
289
289
  end
@@ -303,7 +303,7 @@ describe Mongoid::Association::Depending do
303
303
 
304
304
  it "does not raise an error" do
305
305
  expect {
306
- klass.new.apply_delete_dependencies!
306
+ klass.new.apply_destroy_dependencies!
307
307
  }.not_to raise_error
308
308
  end
309
309
  end
@@ -351,72 +351,65 @@ describe Mongoid::Association::Depending do
351
351
  end
352
352
  end
353
353
 
354
- [:delete, :destroy].each do |method|
355
-
356
- describe "##{method}" do
357
-
358
- context "when cascading removals" do
359
-
360
- context "when strategy is delete" do
361
-
362
- let(:person) do
363
- Person.create
364
- end
365
-
366
- let!(:post) do
367
- person.posts.create(title: "Testing")
368
- end
354
+ describe '#delete and #destroy' do
355
+ context "when cascading removals" do
369
356
 
357
+ shared_examples 'destroys dependents if parent is destroyed but does not if parent is deleted' do
358
+ context '#destroy' do
370
359
  before do
371
- person.send(method)
360
+ parent.destroy
372
361
  end
373
362
 
374
363
  it "deletes the associated documents" do
375
364
  expect {
376
- Post.find(post.id)
365
+ child.class.find(child.id)
377
366
  }.to raise_error(Mongoid::Errors::DocumentNotFound)
378
367
  end
379
368
  end
380
369
 
381
- context "when strategy is destroy" do
382
-
383
- let(:person) do
384
- Person.create
370
+ context '#delete' do
371
+ before do
372
+ parent.delete
385
373
  end
386
374
 
387
- let!(:game) do
388
- person.create_game(name: "Pong")
375
+ it "does not delete the associated documents" do
376
+ child.class.find(child.id).should == child
389
377
  end
378
+ end
379
+ end
390
380
 
391
- before do
392
- person.send(method)
393
- end
381
+ context "when strategy is delete" do
394
382
 
395
- it "destroys the associated documents" do
396
- expect {
397
- Game.find(game.id)
398
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
399
- end
383
+ let(:parent) do
384
+ Person.create
400
385
  end
401
386
 
402
- context "when strategy is nullify" do
387
+ let!(:child) do
388
+ parent.posts.create(title: "Testing")
389
+ end
403
390
 
404
- context "when nullifying a references many" do
391
+ include_examples 'destroys dependents if parent is destroyed but does not if parent is deleted'
392
+ end
405
393
 
406
- let(:movie) do
407
- Movie.create(title: "Bladerunner")
408
- end
394
+ context "when strategy is destroy" do
409
395
 
410
- let!(:rating) do
411
- movie.ratings.create(value: 10)
412
- end
396
+ let(:parent) do
397
+ Person.create
398
+ end
413
399
 
414
- let(:from_db) do
415
- Rating.find(rating.id)
416
- end
400
+ let!(:child) do
401
+ parent.create_game(name: "Pong")
402
+ end
403
+
404
+ include_examples 'destroys dependents if parent is destroyed but does not if parent is deleted'
405
+ end
417
406
 
407
+ context "when strategy is nullify" do
408
+
409
+ shared_examples 'removes references if parent is destroyed but does not if parent is deleted' do
410
+ context '#destroy' do
418
411
  before do
419
- movie.send(method)
412
+ parent.destroy
420
413
  end
421
414
 
422
415
  it "removes the references to the removed document" do
@@ -424,59 +417,87 @@ describe Mongoid::Association::Depending do
424
417
  end
425
418
  end
426
419
 
427
- context "when nullifying a references one" do
420
+ context '#delete' do
421
+ before do
422
+ parent.delete
423
+ end
424
+
425
+ it "does not remove the references to the removed document" do
426
+ from_db.ratable_id.should == parent.id
427
+ end
428
+ end
429
+ end
430
+
431
+ context "when nullifying a references many" do
428
432
 
429
- context "when the relation exists" do
433
+ let(:parent) do
434
+ Movie.create(title: "Bladerunner")
435
+ end
430
436
 
431
- let(:book) do
432
- Book.create(title: "Neuromancer")
433
- end
437
+ let!(:rating) do
438
+ parent.ratings.create(value: 10)
439
+ end
434
440
 
435
- let!(:rating) do
436
- book.create_rating(value: 10)
437
- end
441
+ let(:from_db) do
442
+ Rating.find(rating.id)
443
+ end
438
444
 
439
- let(:from_db) do
440
- Rating.find(rating.id)
441
- end
445
+ include_examples 'removes references if parent is destroyed but does not if parent is deleted'
446
+ end
442
447
 
443
- before do
444
- book.send(method)
445
- end
448
+ context "when nullifying a references one" do
446
449
 
447
- it "removes the references to the removed document" do
448
- expect(from_db.ratable_id).to be_nil
449
- end
450
- end
450
+ context "when the relation exists" do
451
451
 
452
- context "when the relation is nil" do
452
+ let(:parent) do
453
+ Book.create(title: "Neuromancer")
454
+ end
453
455
 
454
- let(:book) do
455
- Book.create(title: "Neuromancer")
456
- end
456
+ let!(:rating) do
457
+ parent.create_rating(value: 10)
458
+ end
457
459
 
458
- it "returns nil" do
459
- expect(book.send(method)).to be true
460
- end
460
+ let(:from_db) do
461
+ Rating.find(rating.id)
461
462
  end
463
+
464
+ include_examples 'removes references if parent is destroyed but does not if parent is deleted'
462
465
  end
463
466
 
464
- context "when nullifying a many to many" do
467
+ context "when no association target exists" do
465
468
 
466
- let(:person) do
467
- Person.create
469
+ let(:parent) do
470
+ Book.create(title: "Neuromancer")
468
471
  end
469
472
 
470
- let!(:preference) do
471
- person.preferences.create(name: "Setting")
472
- end
473
+ [:delete, :destroy].each do |method|
473
474
 
474
- let(:from_db) do
475
- Preference.find(preference.id)
475
+ describe "##{method}" do
476
+ it "succeeds" do
477
+ expect(parent.send(method)).to be true
478
+ end
479
+ end
476
480
  end
481
+ end
482
+ end
483
+
484
+ context "when nullifying a many to many" do
485
+
486
+ let(:person) do
487
+ Person.create
488
+ end
489
+
490
+ let!(:preference) do
491
+ person.preferences.create(name: "Setting")
492
+ end
493
+
494
+ let(:from_db) do
495
+ Preference.find(preference.id)
496
+ end
477
497
 
498
+ context '#destroy' do
478
499
  before do
479
- person.send(method)
500
+ person.destroy
480
501
  end
481
502
 
482
503
  it "removes the references from the removed document" do
@@ -487,356 +508,327 @@ describe Mongoid::Association::Depending do
487
508
  expect(from_db.person_ids).to_not include(person.id)
488
509
  end
489
510
  end
490
- end
491
-
492
- context "when dependent is restrict_with_exception" do
493
-
494
- context "when restricting a references many" do
495
511
 
496
- let!(:association) do
497
- Person.has_many :drugs, dependent: :restrict_with_exception
498
- end
499
-
500
- after do
501
- Person.dependents.delete(association)
502
- Person.has_many :drugs, validate: false
512
+ context '#delete' do
513
+ before do
514
+ person.delete
503
515
  end
504
516
 
505
- context "when the relation is empty" do
506
-
507
- let(:person) do
508
- Person.new drugs: []
509
- end
510
-
511
- it "raises no error" do
512
- expect { person.send(method) }.to_not raise_error
513
- end
514
-
515
- it "deletes the parent" do
516
- person.send(method)
517
- expect(person).to be_destroyed
518
- end
517
+ it "keeps the references from the removed document" do
518
+ expect(person.preference_ids).to include(preference.id)
519
519
  end
520
520
 
521
- context "when the relation is not empty" do
522
-
523
- let(:person) do
524
- Person.new drugs: [Drug.new]
525
- end
526
-
527
- it "raises DeleteRestriction error" do
528
- expect { person.send(method) }.to raise_error(Mongoid::Errors::DeleteRestriction)
529
- end
521
+ it "keeps the references to the removed document" do
522
+ expect(from_db.person_ids).to include(person.id)
530
523
  end
531
524
  end
525
+ end
526
+ end
532
527
 
533
- context "when restricting a references one" do
528
+ shared_examples 'deletes the parent with #delete and #destroy' do
529
+ [:delete, :destroy].each do |method|
534
530
 
535
- let!(:association) do
536
- Person.has_one :account, dependent: :restrict_with_exception
531
+ describe "##{method}" do
532
+ it "raises no error" do
533
+ expect { person.send(method) }.to_not raise_error
537
534
  end
538
535
 
539
- after do
540
- Person.dependents.delete(association)
541
- Person.has_one :account, validate: false
536
+ it "deletes the parent" do
537
+ person.send(method)
538
+ expect(person).to be_destroyed
542
539
  end
540
+ end
541
+ end
542
+ end
543
543
 
544
- context "when the relation is empty" do
544
+ shared_examples 'raises an error with #destroy and deletes the parent with #delete' do
545
+ context '#destroy' do
546
+ it "raises DeleteRestriction error" do
547
+ expect { person.destroy }.to raise_error(Mongoid::Errors::DeleteRestriction)
548
+ end
549
+ end
545
550
 
546
- let(:person) do
547
- Person.new account: nil
548
- end
551
+ context '#delete' do
552
+ it "deletes the parent" do
553
+ person.delete
554
+ expect(person).to be_destroyed
555
+ end
556
+ end
557
+ end
549
558
 
550
- it "raises no error" do
551
- expect { person.send(method) }.to_not raise_error
552
- end
559
+ context "when dependent is restrict_with_exception" do
553
560
 
554
- it "deletes the parent" do
555
- person.send(method)
556
- expect(person).to be_destroyed
557
- end
558
- end
561
+ context "when restricting a references many" do
559
562
 
560
- context "when the relation is not empty" do
563
+ let!(:association) do
564
+ Person.has_many :drugs, dependent: :restrict_with_exception
565
+ end
561
566
 
562
- let(:person) do
563
- Person.new account: Account.new(name: 'test')
564
- end
567
+ after do
568
+ Person.dependents.delete(association)
569
+ Person.has_many :drugs, validate: false
570
+ end
565
571
 
566
- it "raises DeleteRestriction error" do
567
- expect { person.send(method) }.to raise_error(Mongoid::Errors::DeleteRestriction)
568
- end
572
+ context "when the relation is empty" do
573
+
574
+ let(:person) do
575
+ Person.new drugs: []
569
576
  end
577
+
578
+ include_examples 'deletes the parent with #delete and #destroy'
570
579
  end
571
580
 
572
- context "when restricting a many to many" do
581
+ context "when the relation is not empty" do
573
582
 
574
- let!(:association) do
575
- Person.has_and_belongs_to_many :houses, dependent: :restrict_with_exception
583
+ let(:person) do
584
+ Person.new drugs: [Drug.new]
576
585
  end
577
586
 
578
- after do
579
- Person.dependents.delete(association)
580
- Person.has_and_belongs_to_many :houses, validate: false
581
- end
587
+ include_examples 'raises an error with #destroy and deletes the parent with #delete'
588
+ end
589
+ end
582
590
 
583
- context "when the relation is empty" do
591
+ context "when restricting a references one" do
584
592
 
585
- let(:person) do
586
- Person.new houses: []
587
- end
593
+ let!(:association) do
594
+ Person.has_one :account, dependent: :restrict_with_exception
595
+ end
588
596
 
589
- it "raises no error" do
590
- expect { person.send(method) }.to_not raise_error
591
- end
597
+ after do
598
+ Person.dependents.delete(association)
599
+ Person.has_one :account, validate: false
600
+ end
592
601
 
593
- it "deletes the parent" do
594
- person.send(method)
595
- expect(person).to be_destroyed
596
- end
602
+ context "when the relation is empty" do
603
+
604
+ let(:person) do
605
+ Person.new account: nil
597
606
  end
598
607
 
599
- context "when the relation is not empty" do
608
+ include_examples 'deletes the parent with #delete and #destroy'
609
+ end
600
610
 
601
- let(:person) do
602
- Person.new houses: [House.new]
603
- end
611
+ context "when the relation is not empty" do
604
612
 
605
- it "raises DeleteRestriction error" do
606
- expect { person.send(method) }.to raise_error(Mongoid::Errors::DeleteRestriction)
607
- end
613
+ let(:person) do
614
+ Person.new account: Account.new(name: 'test')
608
615
  end
616
+
617
+ include_examples 'raises an error with #destroy and deletes the parent with #delete'
609
618
  end
610
619
  end
611
- end
612
- end
613
- end
614
-
615
- context 'when the strategy is :delete_all' do
616
-
617
- let(:person) do
618
- Person.create
619
- end
620
620
 
621
- context "when cascading a has one" do
621
+ context "when restricting a many to many" do
622
622
 
623
- context "when the relation exists" do
623
+ let!(:association) do
624
+ Person.has_and_belongs_to_many :houses, dependent: :restrict_with_exception
625
+ end
624
626
 
625
- let!(:home) do
626
- person.create_home
627
- end
627
+ after do
628
+ Person.dependents.delete(association)
629
+ Person.has_and_belongs_to_many :houses, validate: false
630
+ end
628
631
 
629
- before do
630
- person.delete
631
- end
632
+ context "when the relation is empty" do
632
633
 
633
- it "deletes the relation" do
634
- expect(home).to be_destroyed
635
- end
634
+ let(:person) do
635
+ Person.new houses: []
636
+ end
636
637
 
637
- it "persists the deletion" do
638
- expect {
639
- home.reload
640
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
641
- end
642
- end
638
+ include_examples 'deletes the parent with #delete and #destroy'
639
+ end
643
640
 
644
- context "when the relation does not exist" do
641
+ context "when the relation is not empty" do
645
642
 
646
- before do
647
- person.delete
648
- end
643
+ let(:person) do
644
+ Person.new houses: [House.new]
645
+ end
649
646
 
650
- it "deletes the base document" do
651
- expect(person).to be_destroyed
647
+ include_examples 'raises an error with #destroy and deletes the parent with #delete'
648
+ end
652
649
  end
653
650
  end
654
651
  end
655
652
 
656
- context "when cascading a has many" do
653
+ context 'when the strategy is :delete_all' do
657
654
 
658
- context "when the relation has documents" do
655
+ let(:person) do
656
+ Person.create
657
+ end
659
658
 
660
- let!(:post_one) do
661
- person.posts.create(title: "one")
662
- end
659
+ context "when cascading a has one" do
663
660
 
664
- let!(:post_two) do
665
- person.posts.create(title: "two")
666
- end
661
+ context "when the relation exists" do
667
662
 
668
- context "when the documents are in memory" do
663
+ let!(:home) do
664
+ person.create_home
665
+ end
669
666
 
670
667
  before do
671
- expect(post_one).to receive(:delete).never
672
- expect(post_two).to receive(:delete).never
673
- person.delete
668
+ person.destroy
674
669
  end
675
670
 
676
- it "deletes the first document" do
677
- expect(post_one).to be_destroyed
671
+ it "deletes the dependents" do
672
+ expect(home).to be_destroyed
678
673
  end
679
674
 
680
- it "deletes the second document" do
681
- expect(post_two).to be_destroyed
675
+ it "persists the deletion" do
676
+ expect {
677
+ home.reload
678
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
682
679
  end
680
+ end
683
681
 
684
- it "unbinds the first document" do
685
- expect(post_one.person).to be_nil
686
- end
682
+ context "when the association target does not exist" do
687
683
 
688
- it "unbinds the second document" do
689
- expect(post_two.person).to be_nil
684
+ before do
685
+ person.destroy
690
686
  end
691
687
 
692
- it "removes the documents from the relation" do
693
- expect(person.posts).to be_empty
688
+ it "deletes the base document" do
689
+ expect(person).to be_destroyed
694
690
  end
691
+ end
692
+ end
695
693
 
696
- it "persists the first deletion" do
697
- expect {
698
- post_one.reload
699
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
694
+ context "when cascading a has many" do
695
+
696
+ context "when the relation has documents" do
697
+
698
+ let!(:post_one) do
699
+ person.posts.create(title: "one")
700
700
  end
701
701
 
702
- it "persists the second deletion" do
703
- expect {
704
- post_two.reload
705
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
702
+ let!(:post_two) do
703
+ person.posts.create(title: "two")
706
704
  end
707
- end
708
- end
709
- end
710
- end
711
705
 
712
- context 'when the strategy is :destroy' do
706
+ context "when the documents are in memory" do
713
707
 
714
- let!(:association) do
715
- Person.has_many :destroyable_posts, class_name: "Post", dependent: :destroy
716
- end
708
+ before do
709
+ expect(post_one).to receive(:delete).never
710
+ expect(post_two).to receive(:delete).never
711
+ person.destroy
712
+ end
717
713
 
718
- after do
719
- Person.dependents.delete(association)
720
- end
714
+ it "deletes the first document" do
715
+ expect(post_one).to be_destroyed
716
+ end
721
717
 
722
- let(:person) do
723
- Person.new
724
- end
718
+ it "deletes the second document" do
719
+ expect(post_two).to be_destroyed
720
+ end
725
721
 
726
- let(:post) do
727
- Post.new
728
- end
722
+ it "unbinds the first document" do
723
+ expect(post_one.person).to be_nil
724
+ end
729
725
 
730
- context "when the documents exist" do
726
+ it "unbinds the second document" do
727
+ expect(post_two.person).to be_nil
728
+ end
731
729
 
732
- before do
733
- expect(post).to receive(:destroy)
734
- person.destroyable_posts << post
735
- end
730
+ it "removes the documents from the relation" do
731
+ expect(person.posts).to be_empty
732
+ end
733
+
734
+ it "persists the first deletion" do
735
+ expect {
736
+ post_one.reload
737
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
738
+ end
736
739
 
737
- it "destroys all documents in the relation" do
738
- person.delete
740
+ it "persists the second deletion" do
741
+ expect {
742
+ post_two.reload
743
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
744
+ end
745
+ end
746
+ end
739
747
  end
740
748
  end
741
749
 
742
- context "when no documents exist" do
750
+ context 'when the strategy is :destroy' do
743
751
 
744
- before do
745
- expect(post).to receive(:destroy).never
752
+ let!(:association) do
753
+ Person.has_many :destroyable_posts, class_name: "Post", dependent: :destroy
746
754
  end
747
755
 
748
- it "it does not destroy the relation" do
749
- person.delete
756
+ after do
757
+ Person.dependents.delete(association)
750
758
  end
751
- end
752
- end
753
759
 
754
- context 'when the strategy is :nullify' do
755
-
756
- let!(:association) do
757
- Person.has_many :nullifyable_posts, class_name: "Post", dependent: :nullify
758
- end
759
-
760
- after do
761
- Person.dependents.delete(association)
762
- end
763
-
764
- let(:person) do
765
- Person.new
766
- end
760
+ let(:person) do
761
+ Person.new
762
+ end
767
763
 
768
- let(:posts_relation) do
769
- person.posts
770
- end
764
+ let(:post) do
765
+ Post.new
766
+ end
771
767
 
772
- before do
773
- allow(person).to receive(:nullifyable_posts).and_return(posts_relation)
774
- expect(posts_relation).to receive(:nullify)
775
- end
768
+ context "when the documents exist" do
776
769
 
777
- it "nullifies the relation" do
778
- person.delete
779
- end
780
- end
770
+ before do
771
+ expect(post).to receive(:destroy)
772
+ person.destroyable_posts << post
773
+ end
781
774
 
782
- context 'when the strategy is :restrict_with_exception' do
775
+ it "destroys all documents in the association" do
776
+ person.destroy
777
+ end
778
+ end
783
779
 
784
- let(:person) do
785
- Person.new
786
- end
780
+ context "when no documents exist" do
787
781
 
788
- let(:post) do
789
- Post.new
790
- end
782
+ before do
783
+ expect(post).to receive(:destroy).never
784
+ end
791
785
 
792
- let!(:association) do
793
- Person.has_many :restrictable_posts, class_name: "Post", dependent: :restrict_with_exception
786
+ it "it does not destroy the association target" do
787
+ person.destroy
788
+ end
789
+ end
794
790
  end
795
791
 
796
- after do
797
- Person.dependents.delete(association)
798
- end
792
+ context 'when the strategy is :nullify' do
799
793
 
800
- context 'when there are related objects' do
794
+ let!(:association) do
795
+ Person.has_many :nullifyable_posts, class_name: "Post", dependent: :nullify
796
+ end
801
797
 
802
- before do
803
- person.restrictable_posts << post
804
- expect(post).to receive(:delete).never
805
- expect(post).to receive(:destroy).never
798
+ after do
799
+ Person.dependents.delete(association)
806
800
  end
807
801
 
808
- it 'raises an exception and leaves the related one intact' do
809
- expect { person.delete }.to raise_exception(Mongoid::Errors::DeleteRestriction)
802
+ let(:person) do
803
+ Person.new
810
804
  end
811
- end
812
805
 
813
- context 'when there are no related objects' do
806
+ let(:posts_relation) do
807
+ person.posts
808
+ end
814
809
 
815
810
  before do
816
- expect(post).to receive(:delete).never
817
- expect(post).to receive(:destroy).never
811
+ allow(person).to receive(:nullifyable_posts).and_return(posts_relation)
812
+ expect(posts_relation).to receive(:nullify)
818
813
  end
819
814
 
820
- it 'deletes the object and leaves the other one intact' do
821
- expect(person.delete).to be(true)
815
+ it "nullifies the association target" do
816
+ person.destroy
822
817
  end
823
818
  end
824
- end
825
819
 
826
- context 'when the strategy is :restrict_with_error' do
820
+ context 'when the strategy is :restrict_with_exception' do
827
821
 
828
- context "when restricting a one-to-many" do
829
-
830
822
  let(:person) do
831
823
  Person.new
832
824
  end
833
-
825
+
834
826
  let(:post) do
835
827
  Post.new
836
828
  end
837
829
 
838
830
  let!(:association) do
839
- Person.has_many :restrictable_posts, class_name: "Post", dependent: :restrict_with_error
831
+ Person.has_many :restrictable_posts, class_name: "Post", dependent: :restrict_with_exception
840
832
  end
841
833
 
842
834
  after do
@@ -847,13 +839,12 @@ describe Mongoid::Association::Depending do
847
839
 
848
840
  before do
849
841
  person.restrictable_posts << post
842
+ expect(post).to receive(:delete).never
843
+ expect(post).to receive(:destroy).never
850
844
  end
851
845
 
852
- it 'adds an error to the parent object' do
853
- expect(person.delete).to be(false)
854
-
855
- person.errors[:restrictable_posts].first.should ==
856
- "is not empty and prevents the document from being destroyed"
846
+ it 'raises an exception and leaves the related one intact' do
847
+ expect { person.destroy }.to raise_exception(Mongoid::Errors::DeleteRestriction)
857
848
  end
858
849
  end
859
850
 
@@ -865,53 +856,101 @@ describe Mongoid::Association::Depending do
865
856
  end
866
857
 
867
858
  it 'deletes the object and leaves the other one intact' do
868
- expect(person.delete).to be(true)
859
+ expect(person.destroy).to be(true)
869
860
  end
870
861
  end
862
+ end
871
863
 
872
- context 'when deleted inside a transaction' do
873
- require_transaction_support
874
-
875
- before do
876
- person.restrictable_posts << post
864
+ context 'when the strategy is :restrict_with_error' do
865
+
866
+ context "when restricting a one-to-many" do
867
+
868
+ let(:person) do
869
+ Person.new
870
+ end
871
+
872
+ let(:post) do
873
+ Post.new
874
+ end
875
+
876
+ let!(:association) do
877
+ Person.has_many :restrictable_posts, class_name: "Post", dependent: :restrict_with_error
877
878
  end
878
879
 
879
- it 'doesn\'t raise an exception' do
880
- person.with_session do |session|
881
- session.with_transaction do
882
- expect { person.destroy }.to_not raise_error
880
+ after do
881
+ Person.dependents.delete(association)
882
+ end
883
+
884
+ context 'when there are related objects' do
885
+
886
+ before do
887
+ person.restrictable_posts << post
888
+ end
889
+
890
+ it 'adds an error to the parent object' do
891
+ expect(person.destroy).to be(false)
892
+
893
+ person.errors[:restrictable_posts].first.should ==
894
+ "is not empty and prevents the document from being destroyed"
895
+ end
896
+ end
897
+
898
+ context 'when there are no related objects' do
899
+
900
+ before do
901
+ expect(post).to receive(:delete).never
902
+ expect(post).to receive(:destroy).never
903
+ end
904
+
905
+ it 'deletes the object and leaves the other one intact' do
906
+ expect(person.destroy).to be(true)
907
+ end
908
+ end
909
+
910
+ context 'when deleted inside a transaction' do
911
+ require_transaction_support
912
+
913
+ before do
914
+ person.restrictable_posts << post
915
+ end
916
+
917
+ it 'doesn\'t raise an exception' do
918
+ person.with_session do |session|
919
+ session.with_transaction do
920
+ expect { person.destroy }.to_not raise_error
921
+ end
883
922
  end
884
923
  end
885
924
  end
886
925
  end
887
- end
888
926
 
889
- context "when restricting a many to many" do
927
+ context "when restricting a many to many" do
890
928
 
891
- let!(:association) do
892
- Person.has_and_belongs_to_many :houses, dependent: :restrict_with_error
893
- end
929
+ let!(:association) do
930
+ Person.has_and_belongs_to_many :houses, dependent: :restrict_with_error
931
+ end
894
932
 
895
- after do
896
- Person.dependents.delete(association)
897
- Person.has_and_belongs_to_many :houses, validate: false
898
- end
933
+ after do
934
+ Person.dependents.delete(association)
935
+ Person.has_and_belongs_to_many :houses, validate: false
936
+ end
899
937
 
900
- let(:person) do
901
- Person.new houses: [House.new]
902
- end
938
+ let(:person) do
939
+ Person.new houses: [House.new]
940
+ end
903
941
 
904
- it "returns false" do
905
- expect(person.destroy).to be false
906
- end
942
+ it "returns false" do
943
+ expect(person.destroy).to be false
944
+ end
907
945
 
908
- context "when inside a transaction" do
909
- require_transaction_support
910
-
911
- it 'doesn\'t raise an exception inside a transaction' do
912
- person.with_session do |session|
913
- session.with_transaction do
914
- expect { person.destroy }.to_not raise_error
946
+ context "when inside a transaction" do
947
+ require_transaction_support
948
+
949
+ it 'doesn\'t raise an exception inside a transaction' do
950
+ person.with_session do |session|
951
+ session.with_transaction do
952
+ expect { person.destroy }.to_not raise_error
953
+ end
915
954
  end
916
955
  end
917
956
  end