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
|
@@ -7,33 +7,6 @@ require_relative './nested_spec_models'
|
|
|
7
7
|
|
|
8
8
|
describe Mongoid::Attributes::Nested do
|
|
9
9
|
|
|
10
|
-
# Expects the enclosing context to define `build_with_id`, taking an id
|
|
11
|
-
# value and returning the document built with it in nested attributes.
|
|
12
|
-
shared_examples 'rejects non-scalar ids' do |klass_name|
|
|
13
|
-
not_found = /not found for class #{klass_name}/
|
|
14
|
-
|
|
15
|
-
context 'when the id is an operator hash' do
|
|
16
|
-
it 'raises a document not found error' do
|
|
17
|
-
expect { build_with_id({ '$ne' => nil }) }
|
|
18
|
-
.to raise_error(Mongoid::Errors::DocumentNotFound, not_found)
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
context 'when the id is an array' do
|
|
23
|
-
it 'raises a document not found error' do
|
|
24
|
-
expect { build_with_id([BSON::ObjectId.new]) }
|
|
25
|
-
.to raise_error(Mongoid::Errors::DocumentNotFound, not_found)
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
context 'when the id is a malformed object id hash' do
|
|
30
|
-
it 'raises a document not found error' do
|
|
31
|
-
expect { build_with_id({ '$oid' => 'junk' }) }
|
|
32
|
-
.to raise_error(Mongoid::Errors::DocumentNotFound, not_found)
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
10
|
describe ".accepts_nested_attributes_for" do
|
|
38
11
|
|
|
39
12
|
context "when the autosave option is not defined" do
|
|
@@ -205,30 +178,6 @@ describe Mongoid::Attributes::Nested do
|
|
|
205
178
|
end
|
|
206
179
|
end
|
|
207
180
|
|
|
208
|
-
context 'when the id in the attributes is not a scalar' do
|
|
209
|
-
let(:person) { Person.create! }
|
|
210
|
-
|
|
211
|
-
def build_with_id(id)
|
|
212
|
-
person.update!(posts_attributes: { '0' => { id: id, title: 'Crafted' } })
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
context 'when the association is empty' do
|
|
216
|
-
include_examples 'rejects non-scalar ids', 'Post'
|
|
217
|
-
end
|
|
218
|
-
|
|
219
|
-
context 'when the association is not empty' do
|
|
220
|
-
before { person.posts.create!(title: 'Existing') }
|
|
221
|
-
|
|
222
|
-
include_examples 'rejects non-scalar ids', 'Post'
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
context 'when allow_reparenting_via_nested_attributes is true' do
|
|
226
|
-
config_override :allow_reparenting_via_nested_attributes, true
|
|
227
|
-
|
|
228
|
-
include_examples 'rejects non-scalar ids', 'Post'
|
|
229
|
-
end
|
|
230
|
-
end
|
|
231
|
-
|
|
232
181
|
context "when the relation is a references and referenced in many" do
|
|
233
182
|
|
|
234
183
|
before do
|
|
@@ -252,100 +201,16 @@ describe Mongoid::Attributes::Nested do
|
|
|
252
201
|
)
|
|
253
202
|
end
|
|
254
203
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
it 'raises a document not found error' do
|
|
259
|
-
expect { person }.to raise_error(Mongoid::Errors::DocumentNotFound,
|
|
260
|
-
/Document\(s\) not found for class Preference/)
|
|
261
|
-
end
|
|
262
|
-
end
|
|
263
|
-
|
|
264
|
-
context 'when allow_reparenting_via_nested_attributes is true' do
|
|
265
|
-
config_override :allow_reparenting_via_nested_attributes, true
|
|
266
|
-
|
|
267
|
-
it 'sets the nested attributes' do
|
|
268
|
-
expect(person.preferences.map(&:name)).to eq([preference.name])
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
it 'updates attributes of existing document which is added to relation' do
|
|
272
|
-
preference_name = 'updated preference'
|
|
273
|
-
person = Person.new(
|
|
274
|
-
preferences_attributes: { 0 => { id: preference.id, name: preference_name } }
|
|
275
|
-
)
|
|
276
|
-
expect(person.preferences.map(&:name)).to eq([preference_name])
|
|
277
|
-
end
|
|
278
|
-
|
|
279
|
-
context 'when the id does not correspond to an existing document' do
|
|
280
|
-
let(:person) do
|
|
281
|
-
Person.new(
|
|
282
|
-
preferences_attributes: { 0 => { id: BSON::ObjectId.new, name: 'Ghost' } }
|
|
283
|
-
)
|
|
284
|
-
end
|
|
285
|
-
|
|
286
|
-
context 'when raise_not_found_error is true' do
|
|
287
|
-
config_override :raise_not_found_error, true
|
|
288
|
-
|
|
289
|
-
it 'raises a document not found error' do
|
|
290
|
-
expect { person }.to raise_error(Mongoid::Errors::DocumentNotFound,
|
|
291
|
-
/Document\(s\) not found for class Preference/)
|
|
292
|
-
end
|
|
293
|
-
end
|
|
294
|
-
|
|
295
|
-
context 'when raise_not_found_error is false' do
|
|
296
|
-
config_override :raise_not_found_error, false
|
|
297
|
-
|
|
298
|
-
it 'raises a document not found error' do
|
|
299
|
-
expect { person }.to raise_error(Mongoid::Errors::DocumentNotFound,
|
|
300
|
-
/Document\(s\) not found for class Preference/)
|
|
301
|
-
end
|
|
302
|
-
end
|
|
303
|
-
end
|
|
304
|
-
end
|
|
305
|
-
|
|
306
|
-
context 'when _destroy is true for a document not in the relation' do
|
|
307
|
-
before do
|
|
308
|
-
Person.send(:undef_method, :preferences_attributes=)
|
|
309
|
-
Person.accepts_nested_attributes_for :preferences, allow_destroy: true
|
|
310
|
-
end
|
|
311
|
-
|
|
312
|
-
let(:person) do
|
|
313
|
-
Person.new(
|
|
314
|
-
preferences_attributes: { 0 => { id: preference.id, _destroy: '1' } }
|
|
315
|
-
)
|
|
316
|
-
end
|
|
317
|
-
|
|
318
|
-
it 'does not raise UnknownAttribute' do
|
|
319
|
-
expect { person }.not_to raise_error
|
|
320
|
-
end
|
|
321
|
-
|
|
322
|
-
it 'does not add the document to the relation' do
|
|
323
|
-
expect(person.preferences).to be_empty
|
|
324
|
-
end
|
|
325
|
-
end
|
|
326
|
-
end
|
|
327
|
-
|
|
328
|
-
context 'when the id in the attributes is not a scalar' do
|
|
329
|
-
let(:target) { Person.create! }
|
|
330
|
-
|
|
331
|
-
def build_with_id(id)
|
|
332
|
-
target.update!(preferences_attributes: { 0 => { id: id, name: 'Crafted' } })
|
|
333
|
-
end
|
|
334
|
-
|
|
335
|
-
context 'when the association is empty' do
|
|
336
|
-
include_examples 'rejects non-scalar ids', 'Preference'
|
|
337
|
-
end
|
|
338
|
-
|
|
339
|
-
context 'when the association is not empty' do
|
|
340
|
-
before { target.preferences.create!(name: 'Existing') }
|
|
341
|
-
|
|
342
|
-
include_examples 'rejects non-scalar ids', 'Preference'
|
|
204
|
+
it "sets the nested attributes" do
|
|
205
|
+
expect(person.preferences.map(&:name)).to eq([preference.name])
|
|
343
206
|
end
|
|
344
207
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
208
|
+
it "updates attributes of existing document which is added to relation" do
|
|
209
|
+
preference_name = 'updated preference'
|
|
210
|
+
person = Person.new(
|
|
211
|
+
preferences_attributes: { 0 => { id: preference.id, name: preference_name } }
|
|
212
|
+
)
|
|
213
|
+
expect(person.preferences.map(&:name)).to eq([preference_name])
|
|
349
214
|
end
|
|
350
215
|
end
|
|
351
216
|
end
|
|
@@ -3150,7 +3015,7 @@ describe Mongoid::Attributes::Nested do
|
|
|
3150
3015
|
{ "0" =>
|
|
3151
3016
|
{ "id" => BSON::ObjectId.new.to_s, "title" => "Rogue" }
|
|
3152
3017
|
}
|
|
3153
|
-
}.to raise_error(Mongoid::Errors::DocumentNotFound, /Document not found for class Post/)
|
|
3018
|
+
}.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Post with id\(s\)/)
|
|
3154
3019
|
end
|
|
3155
3020
|
end
|
|
3156
3021
|
end
|
|
@@ -3184,7 +3049,7 @@ describe Mongoid::Attributes::Nested do
|
|
|
3184
3049
|
expect {
|
|
3185
3050
|
person.posts_attributes =
|
|
3186
3051
|
{ "foo" => { "id" => "test", "title" => "Test" } }
|
|
3187
|
-
}.to raise_error(Mongoid::Errors::DocumentNotFound, /Document not found for class Post/)
|
|
3052
|
+
}.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Post with id\(s\)/)
|
|
3188
3053
|
end
|
|
3189
3054
|
end
|
|
3190
3055
|
end
|
|
@@ -5132,63 +4997,4 @@ describe Mongoid::Attributes::Nested do
|
|
|
5132
4997
|
end
|
|
5133
4998
|
end
|
|
5134
4999
|
end
|
|
5135
|
-
|
|
5136
|
-
context 'when an id in nested attributes belongs to another parent' do
|
|
5137
|
-
let(:victim) { Person.create! }
|
|
5138
|
-
let(:attacker) { Person.create! }
|
|
5139
|
-
|
|
5140
|
-
context 'when the association is a has-many' do
|
|
5141
|
-
before do
|
|
5142
|
-
Person.send(:undef_method, :posts_attributes=)
|
|
5143
|
-
Person.accepts_nested_attributes_for :posts
|
|
5144
|
-
end
|
|
5145
|
-
|
|
5146
|
-
let!(:victim_post) { victim.posts.create!(title: 'Private') }
|
|
5147
|
-
|
|
5148
|
-
it 'does not update the other parent\'s document' do
|
|
5149
|
-
expect { attacker.update!(posts_attributes: { '0' => { id: victim_post.id, title: 'Overwritten' } }) }
|
|
5150
|
-
.to raise_error(Mongoid::Errors::DocumentNotFound)
|
|
5151
|
-
expect(victim_post.reload.title).to eq('Private')
|
|
5152
|
-
end
|
|
5153
|
-
|
|
5154
|
-
it 'does not add the other parent\'s document to the association' do
|
|
5155
|
-
expect { attacker.update!(posts_attributes: { '0' => { id: victim_post.id, title: 'Overwritten' } }) }
|
|
5156
|
-
.to raise_error(Mongoid::Errors::DocumentNotFound)
|
|
5157
|
-
expect(attacker.reload.posts).to be_empty
|
|
5158
|
-
end
|
|
5159
|
-
|
|
5160
|
-
it 'does not update via a direct association assignment' do
|
|
5161
|
-
expect { attacker.update!(posts: { '0' => { id: victim_post.id, title: 'Overwritten' } }) }
|
|
5162
|
-
.to raise_error(Mongoid::Errors::DocumentNotFound)
|
|
5163
|
-
expect(victim_post.reload.title).to eq('Private')
|
|
5164
|
-
end
|
|
5165
|
-
end
|
|
5166
|
-
|
|
5167
|
-
context 'when the association is a has-and-belongs-to-many' do
|
|
5168
|
-
before do
|
|
5169
|
-
Person.send(:undef_method, :preferences_attributes=)
|
|
5170
|
-
Person.accepts_nested_attributes_for :preferences
|
|
5171
|
-
end
|
|
5172
|
-
|
|
5173
|
-
let!(:victim_preference) { victim.preferences.create!(name: 'Private') }
|
|
5174
|
-
|
|
5175
|
-
it 'does not update the other parent\'s document' do
|
|
5176
|
-
expect { attacker.update!(preferences_attributes: { '0' => { id: victim_preference.id, name: 'Overwritten' } }) }
|
|
5177
|
-
.to raise_error(Mongoid::Errors::DocumentNotFound)
|
|
5178
|
-
expect(victim_preference.reload.name).to eq('Private')
|
|
5179
|
-
end
|
|
5180
|
-
|
|
5181
|
-
it 'does not add the other parent\'s document to the association' do
|
|
5182
|
-
expect { attacker.update!(preferences_attributes: { '0' => { id: victim_preference.id, name: 'Overwritten' } }) }
|
|
5183
|
-
.to raise_error(Mongoid::Errors::DocumentNotFound)
|
|
5184
|
-
expect(attacker.reload.preferences).to be_empty
|
|
5185
|
-
end
|
|
5186
|
-
|
|
5187
|
-
it 'does not update via a direct association assignment' do
|
|
5188
|
-
expect { attacker.update!(preferences: { '0' => { id: victim_preference.id, name: 'Overwritten' } }) }
|
|
5189
|
-
.to raise_error(Mongoid::Errors::DocumentNotFound)
|
|
5190
|
-
expect(victim_preference.reload.name).to eq('Private')
|
|
5191
|
-
end
|
|
5192
|
-
end
|
|
5193
|
-
end
|
|
5194
5000
|
end
|
|
@@ -393,11 +393,10 @@ describe Mongoid::Attributes do
|
|
|
393
393
|
end
|
|
394
394
|
|
|
395
395
|
context "when reloaded" do
|
|
396
|
+
config_override :raise_not_found_error, false
|
|
396
397
|
|
|
397
398
|
before do
|
|
398
|
-
Mongoid.raise_not_found_error = false
|
|
399
399
|
person.reload
|
|
400
|
-
Mongoid.raise_not_found_error = true
|
|
401
400
|
end
|
|
402
401
|
|
|
403
402
|
it "returns the default value" do
|
|
@@ -1030,14 +1029,13 @@ describe Mongoid::Attributes do
|
|
|
1030
1029
|
end
|
|
1031
1030
|
|
|
1032
1031
|
context "when the attribute does not exist" do
|
|
1032
|
+
config_override :raise_not_found_error, false
|
|
1033
1033
|
|
|
1034
1034
|
before do
|
|
1035
1035
|
person.collection
|
|
1036
1036
|
.find({ _id: person.id })
|
|
1037
1037
|
.update_one({ "$unset" => { age: 1 }})
|
|
1038
|
-
Mongoid.raise_not_found_error = false
|
|
1039
1038
|
person.reload
|
|
1040
|
-
Mongoid.raise_not_found_error = true
|
|
1041
1039
|
end
|
|
1042
1040
|
|
|
1043
1041
|
it "returns the default value" do
|
|
@@ -1161,14 +1159,13 @@ describe Mongoid::Attributes do
|
|
|
1161
1159
|
end
|
|
1162
1160
|
|
|
1163
1161
|
context "when the attribute does not exist" do
|
|
1162
|
+
config_override :raise_not_found_error, false
|
|
1164
1163
|
|
|
1165
1164
|
before do
|
|
1166
1165
|
person.collection
|
|
1167
1166
|
.find({ _id: person.id })
|
|
1168
1167
|
.update_one({ "$unset" => { age: 1 }})
|
|
1169
|
-
Mongoid.raise_not_found_error = false
|
|
1170
1168
|
person.reload
|
|
1171
|
-
Mongoid.raise_not_found_error = true
|
|
1172
1169
|
end
|
|
1173
1170
|
|
|
1174
1171
|
it "returns true" do
|
|
@@ -2711,31 +2708,4 @@ describe Mongoid::Attributes do
|
|
|
2711
2708
|
catalog.set_field.should == Set.new([ 1, 2 ])
|
|
2712
2709
|
end
|
|
2713
2710
|
end
|
|
2714
|
-
|
|
2715
|
-
context 'when an embedded field has a capitalized store_as name' do
|
|
2716
|
-
let(:person) { Person.new(Purse: { brand: 'Gucci' }) }
|
|
2717
|
-
|
|
2718
|
-
it 'sets the value' do
|
|
2719
|
-
expect(person.purse.brand).to eq('Gucci')
|
|
2720
|
-
end
|
|
2721
|
-
|
|
2722
|
-
it 'saves successfully' do
|
|
2723
|
-
expect(person.save!).to eq(true)
|
|
2724
|
-
end
|
|
2725
|
-
|
|
2726
|
-
context 'when persisted' do
|
|
2727
|
-
before do
|
|
2728
|
-
person.save!
|
|
2729
|
-
person.reload
|
|
2730
|
-
end
|
|
2731
|
-
|
|
2732
|
-
it 'persists the value' do
|
|
2733
|
-
expect(person.reload.purse.brand).to eq('Gucci')
|
|
2734
|
-
end
|
|
2735
|
-
|
|
2736
|
-
it 'uses the correct key in the database' do
|
|
2737
|
-
expect(person.collection.find(_id: person.id).first['Purse']['_id']).to eq(person.purse.id)
|
|
2738
|
-
end
|
|
2739
|
-
end
|
|
2740
|
-
end
|
|
2741
2711
|
end
|
|
@@ -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
|