mongoid 8.0.13 → 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 +17 -66
- data/lib/config/locales/en.yml +46 -40
- data/lib/mongoid/association/accessors.rb +3 -7
- data/lib/mongoid/association/builders.rb +1 -1
- data/lib/mongoid/association/depending.rb +4 -8
- 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 +2 -2
- data/lib/mongoid/association/macros.rb +0 -6
- data/lib/mongoid/association/nested/many.rb +3 -38
- data/lib/mongoid/association/nested/nested_buildable.rb +0 -14
- 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 +4 -103
- 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/factory.rb +0 -4
- 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 -89
- data/lib/mongoid/contextual/aggregable/memory.rb +2 -5
- data/lib/mongoid/contextual/atomic.rb +1 -1
- data/lib/mongoid/contextual/memory.rb +240 -51
- 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 -13
- data/lib/mongoid/criteria/queryable/optional.rb +8 -8
- data/lib/mongoid/criteria/queryable/selectable.rb +43 -121
- 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 -2
- data/lib/mongoid/extensions/hash.rb +3 -51
- 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/matchable.rb +1 -6
- data/lib/mongoid/matcher/eq_impl.rb +1 -1
- data/lib/mongoid/matcher/eq_impl_with_regexp.rb +5 -3
- data/lib/mongoid/matcher/regex.rb +9 -8
- data/lib/mongoid/matcher/type.rb +1 -1
- data/lib/mongoid/matcher.rb +0 -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/threaded.rb +0 -3
- 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 -20
- data/lib/mongoid/validatable.rb +4 -10
- data/lib/mongoid/version.rb +1 -5
- data/lib/mongoid/warnings.rb +17 -2
- data/lib/mongoid.rb +16 -3
- data/spec/integration/app_spec.rb +2 -20
- data/spec/integration/associations/embeds_one_spec.rb +5 -25
- data/spec/integration/associations/has_and_belongs_to_many_spec.rb +0 -55
- data/spec/integration/callbacks_spec.rb +99 -12
- data/spec/integration/discriminator_key_spec.rb +4 -5
- data/spec/integration/dots_and_dollars_spec.rb +2 -12
- data/spec/integration/i18n_fallbacks_spec.rb +3 -2
- data/spec/integration/matcher_operator_data/regex.yml +0 -21
- 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 -103
- data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +9 -195
- data/spec/mongoid/association/syncable_spec.rb +1 -1
- data/spec/mongoid/attributes/nested_spec.rb +10 -204
- data/spec/mongoid/attributes_spec.rb +3 -33
- data/spec/mongoid/changeable_spec.rb +299 -24
- data/spec/mongoid/clients/factory_spec.rb +0 -30
- 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/aggregable/memory_spec.rb +0 -91
- data/spec/mongoid/contextual/memory_spec.rb +332 -253
- 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 -2
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +0 -235
- 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 -11
- 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 -239
- 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/numericality_spec.rb +0 -16
- data/spec/mongoid/validatable/uniqueness_spec.rb +2 -3
- data/spec/mongoid_spec.rb +36 -10
- data/spec/shared/lib/mrss/docker_runner.rb +1 -1
- data/spec/shared/lib/mrss/server_version_registry.rb +1 -1
- data/spec/shared/lib/mrss/spec_organizer.rb +3 -32
- data/spec/shared/share/Dockerfile.erb +85 -15
- data/spec/shared/shlib/distro.sh +0 -10
- data/spec/shared/shlib/server.sh +27 -34
- data/spec/shared/shlib/set_env.sh +68 -9
- data/spec/spec_helper.rb +5 -0
- data/spec/support/expectations.rb +17 -20
- 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 +715 -671
- metadata.gz.sig +2 -0
- data/lib/mongoid/errors/in_memory_regexp_timeout.rb +0 -26
- data/lib/mongoid/field_readable.rb +0 -70
- data/lib/mongoid/matcher/regexp_budget.rb +0 -389
- data/lib/mongoid/validatable/numericality.rb +0 -19
- data/spec/integration/matcher_regexp_timeout_spec.rb +0 -215
- data/spec/integration/query_operator_guard_spec.rb +0 -89
- data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -61
- data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -61
- data/spec/mongoid/matcher/regexp_budget_spec.rb +0 -570
- data/spec/shared/CANDIDATE.md +0 -28
- data/spec/shared/lib/mrss/release/candidate.rb +0 -281
- data/spec/shared/lib/mrss/release/product_data.rb +0 -144
- data/spec/shared/lib/tasks/candidate.rake +0 -64
- data/spec/support/models/purse.rb +0 -9
|
@@ -4,14 +4,12 @@ require "spec_helper"
|
|
|
4
4
|
require_relative "../has_and_belongs_to_many_models"
|
|
5
5
|
|
|
6
6
|
describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
|
|
7
|
+
config_override :raise_not_found_error, true
|
|
7
8
|
|
|
8
9
|
around(:each) do |example|
|
|
9
|
-
original_raise_not_found_error = Mongoid.raise_not_found_error
|
|
10
10
|
original_preferences_association = Person.relations["preferences"]
|
|
11
|
-
Mongoid.raise_not_found_error = true
|
|
12
11
|
Person.has_and_belongs_to_many :preferences, autosave: true
|
|
13
12
|
example.run
|
|
14
|
-
Mongoid.raise_not_found_error = original_raise_not_found_error
|
|
15
13
|
Person.relations["preferences"] = original_preferences_association
|
|
16
14
|
end
|
|
17
15
|
|
|
@@ -1757,6 +1755,43 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
|
|
|
1757
1755
|
end
|
|
1758
1756
|
end
|
|
1759
1757
|
|
|
1758
|
+
describe "#any?" do
|
|
1759
|
+
|
|
1760
|
+
let(:person) do
|
|
1761
|
+
Person.create!
|
|
1762
|
+
end
|
|
1763
|
+
|
|
1764
|
+
context "when nothing exists on the relation" do
|
|
1765
|
+
|
|
1766
|
+
context "when no document is added" do
|
|
1767
|
+
|
|
1768
|
+
let!(:sandwich) do
|
|
1769
|
+
Sandwich.create!
|
|
1770
|
+
end
|
|
1771
|
+
|
|
1772
|
+
it "returns false" do
|
|
1773
|
+
expect(sandwich.meats.any?).to be false
|
|
1774
|
+
end
|
|
1775
|
+
end
|
|
1776
|
+
|
|
1777
|
+
context "when the document is destroyed" do
|
|
1778
|
+
|
|
1779
|
+
before do
|
|
1780
|
+
Meat.create!
|
|
1781
|
+
end
|
|
1782
|
+
|
|
1783
|
+
let!(:sandwich) do
|
|
1784
|
+
Sandwich.create!
|
|
1785
|
+
end
|
|
1786
|
+
|
|
1787
|
+
it "returns false" do
|
|
1788
|
+
sandwich.destroy
|
|
1789
|
+
expect(sandwich.meats.any?).to be false
|
|
1790
|
+
end
|
|
1791
|
+
end
|
|
1792
|
+
end
|
|
1793
|
+
end
|
|
1794
|
+
|
|
1760
1795
|
context "when documents have been persisted" do
|
|
1761
1796
|
|
|
1762
1797
|
let!(:preference) do
|
|
@@ -2268,13 +2303,6 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
|
|
|
2268
2303
|
end
|
|
2269
2304
|
end
|
|
2270
2305
|
|
|
2271
|
-
# Whether the conditions carry a pattern decides which branch of remove_all
|
|
2272
|
-
# runs, so anything that has to behave the same on both is exercised twice.
|
|
2273
|
-
conditions_variants = [
|
|
2274
|
-
[ 'no regular expression', nil ],
|
|
2275
|
-
[ 'a regular expression', { name: /Test/ } ]
|
|
2276
|
-
].freeze
|
|
2277
|
-
|
|
2278
2306
|
%i[ delete_all destroy_all ].each do |method|
|
|
2279
2307
|
describe "\##{method}" do
|
|
2280
2308
|
context 'when the relation is not polymorphic' do
|
|
@@ -2346,47 +2374,6 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
|
|
|
2346
2374
|
expect(person.preferences).to eq([])
|
|
2347
2375
|
end
|
|
2348
2376
|
end
|
|
2349
|
-
|
|
2350
|
-
context 'when the base holds the foreign keys' do
|
|
2351
|
-
# unbind_one pulls ids out of the base's foreign key array and marks
|
|
2352
|
-
# the base dirty, so which documents get unbound is visible here.
|
|
2353
|
-
# Only what the association already held is unbound, and that has to
|
|
2354
|
-
# hold whether or not the conditions carry a regular expression:
|
|
2355
|
-
# scanning under a regexp budget loads the association first, and
|
|
2356
|
-
# that load must not turn into an unbind of its own. See the note in
|
|
2357
|
-
# HasMany::Proxy#remove_all_bounded.
|
|
2358
|
-
let!(:person) do
|
|
2359
|
-
Person.create!.tap do |base|
|
|
2360
|
-
base.preferences.create!(name: 'Testing')
|
|
2361
|
-
base.preferences.create!(name: 'Test')
|
|
2362
|
-
end
|
|
2363
|
-
end
|
|
2364
|
-
|
|
2365
|
-
let(:ids) { person.preference_ids.dup }
|
|
2366
|
-
|
|
2367
|
-
conditions_variants.each do |description, conditions|
|
|
2368
|
-
context "when the conditions carry #{description}" do
|
|
2369
|
-
context 'when the association is already in memory' do
|
|
2370
|
-
it 'unbinds the deleted documents' do
|
|
2371
|
-
person.preferences.send(method, conditions)
|
|
2372
|
-
expect(person.preference_ids).to eq([])
|
|
2373
|
-
expect(person).to be_changed
|
|
2374
|
-
end
|
|
2375
|
-
end
|
|
2376
|
-
|
|
2377
|
-
context 'when the association has not been loaded' do
|
|
2378
|
-
let(:cold) { Person.find(person._id) }
|
|
2379
|
-
|
|
2380
|
-
it 'leaves the foreign keys alone' do
|
|
2381
|
-
expect(ids.length).to eq(2)
|
|
2382
|
-
cold.preferences.send(method, conditions)
|
|
2383
|
-
expect(cold.preference_ids).to eq(ids)
|
|
2384
|
-
expect(cold).not_to be_changed
|
|
2385
|
-
end
|
|
2386
|
-
end
|
|
2387
|
-
end
|
|
2388
|
-
end
|
|
2389
|
-
end
|
|
2390
2377
|
end
|
|
2391
2378
|
end
|
|
2392
2379
|
end
|
|
@@ -2480,10 +2467,7 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
|
|
|
2480
2467
|
context "when the id does not match" do
|
|
2481
2468
|
|
|
2482
2469
|
context "when config set to raise error" do
|
|
2483
|
-
|
|
2484
|
-
before do
|
|
2485
|
-
Mongoid.raise_not_found_error = true
|
|
2486
|
-
end
|
|
2470
|
+
config_override :raise_not_found_error, true
|
|
2487
2471
|
|
|
2488
2472
|
it "raises an error" do
|
|
2489
2473
|
expect {
|
|
@@ -2493,19 +2477,12 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
|
|
|
2493
2477
|
end
|
|
2494
2478
|
|
|
2495
2479
|
context "when config set not to raise error" do
|
|
2480
|
+
config_override :raise_not_found_error, false
|
|
2496
2481
|
|
|
2497
2482
|
let(:preference) do
|
|
2498
2483
|
person.preferences.find(BSON::ObjectId.new)
|
|
2499
2484
|
end
|
|
2500
2485
|
|
|
2501
|
-
before do
|
|
2502
|
-
Mongoid.raise_not_found_error = false
|
|
2503
|
-
end
|
|
2504
|
-
|
|
2505
|
-
after do
|
|
2506
|
-
Mongoid.raise_not_found_error = true
|
|
2507
|
-
end
|
|
2508
|
-
|
|
2509
2486
|
it "returns nil" do
|
|
2510
2487
|
expect(preference).to be_nil
|
|
2511
2488
|
end
|
|
@@ -2544,10 +2521,7 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
|
|
|
2544
2521
|
context "when the ids do not match" do
|
|
2545
2522
|
|
|
2546
2523
|
context "when config set to raise error" do
|
|
2547
|
-
|
|
2548
|
-
before do
|
|
2549
|
-
Mongoid.raise_not_found_error = true
|
|
2550
|
-
end
|
|
2524
|
+
config_override :raise_not_found_error, true
|
|
2551
2525
|
|
|
2552
2526
|
it "raises an error" do
|
|
2553
2527
|
expect {
|
|
@@ -2557,19 +2531,12 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
|
|
|
2557
2531
|
end
|
|
2558
2532
|
|
|
2559
2533
|
context "when config set not to raise error" do
|
|
2534
|
+
config_override :raise_not_found_error, false
|
|
2560
2535
|
|
|
2561
2536
|
let(:preferences) do
|
|
2562
2537
|
person.preferences.find([ BSON::ObjectId.new ])
|
|
2563
2538
|
end
|
|
2564
2539
|
|
|
2565
|
-
before do
|
|
2566
|
-
Mongoid.raise_not_found_error = false
|
|
2567
|
-
end
|
|
2568
|
-
|
|
2569
|
-
after do
|
|
2570
|
-
Mongoid.raise_not_found_error = true
|
|
2571
|
-
end
|
|
2572
|
-
|
|
2573
2540
|
it "returns an empty array" do
|
|
2574
2541
|
expect(preferences).to be_empty
|
|
2575
2542
|
end
|
|
@@ -3074,34 +3041,6 @@ describe Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy do
|
|
|
3074
3041
|
end
|
|
3075
3042
|
end
|
|
3076
3043
|
|
|
3077
|
-
# MONGOID-5844
|
|
3078
|
-
#
|
|
3079
|
-
# Specifically, this tests the case where the association is
|
|
3080
|
-
# initialized with a single element (so that Proxy#push does not take
|
|
3081
|
-
# the `concat` route), which causes `reset_unloaded` to be called, which
|
|
3082
|
-
# sets the `_unloaded` Criteria object to match only the specific element
|
|
3083
|
-
# that was given.
|
|
3084
|
-
#
|
|
3085
|
-
# The issue now is that when the events list is updated to be both events,
|
|
3086
|
-
# _unloaded matches one of them already, and the other has previously been
|
|
3087
|
-
# persisted so `new_record?` won't match it. We need to make sure the
|
|
3088
|
-
# `#size` logic properly accounts for this case.
|
|
3089
|
-
context 'when documents have been previously persisted' do
|
|
3090
|
-
let(:person1) { Person.create! }
|
|
3091
|
-
let(:person2) { Person.create! }
|
|
3092
|
-
let(:event1) { Event.create!(administrators: [ person1 ]) }
|
|
3093
|
-
let(:event2) { Event.create!(administrators: [ person2 ]) }
|
|
3094
|
-
|
|
3095
|
-
before do
|
|
3096
|
-
person1.administrated_events = [ event1, event2 ]
|
|
3097
|
-
end
|
|
3098
|
-
|
|
3099
|
-
it 'returns the number of associated documents [MONGOID-5844]' do
|
|
3100
|
-
expect(person1.administrated_events.to_a.size).to eq(2)
|
|
3101
|
-
expect(person1.administrated_events.size).to eq(2)
|
|
3102
|
-
end
|
|
3103
|
-
end
|
|
3104
|
-
|
|
3105
3044
|
context "when documents have not been persisted" do
|
|
3106
3045
|
|
|
3107
3046
|
before do
|
|
@@ -23,10 +23,9 @@ module RefHasManySpec
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
26
|
+
config_override :raise_not_found_error, true
|
|
26
27
|
|
|
27
28
|
before :all do
|
|
28
|
-
Mongoid.raise_not_found_error = true
|
|
29
|
-
|
|
30
29
|
Drug.belongs_to :person, primary_key: :username
|
|
31
30
|
Person.has_many :drugs, validate: false, primary_key: :username
|
|
32
31
|
end
|
|
@@ -2281,151 +2280,6 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
|
2281
2280
|
expect(person.posts).to eq([])
|
|
2282
2281
|
end
|
|
2283
2282
|
end
|
|
2284
|
-
|
|
2285
|
-
context 'when a document is appended with an id that is already loaded' do
|
|
2286
|
-
# Iterating the association moves an appended document out of _added
|
|
2287
|
-
# without adding it to _loaded, so the scan for matches and the
|
|
2288
|
-
# removal that follows see different instances for the same id.
|
|
2289
|
-
let(:person) { Person.create! }
|
|
2290
|
-
let!(:post) { person.posts.create!(title: 'Testing') }
|
|
2291
|
-
let(:reloaded) { Person.find(person._id) }
|
|
2292
|
-
|
|
2293
|
-
before do
|
|
2294
|
-
reloaded.posts.to_a
|
|
2295
|
-
reloaded.posts._target.push(
|
|
2296
|
-
Post.new(_id: post._id, title: 'Testing', person_id: reloaded._id)
|
|
2297
|
-
)
|
|
2298
|
-
end
|
|
2299
|
-
|
|
2300
|
-
shared_examples 'removes the document once' do
|
|
2301
|
-
it 'sets the association locally' do
|
|
2302
|
-
reloaded.posts.send(method, conditions)
|
|
2303
|
-
expect(reloaded.posts).to eq([])
|
|
2304
|
-
end
|
|
2305
|
-
|
|
2306
|
-
it 'deletes the documents from the database' do
|
|
2307
|
-
reloaded.posts.send(method, conditions)
|
|
2308
|
-
expect(Post.count).to eq(0)
|
|
2309
|
-
end
|
|
2310
|
-
end
|
|
2311
|
-
|
|
2312
|
-
context 'when the conditions carry no regular expression' do
|
|
2313
|
-
let(:conditions) { { title: 'Testing' } }
|
|
2314
|
-
|
|
2315
|
-
it_behaves_like 'removes the document once'
|
|
2316
|
-
end
|
|
2317
|
-
|
|
2318
|
-
context 'when the conditions carry a regular expression' do
|
|
2319
|
-
let(:conditions) { { title: /Testing/ } }
|
|
2320
|
-
|
|
2321
|
-
it_behaves_like 'removes the document once'
|
|
2322
|
-
end
|
|
2323
|
-
end
|
|
2324
|
-
|
|
2325
|
-
context 'when an appended document disagrees with the loaded one' do
|
|
2326
|
-
# Only the appended instance matches, so the removal has to drop that
|
|
2327
|
-
# id from both _loaded and _added. Removing by id and stopping at the
|
|
2328
|
-
# first hash that has it would take the loaded instance instead and
|
|
2329
|
-
# leave the unbound one behind.
|
|
2330
|
-
let(:person) { Person.create! }
|
|
2331
|
-
let!(:post) { person.posts.create!(title: 'Other') }
|
|
2332
|
-
let(:reloaded) { Person.find(person._id) }
|
|
2333
|
-
|
|
2334
|
-
before do
|
|
2335
|
-
reloaded.posts.to_a
|
|
2336
|
-
reloaded.posts._target.push(
|
|
2337
|
-
Post.new(_id: post._id, title: 'Testing', person_id: reloaded._id)
|
|
2338
|
-
)
|
|
2339
|
-
end
|
|
2340
|
-
|
|
2341
|
-
it 'deletes nothing from the database' do
|
|
2342
|
-
expect(reloaded.posts.send(method, { title: /Testing/ })).to eq(0)
|
|
2343
|
-
expect(Post.where(title: 'Other').count).to eq(1)
|
|
2344
|
-
end
|
|
2345
|
-
|
|
2346
|
-
it 'leaves no unbound document in the association' do
|
|
2347
|
-
reloaded.posts.send(method, { title: /Testing/ })
|
|
2348
|
-
expect(reloaded.posts._target.in_memory.map(&:person_id)).not_to include(nil)
|
|
2349
|
-
end
|
|
2350
|
-
end
|
|
2351
|
-
|
|
2352
|
-
context 'when a nested selector is evaluated while the association loads' do
|
|
2353
|
-
# Loading the association runs find callbacks, and application code in
|
|
2354
|
-
# one of those can evaluate a selector of its own. A scope opened
|
|
2355
|
-
# around the load would mark it as having nothing to bound, and that
|
|
2356
|
-
# suppresses the decision for the nested selector too, leaving any
|
|
2357
|
-
# pattern in it unguarded.
|
|
2358
|
-
config_override :in_memory_regexp_time_limit, 5.0
|
|
2359
|
-
|
|
2360
|
-
let(:person) { Person.create! }
|
|
2361
|
-
let(:reloaded) { Person.find(person._id) }
|
|
2362
|
-
|
|
2363
|
-
before do
|
|
2364
|
-
person.posts.create!(title: 'Testing')
|
|
2365
|
-
person.posts.create!(title: 'Keep')
|
|
2366
|
-
reloaded
|
|
2367
|
-
end
|
|
2368
|
-
|
|
2369
|
-
it 'leaves the nested scope free to establish its own budget' do
|
|
2370
|
-
seen = []
|
|
2371
|
-
allow(Mongoid::Factory).to receive(:from_db).and_wrap_original do |original, *args|
|
|
2372
|
-
Mongoid::Matcher::RegexpBudget.open('title' => /Testing/) do
|
|
2373
|
-
seen << Mongoid::Matcher::RegexpBudget.remaining
|
|
2374
|
-
end
|
|
2375
|
-
original.call(*args)
|
|
2376
|
-
end
|
|
2377
|
-
|
|
2378
|
-
reloaded.posts.send(method, { title: 'Testing' })
|
|
2379
|
-
|
|
2380
|
-
expect(seen).not_to be_empty
|
|
2381
|
-
expect(seen).not_to include(nil)
|
|
2382
|
-
end
|
|
2383
|
-
end
|
|
2384
|
-
|
|
2385
|
-
if method == :delete_all
|
|
2386
|
-
context 'when the association has not been loaded' do
|
|
2387
|
-
let(:person) { Person.create! }
|
|
2388
|
-
let(:reloaded) { Person.find(person._id) }
|
|
2389
|
-
let(:subscriber) { Mrss::EventSubscriber.new }
|
|
2390
|
-
|
|
2391
|
-
before do
|
|
2392
|
-
person.posts.create!(title: 'Testing')
|
|
2393
|
-
person.posts.create!(title: 'Test')
|
|
2394
|
-
reloaded
|
|
2395
|
-
end
|
|
2396
|
-
|
|
2397
|
-
def commands_for(conditions)
|
|
2398
|
-
Person.collection.client.subscribe(Mongo::Monitoring::COMMAND, subscriber)
|
|
2399
|
-
reloaded.posts.delete_all(conditions)
|
|
2400
|
-
subscriber.started_events.map(&:command_name)
|
|
2401
|
-
ensure
|
|
2402
|
-
Person.collection.client.unsubscribe(Mongo::Monitoring::COMMAND, subscriber)
|
|
2403
|
-
end
|
|
2404
|
-
|
|
2405
|
-
context 'when the conditions carry no regular expression' do
|
|
2406
|
-
# Nothing to bound, so the scan for matches stays where it was,
|
|
2407
|
-
# after the delete, where the association it loads comes back
|
|
2408
|
-
# empty. Moving it ahead of the delete would transfer the whole
|
|
2409
|
-
# association for an operation that need send nothing over the
|
|
2410
|
-
# wire.
|
|
2411
|
-
it 'deletes before loading the association' do
|
|
2412
|
-
expect(commands_for(nil)).to eq(%w[ delete find ])
|
|
2413
|
-
end
|
|
2414
|
-
end
|
|
2415
|
-
|
|
2416
|
-
context 'when the conditions carry a regular expression' do
|
|
2417
|
-
# The scan has to run under a budget, and before anything is
|
|
2418
|
-
# deleted, so that a budget which runs out leaves the database
|
|
2419
|
-
# untouched. What it scans is what is already in memory: loading
|
|
2420
|
-
# would trade the matching cost the budget exists to bound for an
|
|
2421
|
-
# unbounded amount of memory, since /.*/ is both cheap to supply
|
|
2422
|
-
# and matches every document in the association.
|
|
2423
|
-
it 'deletes without loading the association' do
|
|
2424
|
-
expect(commands_for({ title: /Test/ })).to eq(%w[ delete ])
|
|
2425
|
-
end
|
|
2426
|
-
end
|
|
2427
|
-
end
|
|
2428
|
-
end
|
|
2429
2283
|
end
|
|
2430
2284
|
|
|
2431
2285
|
context "when the association is polymorphic" do
|
|
@@ -2680,10 +2534,7 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
|
2680
2534
|
context "when the id does not match" do
|
|
2681
2535
|
|
|
2682
2536
|
context "when config set to raise error" do
|
|
2683
|
-
|
|
2684
|
-
before do
|
|
2685
|
-
Mongoid.raise_not_found_error = true
|
|
2686
|
-
end
|
|
2537
|
+
config_override :raise_not_found_error, true
|
|
2687
2538
|
|
|
2688
2539
|
it "raises an error" do
|
|
2689
2540
|
expect {
|
|
@@ -2693,19 +2544,12 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
|
2693
2544
|
end
|
|
2694
2545
|
|
|
2695
2546
|
context "when config set not to raise error" do
|
|
2547
|
+
config_override :raise_not_found_error, false
|
|
2696
2548
|
|
|
2697
2549
|
let(:post) do
|
|
2698
2550
|
person.posts.find(BSON::ObjectId.new)
|
|
2699
2551
|
end
|
|
2700
2552
|
|
|
2701
|
-
before do
|
|
2702
|
-
Mongoid.raise_not_found_error = false
|
|
2703
|
-
end
|
|
2704
|
-
|
|
2705
|
-
after do
|
|
2706
|
-
Mongoid.raise_not_found_error = true
|
|
2707
|
-
end
|
|
2708
|
-
|
|
2709
2553
|
it "returns nil" do
|
|
2710
2554
|
expect(post).to be_nil
|
|
2711
2555
|
end
|
|
@@ -2729,10 +2573,7 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
|
2729
2573
|
context "when the ids do not match" do
|
|
2730
2574
|
|
|
2731
2575
|
context "when config set to raise error" do
|
|
2732
|
-
|
|
2733
|
-
before do
|
|
2734
|
-
Mongoid.raise_not_found_error = true
|
|
2735
|
-
end
|
|
2576
|
+
config_override :raise_not_found_error, true
|
|
2736
2577
|
|
|
2737
2578
|
it "raises an error" do
|
|
2738
2579
|
expect {
|
|
@@ -2742,19 +2583,12 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
|
2742
2583
|
end
|
|
2743
2584
|
|
|
2744
2585
|
context "when config set not to raise error" do
|
|
2586
|
+
config_override :raise_not_found_error, false
|
|
2745
2587
|
|
|
2746
2588
|
let(:posts) do
|
|
2747
2589
|
person.posts.find([ BSON::ObjectId.new ])
|
|
2748
2590
|
end
|
|
2749
2591
|
|
|
2750
|
-
before do
|
|
2751
|
-
Mongoid.raise_not_found_error = false
|
|
2752
|
-
end
|
|
2753
|
-
|
|
2754
|
-
after do
|
|
2755
|
-
Mongoid.raise_not_found_error = true
|
|
2756
|
-
end
|
|
2757
|
-
|
|
2758
2592
|
it "returns an empty array" do
|
|
2759
2593
|
expect(posts).to be_empty
|
|
2760
2594
|
end
|
|
@@ -2793,10 +2627,7 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
|
2793
2627
|
context "when the id does not match" do
|
|
2794
2628
|
|
|
2795
2629
|
context "when config set to raise error" do
|
|
2796
|
-
|
|
2797
|
-
before do
|
|
2798
|
-
Mongoid.raise_not_found_error = true
|
|
2799
|
-
end
|
|
2630
|
+
config_override :raise_not_found_error, true
|
|
2800
2631
|
|
|
2801
2632
|
it "raises an error" do
|
|
2802
2633
|
expect {
|
|
@@ -2806,19 +2637,12 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
|
2806
2637
|
end
|
|
2807
2638
|
|
|
2808
2639
|
context "when config set not to raise error" do
|
|
2640
|
+
config_override :raise_not_found_error, false
|
|
2809
2641
|
|
|
2810
2642
|
let(:rating) do
|
|
2811
2643
|
movie.ratings.find(BSON::ObjectId.new)
|
|
2812
2644
|
end
|
|
2813
2645
|
|
|
2814
|
-
before do
|
|
2815
|
-
Mongoid.raise_not_found_error = false
|
|
2816
|
-
end
|
|
2817
|
-
|
|
2818
|
-
after do
|
|
2819
|
-
Mongoid.raise_not_found_error = true
|
|
2820
|
-
end
|
|
2821
|
-
|
|
2822
2646
|
it "returns nil" do
|
|
2823
2647
|
expect(rating).to be_nil
|
|
2824
2648
|
end
|
|
@@ -2850,10 +2674,7 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
|
2850
2674
|
context "when the ids do not match" do
|
|
2851
2675
|
|
|
2852
2676
|
context "when config set to raise error" do
|
|
2853
|
-
|
|
2854
|
-
before do
|
|
2855
|
-
Mongoid.raise_not_found_error = true
|
|
2856
|
-
end
|
|
2677
|
+
config_override :raise_not_found_error, true
|
|
2857
2678
|
|
|
2858
2679
|
it "raises an error" do
|
|
2859
2680
|
expect {
|
|
@@ -2863,19 +2684,12 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
|
2863
2684
|
end
|
|
2864
2685
|
|
|
2865
2686
|
context "when config set not to raise error" do
|
|
2687
|
+
config_override :raise_not_found_error, false
|
|
2866
2688
|
|
|
2867
2689
|
let(:ratings) do
|
|
2868
2690
|
movie.ratings.find([ BSON::ObjectId.new ])
|
|
2869
2691
|
end
|
|
2870
2692
|
|
|
2871
|
-
before do
|
|
2872
|
-
Mongoid.raise_not_found_error = false
|
|
2873
|
-
end
|
|
2874
|
-
|
|
2875
|
-
after do
|
|
2876
|
-
Mongoid.raise_not_found_error = true
|
|
2877
|
-
end
|
|
2878
|
-
|
|
2879
2693
|
it "returns an empty array" do
|
|
2880
2694
|
expect(ratings).to be_empty
|
|
2881
2695
|
end
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
require "spec_helper"
|
|
4
4
|
|
|
5
5
|
describe "Syncable Association" do
|
|
6
|
+
config_override :raise_not_found_error, true
|
|
6
7
|
|
|
7
8
|
before(:all) do
|
|
8
|
-
Mongoid.raise_not_found_error = true
|
|
9
9
|
Person._synced(Person.relations["preferences"])
|
|
10
10
|
Person.has_and_belongs_to_many :preferences
|
|
11
11
|
Preference.has_and_belongs_to_many :people
|