mongoid 8.0.10 → 8.1.0
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +3 -3
- data/README.md +3 -3
- data/Rakefile +18 -67
- data/lib/config/locales/en.yml +46 -14
- data/lib/mongoid/association/accessors.rb +3 -7
- data/lib/mongoid/association/builders.rb +1 -1
- data/lib/mongoid/association/eager_loadable.rb +0 -3
- data/lib/mongoid/association/embedded/batchable.rb +2 -2
- data/lib/mongoid/association/embedded/embedded_in/buildable.rb +2 -2
- data/lib/mongoid/association/embedded/embedded_in/proxy.rb +2 -1
- data/lib/mongoid/association/embedded/embeds_many/buildable.rb +3 -2
- data/lib/mongoid/association/embedded/embeds_many/proxy.rb +6 -6
- data/lib/mongoid/association/embedded/embeds_one/buildable.rb +1 -1
- data/lib/mongoid/association/embedded/embeds_one/proxy.rb +1 -1
- data/lib/mongoid/association/macros.rb +0 -6
- data/lib/mongoid/association/nested/one.rb +40 -2
- data/lib/mongoid/association/proxy.rb +1 -1
- data/lib/mongoid/association/referenced/counter_cache.rb +2 -2
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +1 -1
- data/lib/mongoid/association/referenced/has_many/enumerable.rb +6 -23
- data/lib/mongoid/association/referenced/has_many/proxy.rb +3 -3
- data/lib/mongoid/association/reflections.rb +2 -2
- data/lib/mongoid/atomic.rb +7 -16
- data/lib/mongoid/attributes/dynamic.rb +1 -1
- data/lib/mongoid/attributes/nested.rb +2 -2
- data/lib/mongoid/attributes/processing.rb +5 -29
- data/lib/mongoid/attributes/projector.rb +1 -1
- data/lib/mongoid/attributes/readonly.rb +1 -1
- data/lib/mongoid/attributes.rb +8 -2
- data/lib/mongoid/changeable.rb +107 -5
- data/lib/mongoid/clients/storage_options.rb +2 -5
- data/lib/mongoid/clients/validators/storage.rb +1 -13
- data/lib/mongoid/collection_configurable.rb +58 -0
- data/lib/mongoid/composable.rb +2 -0
- data/lib/mongoid/config/defaults.rb +60 -0
- data/lib/mongoid/config/options.rb +0 -3
- data/lib/mongoid/config/validators/async_query_executor.rb +24 -0
- data/lib/mongoid/config/validators.rb +1 -0
- data/lib/mongoid/config.rb +88 -27
- data/lib/mongoid/contextual/atomic.rb +1 -1
- data/lib/mongoid/contextual/memory.rb +233 -33
- data/lib/mongoid/contextual/mongo/documents_loader.rb +177 -0
- data/lib/mongoid/contextual/mongo.rb +370 -133
- data/lib/mongoid/contextual/none.rb +162 -7
- data/lib/mongoid/contextual.rb +12 -0
- data/lib/mongoid/criteria/findable.rb +2 -2
- data/lib/mongoid/criteria/includable.rb +4 -3
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -15
- data/lib/mongoid/criteria/queryable/key.rb +1 -1
- data/lib/mongoid/criteria/queryable/mergeable.rb +1 -1
- data/lib/mongoid/criteria/queryable/optional.rb +8 -8
- data/lib/mongoid/criteria/queryable/selectable.rb +43 -12
- data/lib/mongoid/criteria/queryable/selector.rb +1 -1
- data/lib/mongoid/criteria/queryable/storable.rb +1 -1
- data/lib/mongoid/criteria.rb +6 -5
- data/lib/mongoid/deprecable.rb +1 -2
- data/lib/mongoid/deprecation.rb +3 -3
- data/lib/mongoid/document.rb +1 -8
- data/lib/mongoid/errors/create_collection_failure.rb +33 -0
- data/lib/mongoid/errors/drop_collection_failure.rb +27 -0
- data/lib/mongoid/errors/immutable_attribute.rb +26 -0
- data/lib/mongoid/errors/invalid_async_query_executor.rb +25 -0
- data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +22 -0
- data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
- data/lib/mongoid/errors.rb +4 -1
- data/lib/mongoid/extensions/hash.rb +2 -24
- data/lib/mongoid/extensions/object.rb +2 -2
- data/lib/mongoid/extensions/time.rb +2 -0
- data/lib/mongoid/fields/localized.rb +10 -0
- data/lib/mongoid/fields/standard.rb +10 -0
- data/lib/mongoid/fields.rb +59 -35
- data/lib/mongoid/findable.rb +27 -3
- data/lib/mongoid/interceptable.rb +6 -116
- data/lib/mongoid/matcher/eq_impl.rb +1 -1
- data/lib/mongoid/matcher/type.rb +1 -1
- data/lib/mongoid/persistable/creatable.rb +1 -0
- data/lib/mongoid/persistable/deletable.rb +1 -1
- data/lib/mongoid/persistable/savable.rb +13 -1
- data/lib/mongoid/persistable/unsettable.rb +2 -2
- data/lib/mongoid/persistable/updatable.rb +51 -1
- data/lib/mongoid/persistable/upsertable.rb +20 -1
- data/lib/mongoid/persistable.rb +3 -0
- data/lib/mongoid/query_cache.rb +5 -1
- data/lib/mongoid/railties/database.rake +7 -2
- data/lib/mongoid/reloadable.rb +5 -3
- data/lib/mongoid/stateful.rb +22 -1
- data/lib/mongoid/tasks/database.rake +12 -0
- data/lib/mongoid/tasks/database.rb +20 -0
- data/lib/mongoid/timestamps/created.rb +1 -8
- data/lib/mongoid/traversable.rb +0 -12
- data/lib/mongoid/utils.rb +22 -0
- data/lib/mongoid/validatable/associated.rb +17 -98
- data/lib/mongoid/validatable/macros.rb +5 -5
- data/lib/mongoid/validatable.rb +4 -9
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid/warnings.rb +17 -1
- data/lib/mongoid.rb +16 -3
- data/spec/integration/app_spec.rb +2 -6
- data/spec/integration/associations/has_and_belongs_to_many_spec.rb +0 -40
- data/spec/integration/callbacks_spec.rb +99 -12
- data/spec/integration/discriminator_key_spec.rb +4 -5
- data/spec/integration/i18n_fallbacks_spec.rb +3 -2
- data/spec/mongoid/association/eager_spec.rb +2 -24
- data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +27 -0
- data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +20 -25
- data/spec/mongoid/association/embedded/embeds_many_models.rb +1 -0
- data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +0 -4
- data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +15 -2
- data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -18
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +42 -55
- data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +9 -50
- data/spec/mongoid/association/syncable_spec.rb +1 -1
- data/spec/mongoid/association_spec.rb +0 -60
- data/spec/mongoid/attributes_spec.rb +3 -33
- data/spec/mongoid/changeable_spec.rb +299 -24
- data/spec/mongoid/clients_spec.rb +122 -13
- data/spec/mongoid/collection_configurable_spec.rb +158 -0
- data/spec/mongoid/config/defaults_spec.rb +160 -0
- data/spec/mongoid/config_spec.rb +154 -27
- data/spec/mongoid/contextual/memory_spec.rb +332 -76
- data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +187 -0
- data/spec/mongoid/contextual/mongo_spec.rb +1009 -125
- data/spec/mongoid/contextual/none_spec.rb +49 -2
- data/spec/mongoid/copyable_spec.rb +2 -10
- data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +4 -10
- data/spec/mongoid/criteria/queryable/options_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +419 -0
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/selector_spec.rb +3 -76
- data/spec/mongoid/criteria/queryable/storable_spec.rb +0 -72
- data/spec/mongoid/criteria_projection_spec.rb +1 -4
- data/spec/mongoid/criteria_spec.rb +5 -9
- data/spec/mongoid/document_spec.rb +0 -27
- data/spec/mongoid/errors/readonly_document_spec.rb +2 -2
- data/spec/mongoid/extensions/hash_spec.rb +3 -3
- data/spec/mongoid/extensions/time_spec.rb +8 -43
- data/spec/mongoid/extensions/time_with_zone_spec.rb +7 -52
- data/spec/mongoid/fields/localized_spec.rb +46 -28
- data/spec/mongoid/fields_spec.rb +136 -77
- data/spec/mongoid/findable_spec.rb +391 -34
- data/spec/mongoid/indexable_spec.rb +16 -10
- data/spec/mongoid/interceptable_spec.rb +153 -442
- data/spec/mongoid/interceptable_spec_models.rb +111 -51
- data/spec/mongoid/persistable/deletable_spec.rb +26 -6
- data/spec/mongoid/persistable/destroyable_spec.rb +26 -6
- data/spec/mongoid/persistable/incrementable_spec.rb +37 -0
- data/spec/mongoid/persistable/logical_spec.rb +37 -0
- data/spec/mongoid/persistable/poppable_spec.rb +36 -0
- data/spec/mongoid/persistable/pullable_spec.rb +72 -0
- data/spec/mongoid/persistable/pushable_spec.rb +72 -0
- data/spec/mongoid/persistable/renamable_spec.rb +36 -0
- data/spec/mongoid/persistable/savable_spec.rb +96 -0
- data/spec/mongoid/persistable/settable_spec.rb +37 -0
- data/spec/mongoid/persistable/unsettable_spec.rb +36 -0
- data/spec/mongoid/persistable/updatable_spec.rb +20 -28
- data/spec/mongoid/persistable/upsertable_spec.rb +80 -6
- data/spec/mongoid/persistence_context_spec.rb +7 -57
- data/spec/mongoid/query_cache_spec.rb +56 -61
- data/spec/mongoid/reloadable_spec.rb +24 -28
- data/spec/mongoid/scopable_spec.rb +70 -0
- data/spec/mongoid/serializable_spec.rb +23 -44
- data/spec/mongoid/stateful_spec.rb +122 -8
- data/spec/mongoid/tasks/database_rake_spec.rb +74 -0
- data/spec/mongoid/tasks/database_spec.rb +127 -0
- data/spec/mongoid/timestamps/created_spec.rb +0 -23
- data/spec/mongoid/timestamps_spec.rb +9 -11
- data/spec/mongoid/touchable_spec.rb +277 -5
- data/spec/mongoid/touchable_spec_models.rb +3 -1
- data/spec/mongoid/traversable_spec.rb +9 -24
- data/spec/mongoid/validatable/associated_spec.rb +34 -27
- data/spec/mongoid/validatable/uniqueness_spec.rb +2 -3
- data/spec/mongoid_spec.rb +36 -10
- data/spec/shared/LICENSE +20 -0
- data/spec/shared/bin/get-mongodb-download-url +17 -0
- data/spec/shared/bin/s3-copy +45 -0
- data/spec/shared/bin/s3-upload +69 -0
- data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
- data/spec/shared/lib/mrss/cluster_config.rb +231 -0
- data/spec/shared/lib/mrss/constraints.rb +378 -0
- data/spec/shared/lib/mrss/docker_runner.rb +298 -0
- data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
- data/spec/shared/lib/mrss/event_subscriber.rb +210 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +238 -0
- data/spec/shared/lib/mrss/server_version_registry.rb +113 -0
- data/spec/shared/lib/mrss/session_registry.rb +69 -0
- data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
- data/spec/shared/lib/mrss/spec_organizer.rb +179 -0
- data/spec/shared/lib/mrss/utils.rb +37 -0
- data/spec/shared/share/Dockerfile.erb +321 -0
- data/spec/shared/share/haproxy-1.conf +16 -0
- data/spec/shared/share/haproxy-2.conf +17 -0
- data/spec/shared/shlib/config.sh +27 -0
- data/spec/shared/shlib/distro.sh +74 -0
- data/spec/shared/shlib/server.sh +416 -0
- data/spec/shared/shlib/set_env.sh +169 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/support/immutable_ids.rb +118 -0
- data/spec/support/macros.rb +47 -15
- data/spec/support/models/artist.rb +0 -1
- data/spec/support/models/band.rb +1 -0
- data/spec/support/models/building.rb +2 -0
- data/spec/support/models/name.rb +0 -10
- data/spec/support/models/person.rb +0 -1
- data/spec/support/models/product.rb +1 -0
- data.tar.gz.sig +0 -0
- metadata +745 -637
- metadata.gz.sig +2 -0
- data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -60
- data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -60
- data/spec/support/models/purse.rb +0 -9
@@ -476,6 +476,188 @@ describe Mongoid::Changeable do
|
|
476
476
|
end
|
477
477
|
end
|
478
478
|
end
|
479
|
+
|
480
|
+
context "when including key word args" do
|
481
|
+
|
482
|
+
let(:person) { Person.new }
|
483
|
+
|
484
|
+
context "when only including from" do
|
485
|
+
|
486
|
+
context "when the object has not changed" do
|
487
|
+
|
488
|
+
it "returns false" do
|
489
|
+
expect(person.send(:attribute_changed?, :score, from: nil)).to be false
|
490
|
+
end
|
491
|
+
|
492
|
+
it "returns false using (attribute)_changed?" do
|
493
|
+
expect(person.score_changed?(from: nil)).to be false
|
494
|
+
end
|
495
|
+
end
|
496
|
+
|
497
|
+
context "when the object has changed from the wrong item" do
|
498
|
+
|
499
|
+
before do
|
500
|
+
person.score = 2
|
501
|
+
end
|
502
|
+
|
503
|
+
it "returns false" do
|
504
|
+
expect(person.send(:attribute_changed?, :score, from: 1)).to be false
|
505
|
+
end
|
506
|
+
|
507
|
+
it "returns false using (attribute)_changed?" do
|
508
|
+
expect(person.score_changed?(from: 1)).to be false
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
512
|
+
context "when the object has changed from the correct item" do
|
513
|
+
|
514
|
+
before do
|
515
|
+
person.score = 2
|
516
|
+
end
|
517
|
+
|
518
|
+
it "returns true" do
|
519
|
+
expect(person.send(:attribute_changed?, :score, from: nil)).to be true
|
520
|
+
end
|
521
|
+
|
522
|
+
it "returns true using (attribute)_changed?" do
|
523
|
+
expect(person.score_changed?(from: nil)).to be true
|
524
|
+
end
|
525
|
+
end
|
526
|
+
end
|
527
|
+
|
528
|
+
context "when only including to" do
|
529
|
+
|
530
|
+
context "when the object has not changed" do
|
531
|
+
|
532
|
+
it "returns false" do
|
533
|
+
expect(person.send(:attribute_changed?, :score, to: nil)).to be false
|
534
|
+
end
|
535
|
+
|
536
|
+
it "returns false using (attribute)_changed?" do
|
537
|
+
expect(person.score_changed?(to: nil)).to be false
|
538
|
+
end
|
539
|
+
end
|
540
|
+
|
541
|
+
context "when the object has changed to the wrong item" do
|
542
|
+
|
543
|
+
before do
|
544
|
+
person.score = 2
|
545
|
+
end
|
546
|
+
|
547
|
+
it "returns false" do
|
548
|
+
expect(person.send(:attribute_changed?, :score, to: 1)).to be false
|
549
|
+
end
|
550
|
+
|
551
|
+
it "returns false using (attribute)_changed?" do
|
552
|
+
expect(person.score_changed?(to: 1)).to be false
|
553
|
+
end
|
554
|
+
end
|
555
|
+
|
556
|
+
context "when the object has changed to the correct item" do
|
557
|
+
|
558
|
+
before do
|
559
|
+
person.score = 2
|
560
|
+
end
|
561
|
+
|
562
|
+
it "returns true" do
|
563
|
+
expect(person.send(:attribute_changed?, :score, to: 2)).to be true
|
564
|
+
end
|
565
|
+
|
566
|
+
it "returns true using (attribute)_changed?" do
|
567
|
+
expect(person.score_changed?(to: 2)).to be true
|
568
|
+
end
|
569
|
+
end
|
570
|
+
end
|
571
|
+
|
572
|
+
context "when including from and to" do
|
573
|
+
|
574
|
+
context "when the object has not changed" do
|
575
|
+
|
576
|
+
it "returns false" do
|
577
|
+
expect(person.send(:attribute_changed?, :score, from: nil, to: nil)).to be false
|
578
|
+
end
|
579
|
+
|
580
|
+
it "returns false using (attribute)_changed?" do
|
581
|
+
expect(person.score_changed?(from: nil, to: nil)).to be false
|
582
|
+
end
|
583
|
+
end
|
584
|
+
|
585
|
+
context "when only the from is correct" do
|
586
|
+
|
587
|
+
before do
|
588
|
+
person.score = 2
|
589
|
+
end
|
590
|
+
|
591
|
+
it "returns false" do
|
592
|
+
expect(person.send(:attribute_changed?, :score, from: nil, to: 3)).to be false
|
593
|
+
end
|
594
|
+
|
595
|
+
it "returns false using (attribute)_changed?" do
|
596
|
+
expect(person.score_changed?(from: nil, to: 3)).to be false
|
597
|
+
end
|
598
|
+
end
|
599
|
+
|
600
|
+
context "when only the to is correct" do
|
601
|
+
|
602
|
+
before do
|
603
|
+
person.score = 2
|
604
|
+
end
|
605
|
+
|
606
|
+
it "returns false" do
|
607
|
+
expect(person.send(:attribute_changed?, :score, from: 1, to: 2)).to be false
|
608
|
+
end
|
609
|
+
|
610
|
+
it "returns false using (attribute)_changed?" do
|
611
|
+
expect(person.score_changed?(from: 1, to: 2)).to be false
|
612
|
+
end
|
613
|
+
end
|
614
|
+
|
615
|
+
context "when the from and to are correct" do
|
616
|
+
|
617
|
+
before do
|
618
|
+
person.score = 2
|
619
|
+
end
|
620
|
+
|
621
|
+
it "returns true" do
|
622
|
+
expect(person.send(:attribute_changed?, :score, from: nil, to: 2)).to be true
|
623
|
+
end
|
624
|
+
|
625
|
+
it "returns true using (attribute)_changed?" do
|
626
|
+
expect(person.score_changed?(from: nil, to: 2)).to be true
|
627
|
+
end
|
628
|
+
end
|
629
|
+
|
630
|
+
context "when value is mongoized" do
|
631
|
+
|
632
|
+
before do
|
633
|
+
person.score = "2"
|
634
|
+
end
|
635
|
+
|
636
|
+
it "returns true with mongoized value" do
|
637
|
+
expect(person.send(:attribute_changed?, :score, from: nil, to: 2)).to be true
|
638
|
+
end
|
639
|
+
|
640
|
+
it "returns true with mongoized value using (attribute)_changed?" do
|
641
|
+
expect(person.score_changed?(from: nil, to: 2)).to be true
|
642
|
+
end
|
643
|
+
end
|
644
|
+
|
645
|
+
context "when value is mongoized" do
|
646
|
+
|
647
|
+
before do
|
648
|
+
person.score = "2"
|
649
|
+
end
|
650
|
+
|
651
|
+
it "returns false with unmongoized value" do
|
652
|
+
expect(person.send(:attribute_changed?, :score, from: nil, to: "2")).to be false
|
653
|
+
end
|
654
|
+
|
655
|
+
it "returns false with unmongoized value using (attribute)_changed?" do
|
656
|
+
expect(person.score_changed?(from: nil, to: "2")).to be false
|
657
|
+
end
|
658
|
+
end
|
659
|
+
end
|
660
|
+
end
|
479
661
|
end
|
480
662
|
|
481
663
|
describe "#attribute_changed_from_default?" do
|
@@ -1167,20 +1349,10 @@ describe Mongoid::Changeable do
|
|
1167
1349
|
|
1168
1350
|
context "when the document is embedded" do
|
1169
1351
|
|
1170
|
-
let(:person)
|
1171
|
-
|
1172
|
-
end
|
1352
|
+
let(:person) { Person.create(title: "Grand Poobah") }
|
1353
|
+
let(:address) { person.addresses.create(street: "Oxford St") }
|
1173
1354
|
|
1174
|
-
|
1175
|
-
Address.instantiate(street: "Oxford St")
|
1176
|
-
end
|
1177
|
-
|
1178
|
-
before do
|
1179
|
-
person.addresses << address
|
1180
|
-
person.instance_variable_set(:@new_record, false)
|
1181
|
-
address.instance_variable_set(:@new_record, false)
|
1182
|
-
address.street = "Bond St"
|
1183
|
-
end
|
1355
|
+
before { address.street = "Bond St" }
|
1184
1356
|
|
1185
1357
|
it "returns a hash of field names and new values" do
|
1186
1358
|
expect(address.setters).to eq(
|
@@ -1189,17 +1361,9 @@ describe Mongoid::Changeable do
|
|
1189
1361
|
end
|
1190
1362
|
|
1191
1363
|
context "when the document is embedded multiple levels" do
|
1192
|
-
|
1193
|
-
|
1194
|
-
|
1195
|
-
end
|
1196
|
-
|
1197
|
-
before do
|
1198
|
-
location.instance_variable_set(:@new_record, false)
|
1199
|
-
address.locations << location
|
1200
|
-
location.name = "Work"
|
1201
|
-
end
|
1202
|
-
|
1364
|
+
let(:location) { address.locations.create(name: "Home") }
|
1365
|
+
before { location.name = "Work" }
|
1366
|
+
|
1203
1367
|
it "returns the proper hash with locations" do
|
1204
1368
|
expect(location.setters).to eq(
|
1205
1369
|
{ "addresses.0.locations.0.name" => "Work" }
|
@@ -1479,6 +1643,117 @@ describe Mongoid::Changeable do
|
|
1479
1643
|
end
|
1480
1644
|
end
|
1481
1645
|
|
1646
|
+
describe '#attribute_before_last_save' do
|
1647
|
+
let(:person) do
|
1648
|
+
Person.create!(title: "Grand Poobah")
|
1649
|
+
end
|
1650
|
+
|
1651
|
+
before do
|
1652
|
+
person.title = "Captain Obvious"
|
1653
|
+
end
|
1654
|
+
|
1655
|
+
context "when the document has been saved" do
|
1656
|
+
before do
|
1657
|
+
person.save!
|
1658
|
+
end
|
1659
|
+
|
1660
|
+
it "returns the changes" do
|
1661
|
+
expect(person.attribute_before_last_save(:title)).to eq("Grand Poobah")
|
1662
|
+
expect(person.title_before_last_save).to eq("Grand Poobah")
|
1663
|
+
end
|
1664
|
+
end
|
1665
|
+
|
1666
|
+
context "when the document has not been saved" do
|
1667
|
+
it "returns no changes" do
|
1668
|
+
expect(person.attribute_before_last_save(:title)).to be_nil
|
1669
|
+
expect(person.title_before_last_save).to be_nil
|
1670
|
+
end
|
1671
|
+
end
|
1672
|
+
end
|
1673
|
+
|
1674
|
+
describe '#saved_change_to_attribute' do
|
1675
|
+
let(:person) do
|
1676
|
+
Person.create!(title: "Grand Poobah")
|
1677
|
+
end
|
1678
|
+
|
1679
|
+
before do
|
1680
|
+
person.title = "Captain Obvious"
|
1681
|
+
end
|
1682
|
+
|
1683
|
+
context "when the document has been saved" do
|
1684
|
+
before do
|
1685
|
+
person.save!
|
1686
|
+
end
|
1687
|
+
|
1688
|
+
it "returns the changes" do
|
1689
|
+
expect(person.saved_change_to_attribute(:title)).to eq(["Grand Poobah", "Captain Obvious"])
|
1690
|
+
expect(person.saved_change_to_title).to eq(["Grand Poobah", "Captain Obvious"])
|
1691
|
+
end
|
1692
|
+
end
|
1693
|
+
|
1694
|
+
context "when the document has not been saved" do
|
1695
|
+
it "returns changes for the previous save" do
|
1696
|
+
expect(person.saved_change_to_attribute(:title)).to eq([nil, "Grand Poobah"])
|
1697
|
+
expect(person.saved_change_to_title).to eq([nil, "Grand Poobah"])
|
1698
|
+
end
|
1699
|
+
end
|
1700
|
+
end
|
1701
|
+
|
1702
|
+
describe '#saved_change_to_attribute?' do
|
1703
|
+
context "when the document has been saved" do
|
1704
|
+
let(:person) do
|
1705
|
+
Person.create!(title: "Grand Poobah")
|
1706
|
+
end
|
1707
|
+
|
1708
|
+
before do
|
1709
|
+
person.title = "Captain Obvious"
|
1710
|
+
end
|
1711
|
+
|
1712
|
+
before do
|
1713
|
+
person.save!
|
1714
|
+
end
|
1715
|
+
|
1716
|
+
it "detects the changes" do
|
1717
|
+
expect(person.saved_change_to_attribute?(:title)).to be_truthy
|
1718
|
+
expect(person.saved_change_to_attribute?(:title, from: "Grand Poobah")).to be_truthy
|
1719
|
+
expect(person.saved_change_to_attribute?(:title, to: "Captain Obvious")).to be_truthy
|
1720
|
+
expect(person.saved_change_to_attribute?(:title, from: "Grand Poobah", to: "Captain Obvious")).to be_truthy
|
1721
|
+
expect(person.saved_change_to_title?(from: "Grand Poobah", to: "Captain Obvious")).to be_truthy
|
1722
|
+
expect(person.saved_change_to_attribute?(:age)).to be_falsey
|
1723
|
+
expect(person.saved_change_to_age?).to be_falsey
|
1724
|
+
end
|
1725
|
+
end
|
1726
|
+
|
1727
|
+
context "when the document has not been saved" do
|
1728
|
+
let(:person) do
|
1729
|
+
Person.new(title: "Grand Poobah")
|
1730
|
+
end
|
1731
|
+
|
1732
|
+
it "returns changes for the previous save" do
|
1733
|
+
expect(person.saved_change_to_attribute?(:title)).to be_falsey
|
1734
|
+
expect(person.saved_change_to_title?).to be_falsey
|
1735
|
+
end
|
1736
|
+
end
|
1737
|
+
end
|
1738
|
+
|
1739
|
+
describe '#will_save_change_to_attribute?' do
|
1740
|
+
let(:person) do
|
1741
|
+
Person.create!(title: "Grand Poobah")
|
1742
|
+
end
|
1743
|
+
|
1744
|
+
before do
|
1745
|
+
person.title = "Captain Obvious"
|
1746
|
+
end
|
1747
|
+
|
1748
|
+
it 'correctly detects changes' do
|
1749
|
+
expect(person.will_save_change_to_attribute?(:title)).to eq(true)
|
1750
|
+
expect(person.will_save_change_to_title?).to eq(true)
|
1751
|
+
expect(person.will_save_change_to_attribute?(:score)).to eq(false)
|
1752
|
+
expect(person.will_save_change_to_score?).to eq(false)
|
1753
|
+
end
|
1754
|
+
|
1755
|
+
end
|
1756
|
+
|
1482
1757
|
context "when fields have been defined pre-dirty inclusion" do
|
1483
1758
|
|
1484
1759
|
let(:document) do
|
@@ -738,19 +738,6 @@ describe Mongoid::Clients do
|
|
738
738
|
end
|
739
739
|
end
|
740
740
|
|
741
|
-
context "when provided a class that extends another document" do
|
742
|
-
|
743
|
-
let(:klass) do
|
744
|
-
Class.new(Band)
|
745
|
-
end
|
746
|
-
|
747
|
-
it "raises an error" do
|
748
|
-
expect {
|
749
|
-
klass.store_in(database: :artists)
|
750
|
-
}.to raise_error(Mongoid::Errors::InvalidStorageParent)
|
751
|
-
end
|
752
|
-
end
|
753
|
-
|
754
741
|
context "when provided a hash" do
|
755
742
|
|
756
743
|
context "when the hash is not valid" do
|
@@ -762,6 +749,128 @@ describe Mongoid::Clients do
|
|
762
749
|
end
|
763
750
|
end
|
764
751
|
end
|
752
|
+
|
753
|
+
context "when it is called on a subclass" do
|
754
|
+
|
755
|
+
let(:client) { StoreParent.collection.client }
|
756
|
+
let(:parent) { StoreParent.create! }
|
757
|
+
let(:child1) { StoreChild1.create! }
|
758
|
+
let(:child2) { StoreChild2.create! }
|
759
|
+
|
760
|
+
before do
|
761
|
+
class StoreParent
|
762
|
+
include Mongoid::Document
|
763
|
+
end
|
764
|
+
|
765
|
+
class StoreChild1 < StoreParent
|
766
|
+
end
|
767
|
+
|
768
|
+
class StoreChild2 < StoreParent
|
769
|
+
end
|
770
|
+
end
|
771
|
+
|
772
|
+
after do
|
773
|
+
Object.send(:remove_const, :StoreParent)
|
774
|
+
Object.send(:remove_const, :StoreChild1)
|
775
|
+
Object.send(:remove_const, :StoreChild2)
|
776
|
+
end
|
777
|
+
|
778
|
+
context "when it is not called on the parent" do
|
779
|
+
|
780
|
+
context "when it is called on all subclasses" do
|
781
|
+
|
782
|
+
before do
|
783
|
+
StoreChild1.store_in collection: :store_ones
|
784
|
+
StoreChild2.store_in collection: :store_twos
|
785
|
+
[ parent, child1, child2 ]
|
786
|
+
end
|
787
|
+
|
788
|
+
let(:db_parent) { client['store_parents'].find.first }
|
789
|
+
let(:db_child1) { client['store_ones'].find.first }
|
790
|
+
let(:db_child2) { client['store_twos'].find.first }
|
791
|
+
|
792
|
+
it "stores the documents in the correct collections" do
|
793
|
+
expect(db_parent).to eq({ "_id" => parent.id, "_type" => "StoreParent" })
|
794
|
+
expect(db_child1).to eq({ "_id" => child1.id, "_type" => "StoreChild1" })
|
795
|
+
expect(db_child2).to eq({ "_id" => child2.id, "_type" => "StoreChild2" })
|
796
|
+
end
|
797
|
+
|
798
|
+
it "only queries from its own collections" do
|
799
|
+
expect(StoreParent.count).to eq(1)
|
800
|
+
expect(StoreChild1.count).to eq(1)
|
801
|
+
expect(StoreChild2.count).to eq(1)
|
802
|
+
end
|
803
|
+
end
|
804
|
+
|
805
|
+
context "when it is called on one of the subclasses" do
|
806
|
+
|
807
|
+
before do
|
808
|
+
StoreChild1.store_in collection: :store_ones
|
809
|
+
[ parent, child1, child2 ]
|
810
|
+
end
|
811
|
+
|
812
|
+
let(:db_parent) { client['store_parents'].find.first }
|
813
|
+
let(:db_child1) { client['store_ones'].find.first }
|
814
|
+
let(:db_child2) { client['store_parents'].find.to_a.last }
|
815
|
+
|
816
|
+
it "stores the documents in the correct collections" do
|
817
|
+
expect(db_parent).to eq({ "_id" => parent.id, "_type" => "StoreParent" })
|
818
|
+
expect(db_child1).to eq({ "_id" => child1.id, "_type" => "StoreChild1" })
|
819
|
+
expect(db_child2).to eq({ "_id" => child2.id, "_type" => "StoreChild2" })
|
820
|
+
end
|
821
|
+
|
822
|
+
it "queries from its own collections" do
|
823
|
+
expect(StoreParent.count).to eq(2)
|
824
|
+
expect(StoreChild1.count).to eq(1)
|
825
|
+
expect(StoreChild2.count).to eq(1)
|
826
|
+
end
|
827
|
+
end
|
828
|
+
end
|
829
|
+
|
830
|
+
context "when it is called on the parent" do
|
831
|
+
|
832
|
+
before do
|
833
|
+
StoreParent.store_in collection: :st_parents
|
834
|
+
end
|
835
|
+
|
836
|
+
context "when it is called on all subclasses" do
|
837
|
+
|
838
|
+
before do
|
839
|
+
StoreChild1.store_in collection: :store_ones
|
840
|
+
StoreChild2.store_in collection: :store_twos
|
841
|
+
[ parent, child1, child2 ]
|
842
|
+
end
|
843
|
+
|
844
|
+
let(:db_parent) { client['st_parents'].find.first }
|
845
|
+
let(:db_child1) { client['store_ones'].find.first }
|
846
|
+
let(:db_child2) { client['store_twos'].find.first }
|
847
|
+
|
848
|
+
it "stores the documents in the correct collections" do
|
849
|
+
expect(db_parent).to eq({ "_id" => parent.id, "_type" => "StoreParent" })
|
850
|
+
expect(db_child1).to eq({ "_id" => child1.id, "_type" => "StoreChild1" })
|
851
|
+
expect(db_child2).to eq({ "_id" => child2.id, "_type" => "StoreChild2" })
|
852
|
+
end
|
853
|
+
end
|
854
|
+
|
855
|
+
context "when it is called on one of the subclasses" do
|
856
|
+
|
857
|
+
before do
|
858
|
+
StoreChild1.store_in collection: :store_ones
|
859
|
+
[ parent, child1, child2 ]
|
860
|
+
end
|
861
|
+
|
862
|
+
let(:db_parent) { client['st_parents'].find.first }
|
863
|
+
let(:db_child1) { client['store_ones'].find.first }
|
864
|
+
let(:db_child2) { client['st_parents'].find.to_a.last }
|
865
|
+
|
866
|
+
it "stores the documents in the correct collections" do
|
867
|
+
expect(db_parent).to eq({ "_id" => parent.id, "_type" => "StoreParent" })
|
868
|
+
expect(db_child1).to eq({ "_id" => child1.id, "_type" => "StoreChild1" })
|
869
|
+
expect(db_child2).to eq({ "_id" => child2.id, "_type" => "StoreChild2" })
|
870
|
+
end
|
871
|
+
end
|
872
|
+
end
|
873
|
+
end
|
765
874
|
end
|
766
875
|
|
767
876
|
describe ".with" do
|
@@ -0,0 +1,158 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe Mongoid::CollectionConfigurable do
|
6
|
+
|
7
|
+
before(:all) do
|
8
|
+
class CollectionConfigurableValidOptions
|
9
|
+
include Mongoid::Document
|
10
|
+
|
11
|
+
store_in collection_options: {
|
12
|
+
capped: true,
|
13
|
+
size: 2560
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
class CollectionConfigurableUnknownOptions
|
18
|
+
include Mongoid::Document
|
19
|
+
|
20
|
+
store_in collection_options: {
|
21
|
+
i_am_not_an_option: true,
|
22
|
+
let_me: { fail: true }
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
class CollectionConfigurableInvalidOptions
|
27
|
+
include Mongoid::Document
|
28
|
+
|
29
|
+
store_in collection_options: {
|
30
|
+
capped: true
|
31
|
+
# Creating a capped collection requires `size` field; therefore,
|
32
|
+
# an attempt to create a collection with only `capped : true` option
|
33
|
+
# fails.
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
after(:all) do
|
39
|
+
Mongoid.deregister_model(CollectionConfigurableValidOptions)
|
40
|
+
Object.send(:remove_const, :CollectionConfigurableValidOptions)
|
41
|
+
Mongoid.deregister_model(CollectionConfigurableUnknownOptions)
|
42
|
+
Object.send(:remove_const, :CollectionConfigurableUnknownOptions)
|
43
|
+
Mongoid.deregister_model(CollectionConfigurableInvalidOptions)
|
44
|
+
Object.send(:remove_const, :CollectionConfigurableInvalidOptions)
|
45
|
+
end
|
46
|
+
|
47
|
+
after(:each) do
|
48
|
+
[
|
49
|
+
CollectionConfigurableValidOptions,
|
50
|
+
CollectionConfigurableUnknownOptions
|
51
|
+
].each do |klazz|
|
52
|
+
klazz.collection.drop
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'when collection does not exist' do
|
57
|
+
context 'with valid options' do
|
58
|
+
let(:subject) do
|
59
|
+
CollectionConfigurableValidOptions
|
60
|
+
end
|
61
|
+
|
62
|
+
before(:each) do
|
63
|
+
subject.create_collection
|
64
|
+
end
|
65
|
+
|
66
|
+
let(:coll_options) do
|
67
|
+
subject.collection.database.list_collections(filter: { name: subject.collection_name.to_s }).first
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'creates the collection' do
|
71
|
+
expect(coll_options).not_to be_nil
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'passes collection options' do
|
75
|
+
expect(coll_options.dig('options', 'capped')).to eq(true)
|
76
|
+
expect(coll_options.dig('options', 'size')).to eq(2560)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'with an unknown collection options' do
|
81
|
+
let(:subject) do
|
82
|
+
CollectionConfigurableUnknownOptions
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'raises an error' do
|
86
|
+
expect do
|
87
|
+
subject.create_collection
|
88
|
+
end.to raise_error(Mongoid::Errors::CreateCollectionFailure)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'with invalid options' do
|
93
|
+
let(:subject) do
|
94
|
+
CollectionConfigurableInvalidOptions
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'raises an error' do
|
98
|
+
expect do
|
99
|
+
subject.create_collection
|
100
|
+
end.to raise_error(Mongoid::Errors::CreateCollectionFailure)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context 'when collection exists' do
|
106
|
+
let(:subject) do
|
107
|
+
CollectionConfigurableValidOptions
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'when force is false' do
|
111
|
+
let(:logger) do
|
112
|
+
double("logger").tap do |log|
|
113
|
+
expect(log).to receive(:debug).once.with(/Collection '#{subject.collection_name}' already exist/)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
before do
|
118
|
+
allow(subject).to receive(:logger).and_return(logger)
|
119
|
+
subject.collection.create
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'logs a message' do
|
123
|
+
subject.create_collection
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
context 'when force is true' do
|
128
|
+
let(:logger) do
|
129
|
+
double("logger")
|
130
|
+
end
|
131
|
+
|
132
|
+
let(:coll_options) do
|
133
|
+
subject.collection.database.list_collections(filter: { name: subject.collection_name.to_s }).first
|
134
|
+
end
|
135
|
+
|
136
|
+
before do
|
137
|
+
allow(subject).to receive(:logger).and_return(logger)
|
138
|
+
subject.collection.create
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'does not log a message' do
|
142
|
+
expect(logger).to receive(:debug).never.with(/Collection '#{subject.collection_name}' already exist/)
|
143
|
+
subject.create_collection(force: true)
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'creates the collection' do
|
147
|
+
subject.create_collection(force: true)
|
148
|
+
expect(coll_options).not_to be_nil
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'passes collection options' do
|
152
|
+
subject.create_collection(force: true)
|
153
|
+
expect(coll_options.dig('options', 'capped')).to eq(true)
|
154
|
+
expect(coll_options.dig('options', 'size')).to eq(2560)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|