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
@@ -215,13 +215,13 @@ module Mongoid
|
|
215
215
|
# completely depending on whether it is iterated to completion.
|
216
216
|
#
|
217
217
|
# This method can take a parameter and a block. The behavior with
|
218
|
-
# either the
|
218
|
+
# either the parameter or the block is delegated to the standard
|
219
219
|
# library Enumerable module.
|
220
220
|
#
|
221
221
|
# Note that when Enumerable's any? method is invoked with both
|
222
222
|
# a block and a pattern, it only uses the pattern.
|
223
223
|
#
|
224
|
-
# @param [ Object ]
|
224
|
+
# @param [ Object... ] *args The condition that documents
|
225
225
|
# must satisfy. See Enumerable documentation for details.
|
226
226
|
#
|
227
227
|
# @return [ true | false ] If the association has any documents.
|
@@ -422,28 +422,11 @@ module Mongoid
|
|
422
422
|
#
|
423
423
|
# @return [ Integer ] The size of the enumerable.
|
424
424
|
def size
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
# computing the size of the association, along with anything that has
|
429
|
-
# since been added.
|
430
|
-
if _unloaded
|
431
|
-
if _added.any?
|
432
|
-
# Note that _added may include records that _unloaded already
|
433
|
-
# matches. This is the case if the association is assigned an array
|
434
|
-
# of items and some of them were already elements of the association.
|
435
|
-
#
|
436
|
-
# we need to thus make sure _unloaded.count excludes any elements
|
437
|
-
# that already exist in _added.
|
438
|
-
|
439
|
-
count = _unloaded.not(:_id.in => _added.values.map(&:id)).count
|
440
|
-
count + _added.values.count
|
441
|
-
else
|
442
|
-
_unloaded.count
|
443
|
-
end
|
444
|
-
|
425
|
+
count = (_unloaded ? _unloaded.count : _loaded.count)
|
426
|
+
if count.zero?
|
427
|
+
count + _added.count
|
445
428
|
else
|
446
|
-
|
429
|
+
count + _added.values.count { |d| d.new_record? }
|
447
430
|
end
|
448
431
|
end
|
449
432
|
|
@@ -25,7 +25,7 @@ module Mongoid
|
|
25
25
|
# @example Concat with other documents.
|
26
26
|
# person.posts.concat([ post_one, post_two ])
|
27
27
|
#
|
28
|
-
# @param [ Document
|
28
|
+
# @param [ Document... ] *args Any number of documents.
|
29
29
|
#
|
30
30
|
# @return [ Array<Document> ] The loaded docs.
|
31
31
|
def <<(*args)
|
@@ -203,7 +203,7 @@ module Mongoid
|
|
203
203
|
# @note This will keep matching documents in memory for iteration
|
204
204
|
# later.
|
205
205
|
#
|
206
|
-
# @param [ Object | Array<Object> ] *args The ids.
|
206
|
+
# @param [ [ Object | Array<Object> ]... ] *args The ids.
|
207
207
|
# @param [ Proc ] block Optional block to pass.
|
208
208
|
#
|
209
209
|
# @return [ Document | Array<Document> | nil ] A document or matching documents.
|
@@ -418,7 +418,7 @@ module Mongoid
|
|
418
418
|
# If the method exists on the array, use the default proxy behavior.
|
419
419
|
#
|
420
420
|
# @param [ Symbol | String ] name The name of the method.
|
421
|
-
# @param [
|
421
|
+
# @param [ Object... ] *args The method args
|
422
422
|
# @param [ Proc ] block Optional block to pass.
|
423
423
|
#
|
424
424
|
# @return [ Criteria | Object ] A Criteria or return value from the target.
|
@@ -25,7 +25,7 @@ module Mongoid
|
|
25
25
|
# @example Find multiple association metadata by macro.
|
26
26
|
# person.reflect_on_all_associations(:embeds_many)
|
27
27
|
#
|
28
|
-
# @param [
|
28
|
+
# @param [ Symbol... ] *macros The association macros.
|
29
29
|
#
|
30
30
|
# @return [ Array<Association> ] The matching association metadata.
|
31
31
|
def reflect_on_all_association(*macros)
|
@@ -51,7 +51,7 @@ module Mongoid
|
|
51
51
|
# @example Find multiple association metadata by macro.
|
52
52
|
# Person.reflect_on_all_associations(:embeds_many)
|
53
53
|
#
|
54
|
-
# @param [
|
54
|
+
# @param [ Symbol... ] *macros The association macros.
|
55
55
|
#
|
56
56
|
# @return [ Array<Association> ] The matching association metadata.
|
57
57
|
def reflect_on_all_associations(*macros)
|
data/lib/mongoid/atomic.rb
CHANGED
@@ -178,15 +178,13 @@ module Mongoid
|
|
178
178
|
#
|
179
179
|
# @return [ Object ] The associated path.
|
180
180
|
def atomic_paths
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
paths.tap { @atomic_paths = paths unless new_record? }
|
181
|
+
@atomic_paths ||= begin
|
182
|
+
if _association
|
183
|
+
_association.path(self)
|
184
|
+
else
|
185
|
+
Atomic::Paths::Root.new(self)
|
186
|
+
end
|
187
|
+
end
|
190
188
|
end
|
191
189
|
|
192
190
|
# Get all the attributes that need to be pulled.
|
@@ -313,13 +311,6 @@ module Mongoid
|
|
313
311
|
|
314
312
|
private
|
315
313
|
|
316
|
-
# Clears all pending atomic updates.
|
317
|
-
def reset_atomic_updates!
|
318
|
-
Atomic::UPDATES.each do |update|
|
319
|
-
send(update).clear
|
320
|
-
end
|
321
|
-
end
|
322
|
-
|
323
314
|
# Generates the atomic updates in the correct order.
|
324
315
|
#
|
325
316
|
# @example Generate the updates.
|
@@ -115,7 +115,7 @@ module Mongoid
|
|
115
115
|
# document.method_missing(:test)
|
116
116
|
#
|
117
117
|
# @param [ String | Symbol ] name The name of the method.
|
118
|
-
# @param [
|
118
|
+
# @param [ Object... ] *args The arguments to the method.
|
119
119
|
#
|
120
120
|
# @return [ Object ] The result of the method call.
|
121
121
|
def method_missing(name, *args)
|
@@ -33,8 +33,8 @@ module Mongoid
|
|
33
33
|
# accepts_nested_attributes_for :addresses, :game, :posts
|
34
34
|
# end
|
35
35
|
#
|
36
|
-
# @param [
|
37
|
-
# by
|
36
|
+
# @param [ Symbol..., Hash ] *args A list of association names, followed
|
37
|
+
# by an optional hash of options.
|
38
38
|
#
|
39
39
|
# @option *args [ true | false ] :allow_destroy Can deletion occur?
|
40
40
|
# @option *args [ Proc | Symbol ] :reject_if Block or symbol pointing
|
@@ -43,46 +43,22 @@ module Mongoid
|
|
43
43
|
# @return [ true | false ] True if pending, false if not.
|
44
44
|
def pending_attribute?(key, value)
|
45
45
|
name = key.to_s
|
46
|
+
|
46
47
|
aliased = if aliased_associations.key?(name)
|
47
48
|
aliased_associations[name]
|
48
49
|
else
|
49
50
|
name
|
50
51
|
end
|
52
|
+
|
51
53
|
if relations.has_key?(aliased)
|
52
|
-
|
54
|
+
pending_relations[name] = value
|
53
55
|
return true
|
54
56
|
end
|
55
57
|
if nested_attributes.has_key?(aliased)
|
56
|
-
set_pending_nested(name, aliased, value)
|
57
|
-
return true
|
58
|
-
end
|
59
|
-
false
|
60
|
-
end
|
61
|
-
|
62
|
-
# Set value of the pending relation.
|
63
|
-
#
|
64
|
-
# @param [ Symbol ] name The name of the relation.
|
65
|
-
# @param [ Symbol ] aliased The aliased name of the relation.
|
66
|
-
# @param [ Object ] value The value of the relation.
|
67
|
-
def set_pending_relation(name, aliased, value)
|
68
|
-
if stored_as_associations.include?(name)
|
69
|
-
pending_relations[aliased] = value
|
70
|
-
else
|
71
|
-
pending_relations[name] = value
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
# Set value of the pending nested attribute.
|
76
|
-
#
|
77
|
-
# @param [ Symbol ] name The name of the nested attribute.
|
78
|
-
# @param [ Symbol ] aliased The aliased name of the nested attribute.
|
79
|
-
# @param [ Object ] value The value of the nested attribute.
|
80
|
-
def set_pending_nested(name, aliased, value)
|
81
|
-
if stored_as_associations.include?(name)
|
82
|
-
pending_nested[aliased] = value
|
83
|
-
else
|
84
58
|
pending_nested[name] = value
|
59
|
+
return true
|
85
60
|
end
|
61
|
+
return false
|
86
62
|
end
|
87
63
|
|
88
64
|
# Get all the pending associations that need to be set.
|
@@ -6,7 +6,7 @@ module Mongoid
|
|
6
6
|
# This module defines projection helpers.
|
7
7
|
#
|
8
8
|
# Projection rules are rather non-trivial. See
|
9
|
-
# https://
|
9
|
+
# https://www.mongodb.com/docs/manual/reference/method/db.collection.find/#find-projection
|
10
10
|
# for server documentation.
|
11
11
|
# 4.4 server (and presumably all older ones) requires that a projection
|
12
12
|
# for content fields is either exclusionary or inclusionary, i.e. one
|
@@ -61,7 +61,7 @@ module Mongoid
|
|
61
61
|
# attr_readonly :name, :genre
|
62
62
|
# end
|
63
63
|
#
|
64
|
-
# @param [
|
64
|
+
# @param [ Symbol... ] *names The names of the fields.
|
65
65
|
def attr_readonly(*names)
|
66
66
|
names.each do |name|
|
67
67
|
readonly_attributes << database_field_name(name)
|
data/lib/mongoid/attributes.rb
CHANGED
@@ -177,8 +177,14 @@ module Mongoid
|
|
177
177
|
attribute_will_change!(field_name)
|
178
178
|
end
|
179
179
|
if localized
|
180
|
-
|
181
|
-
|
180
|
+
present = fields[field_name].try(:localize_present?)
|
181
|
+
loc_key, loc_val = typed_value.first
|
182
|
+
if present && loc_val.blank?
|
183
|
+
attributes[field_name]&.delete(loc_key)
|
184
|
+
else
|
185
|
+
attributes[field_name] ||= {}
|
186
|
+
attributes[field_name].merge!(typed_value)
|
187
|
+
end
|
182
188
|
else
|
183
189
|
attributes[field_name] = typed_value
|
184
190
|
end
|
data/lib/mongoid/changeable.rb
CHANGED
@@ -68,9 +68,13 @@ module Mongoid
|
|
68
68
|
# @example Move the changes to previous.
|
69
69
|
# person.move_changes
|
70
70
|
def move_changes
|
71
|
+
@changes_before_last_save = @previous_changes
|
71
72
|
@previous_changes = changes
|
73
|
+
@attributes_before_last_save = @previous_attributes
|
72
74
|
@previous_attributes = attributes.dup
|
73
|
-
|
75
|
+
Atomic::UPDATES.each do |update|
|
76
|
+
send(update).clear
|
77
|
+
end
|
74
78
|
changed_attributes.clear
|
75
79
|
end
|
76
80
|
|
@@ -131,6 +135,72 @@ module Mongoid
|
|
131
135
|
mods
|
132
136
|
end
|
133
137
|
|
138
|
+
# Returns the original value of an attribute before the last save.
|
139
|
+
#
|
140
|
+
# This method is useful in after callbacks to get the original value of
|
141
|
+
# an attribute before the save that triggered the callbacks to run.
|
142
|
+
#
|
143
|
+
# @param [ Symbol | String ] attr The name of the attribute.
|
144
|
+
#
|
145
|
+
# @return [ Object ] Value of the attribute before the last save.
|
146
|
+
def attribute_before_last_save(attr)
|
147
|
+
attr = database_field_name(attr)
|
148
|
+
attributes_before_last_save[attr]
|
149
|
+
end
|
150
|
+
|
151
|
+
# Returns the change to an attribute during the last save.
|
152
|
+
#
|
153
|
+
# @param [ Symbol | String ] attr The name of the attribute.
|
154
|
+
#
|
155
|
+
# @return [ Array<Object> | nil ] If the attribute was changed, returns
|
156
|
+
# an array containing the original value and the saved value, otherwise nil.
|
157
|
+
def saved_change_to_attribute(attr)
|
158
|
+
attr = database_field_name(attr)
|
159
|
+
previous_changes[attr]
|
160
|
+
end
|
161
|
+
|
162
|
+
# Returns whether this attribute changed during the last save.
|
163
|
+
#
|
164
|
+
# This method is useful in after callbacks, to see the change
|
165
|
+
# in an attribute during the save that triggered the callbacks to run.
|
166
|
+
#
|
167
|
+
# @param [ String ] attr The name of the attribute.
|
168
|
+
# @param **kwargs The optional keyword arguments.
|
169
|
+
#
|
170
|
+
# @option **kwargs [ Object ] :from The object the attribute was changed from.
|
171
|
+
# @option **kwargs [ Object ] :to The object the attribute was changed to.
|
172
|
+
#
|
173
|
+
# @return [ true | false ] Whether the attribute has changed during the last save.
|
174
|
+
def saved_change_to_attribute?(attr, **kwargs)
|
175
|
+
changes = saved_change_to_attribute(attr)
|
176
|
+
return false unless changes.is_a?(Array)
|
177
|
+
if kwargs.key?(:from) && kwargs.key?(:to)
|
178
|
+
changes.first == kwargs[:from] && changes.last == kwargs[:to]
|
179
|
+
elsif kwargs.key?(:from)
|
180
|
+
changes.first == kwargs[:from]
|
181
|
+
elsif kwargs.key?(:to)
|
182
|
+
changes.last == kwargs[:to]
|
183
|
+
else
|
184
|
+
true
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# Returns whether this attribute change the next time we save.
|
189
|
+
#
|
190
|
+
# This method is useful in validations and before callbacks to determine
|
191
|
+
# if the next call to save will change a particular attribute.
|
192
|
+
#
|
193
|
+
# @param [ String ] attr The name of the attribute.
|
194
|
+
# @param **kwargs The optional keyword arguments.
|
195
|
+
#
|
196
|
+
# @option **kwargs [ Object ] :from The object the attribute was changed from.
|
197
|
+
# @option **kwargs [ Object ] :to The object the attribute was changed to.
|
198
|
+
#
|
199
|
+
# @return [ true | false ] Whether the attribute change the next time we save.
|
200
|
+
def will_save_change_to_attribute?(attr, **kwargs)
|
201
|
+
attribute_changed?(attr, **kwargs)
|
202
|
+
end
|
203
|
+
|
134
204
|
private
|
135
205
|
|
136
206
|
# Get attributes of the document before the document was saved.
|
@@ -140,6 +210,14 @@ module Mongoid
|
|
140
210
|
@previous_attributes ||= {}
|
141
211
|
end
|
142
212
|
|
213
|
+
def changes_before_last_save
|
214
|
+
@changes_before_last_save ||= {}
|
215
|
+
end
|
216
|
+
|
217
|
+
def attributes_before_last_save
|
218
|
+
@attributes_before_last_save ||= {}
|
219
|
+
end
|
220
|
+
|
143
221
|
# Get the old and new value for the provided attribute.
|
144
222
|
#
|
145
223
|
# @example Get the attribute change.
|
@@ -159,12 +237,24 @@ module Mongoid
|
|
159
237
|
# model.attribute_changed?("name")
|
160
238
|
#
|
161
239
|
# @param [ String ] attr The name of the attribute.
|
240
|
+
# @param **kwargs The optional keyword arguments.
|
241
|
+
#
|
242
|
+
# @option **kwargs [ Object ] :from The object the attribute was changed from.
|
243
|
+
# @option **kwargs [ Object ] :to The object the attribute was changed to.
|
162
244
|
#
|
163
245
|
# @return [ true | false ] Whether the attribute has changed.
|
164
|
-
def attribute_changed?(attr)
|
246
|
+
def attribute_changed?(attr, **kwargs)
|
165
247
|
attr = database_field_name(attr)
|
166
248
|
return false unless changed_attributes.key?(attr)
|
167
|
-
changed_attributes[attr]
|
249
|
+
return false if changed_attributes[attr] == attributes[attr]
|
250
|
+
if kwargs.key?(:from)
|
251
|
+
return false if changed_attributes[attr] != kwargs[:from]
|
252
|
+
end
|
253
|
+
if kwargs.key?(:to)
|
254
|
+
return false if attributes[attr] != kwargs[:to]
|
255
|
+
end
|
256
|
+
|
257
|
+
true
|
168
258
|
end
|
169
259
|
|
170
260
|
# Get whether or not the field has a different value from the default.
|
@@ -300,8 +390,11 @@ module Mongoid
|
|
300
390
|
# @param [ String ] meth The name of the accessor.
|
301
391
|
def create_dirty_change_check(name, meth)
|
302
392
|
generated_methods.module_eval do
|
303
|
-
re_define_method("#{meth}_changed?") do
|
304
|
-
attribute_changed?(name)
|
393
|
+
re_define_method("#{meth}_changed?") do |**kwargs|
|
394
|
+
attribute_changed?(name, **kwargs)
|
395
|
+
end
|
396
|
+
re_define_method("will_save_change_to_#{meth}?") do |**kwargs|
|
397
|
+
will_save_change_to_attribute?(name, **kwargs)
|
305
398
|
end
|
306
399
|
end
|
307
400
|
end
|
@@ -336,6 +429,15 @@ module Mongoid
|
|
336
429
|
re_define_method("#{meth}_previously_was") do
|
337
430
|
attribute_previously_was(name)
|
338
431
|
end
|
432
|
+
re_define_method("#{meth}_before_last_save") do
|
433
|
+
attribute_before_last_save(name)
|
434
|
+
end
|
435
|
+
re_define_method("saved_change_to_#{meth}") do
|
436
|
+
saved_change_to_attribute(name)
|
437
|
+
end
|
438
|
+
re_define_method("saved_change_to_#{meth}?") do |**kwargs|
|
439
|
+
saved_change_to_attribute?(name, **kwargs)
|
440
|
+
end
|
339
441
|
end
|
340
442
|
end
|
341
443
|
|
@@ -6,10 +6,7 @@ module Mongoid
|
|
6
6
|
extend ActiveSupport::Concern
|
7
7
|
|
8
8
|
included do
|
9
|
-
|
10
|
-
cattr_accessor :storage_options, instance_writer: false do
|
11
|
-
storage_options_defaults
|
12
|
-
end
|
9
|
+
class_attribute :storage_options, instance_writer: false, default: storage_options_defaults
|
13
10
|
end
|
14
11
|
|
15
12
|
module ClassMethods
|
@@ -49,7 +46,7 @@ module Mongoid
|
|
49
46
|
# @return [ Class ] The model class.
|
50
47
|
def store_in(options)
|
51
48
|
Validators::Storage.validate(self, options)
|
52
|
-
storage_options.merge
|
49
|
+
self.storage_options = self.storage_options.merge(options)
|
53
50
|
end
|
54
51
|
|
55
52
|
# Reset the store_in options
|
@@ -9,7 +9,7 @@ module Mongoid
|
|
9
9
|
extend self
|
10
10
|
|
11
11
|
# The valid options for storage.
|
12
|
-
VALID_OPTIONS = [ :collection, :database, :client ].freeze
|
12
|
+
VALID_OPTIONS = [ :collection, :collection_options, :database, :client ].freeze
|
13
13
|
|
14
14
|
# Validate the options provided to :store_in.
|
15
15
|
#
|
@@ -20,21 +20,9 @@ module Mongoid
|
|
20
20
|
# @param [ Hash | String | Symbol ] options The provided options.
|
21
21
|
def validate(klass, options)
|
22
22
|
valid_keys?(options) or raise Errors::InvalidStorageOptions.new(klass, options)
|
23
|
-
valid_parent?(klass) or raise Errors::InvalidStorageParent.new(klass)
|
24
23
|
end
|
25
24
|
|
26
25
|
private
|
27
|
-
# Determine if the current klass is valid to change store_in
|
28
|
-
# options
|
29
|
-
#
|
30
|
-
# @api private
|
31
|
-
#
|
32
|
-
# @param [ Class ] klass
|
33
|
-
#
|
34
|
-
# @return [ true | false ] If the class is valid.
|
35
|
-
def valid_parent?(klass)
|
36
|
-
!klass.superclass.include?(Mongoid::Document)
|
37
|
-
end
|
38
26
|
|
39
27
|
# Determine if all keys in the options hash are valid.
|
40
28
|
#
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mongoid
|
4
|
+
|
5
|
+
# Encapsulates behavior around defining collections.
|
6
|
+
module CollectionConfigurable
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
# Create the collection for the called upon Mongoid model.
|
11
|
+
#
|
12
|
+
# This method does not re-create existing collections.
|
13
|
+
#
|
14
|
+
# If the document includes `store_in` macro with `collection_options` key,
|
15
|
+
# these options are used when creating the collection.
|
16
|
+
#
|
17
|
+
# @param [ true | false ] force If true, the method will drop existing
|
18
|
+
# collections before creating new ones. If false, the method will create
|
19
|
+
# only new collection (that do not exist in the database).
|
20
|
+
#
|
21
|
+
# @raise [ Errors::CreateCollectionFailure ] If collection creation failed.
|
22
|
+
# @raise [ Errors::DropCollectionFailure ] If an attempt to drop collection failed.
|
23
|
+
def create_collection(force: false)
|
24
|
+
if collection_name.empty?
|
25
|
+
# This is most probably an anonymous class, we ignore them.
|
26
|
+
return
|
27
|
+
end
|
28
|
+
if collection_name.match(/^system\./)
|
29
|
+
# We do not do anything with system collections.
|
30
|
+
return
|
31
|
+
end
|
32
|
+
if force
|
33
|
+
collection.drop
|
34
|
+
end
|
35
|
+
if coll_options = collection.database.list_collections(filter: { name: collection_name.to_s }).first
|
36
|
+
if force
|
37
|
+
raise Errors::DropCollectionFailure.new(collection_name)
|
38
|
+
else
|
39
|
+
logger.debug(
|
40
|
+
"MONGOID: Collection '#{collection_name}' already exists " +
|
41
|
+
"in database '#{database_name}' with options '#{coll_options}'."
|
42
|
+
)
|
43
|
+
end
|
44
|
+
else
|
45
|
+
begin
|
46
|
+
collection.database[collection_name, storage_options.fetch(:collection_options, {})].create
|
47
|
+
rescue Mongo::Error::OperationFailure => e
|
48
|
+
raise Errors::CreateCollectionFailure.new(
|
49
|
+
collection_name,
|
50
|
+
storage_options[:collection_options],
|
51
|
+
e
|
52
|
+
)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/mongoid/composable.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "mongoid/changeable"
|
4
|
+
require "mongoid/collection_configurable"
|
4
5
|
require "mongoid/findable"
|
5
6
|
require "mongoid/indexable"
|
6
7
|
require "mongoid/inspectable"
|
@@ -36,6 +37,7 @@ module Mongoid
|
|
36
37
|
include Atomic
|
37
38
|
include Changeable
|
38
39
|
include Clients
|
40
|
+
include CollectionConfigurable
|
39
41
|
include Attributes
|
40
42
|
include Evolvable
|
41
43
|
include Fields
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mongoid
|
4
|
+
module Config
|
5
|
+
|
6
|
+
# Encapsulates logic for loading defaults.
|
7
|
+
module Defaults
|
8
|
+
|
9
|
+
# Load the defaults for the feature flags in the given Mongoid version.
|
10
|
+
# Note that this method will load the *new* functionality introduced in
|
11
|
+
# the given Mongoid version.
|
12
|
+
#
|
13
|
+
# @param [ String | Float ] The version number as X.y.
|
14
|
+
#
|
15
|
+
# raises [ ArgumentError ] if an invalid version is given.
|
16
|
+
def load_defaults(version)
|
17
|
+
# Note that for 7.x, since all of the feature flag defaults have been
|
18
|
+
# flipped to the new functionality, all of the settings for those
|
19
|
+
# versions are to give old functionality. Because of this, it is
|
20
|
+
# possible to recurse to later version to get all of the options to
|
21
|
+
# turn off. Note that this won't be true when adding feature flags to
|
22
|
+
# 9.x, since the default will be the old functionality until the next
|
23
|
+
# major version is released. More likely, the recursion will have to go
|
24
|
+
# in the other direction (towards earlier versions).
|
25
|
+
|
26
|
+
case version.to_s
|
27
|
+
when "7.3"
|
28
|
+
# flags introduced in 7.4 - old functionality
|
29
|
+
self.broken_aggregables = true
|
30
|
+
self.broken_alias_handling = true
|
31
|
+
self.broken_and = true
|
32
|
+
self.broken_scoping = true
|
33
|
+
self.broken_updates = true
|
34
|
+
self.compare_time_by_ms = false
|
35
|
+
self.legacy_pluck_distinct = true
|
36
|
+
self.legacy_triple_equals = true
|
37
|
+
self.object_id_as_json_oid = true
|
38
|
+
|
39
|
+
load_defaults "7.4"
|
40
|
+
when "7.4"
|
41
|
+
# flags introduced in 7.5 - old functionality
|
42
|
+
self.legacy_attributes = true
|
43
|
+
self.overwrite_chained_operators = true
|
44
|
+
|
45
|
+
load_defaults "7.5"
|
46
|
+
when "7.5"
|
47
|
+
# flags introduced in 8.0 - old functionality
|
48
|
+
self.map_big_decimal_to_decimal128 = false
|
49
|
+
when "8.0"
|
50
|
+
# All flag defaults currently reflect 8.0 behavior.
|
51
|
+
when "8.1"
|
52
|
+
# flags introduced in 8.1 - new functionality
|
53
|
+
self.legacy_readonly = false
|
54
|
+
else
|
55
|
+
raise ArgumentError, "Unknown version: #{version}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -25,8 +25,6 @@ module Mongoid
|
|
25
25
|
# @param [ Hash ] options Extras for the option.
|
26
26
|
#
|
27
27
|
# @option options [ Object ] :default The default value.
|
28
|
-
# @option options [ Proc | nil ] :on_change The callback to invoke when the
|
29
|
-
# setter is invoked.
|
30
28
|
def option(name, options = {})
|
31
29
|
defaults[name] = settings[name] = options[:default]
|
32
30
|
|
@@ -40,7 +38,6 @@ module Mongoid
|
|
40
38
|
|
41
39
|
define_method("#{name}=") do |value|
|
42
40
|
settings[name] = value
|
43
|
-
options[:on_change]&.call(value)
|
44
41
|
end
|
45
42
|
|
46
43
|
define_method("#{name}?") do
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mongoid
|
4
|
+
module Config
|
5
|
+
module Validators
|
6
|
+
|
7
|
+
# Validator for async query executor configuration.
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
module AsyncQueryExecutor
|
11
|
+
extend self
|
12
|
+
|
13
|
+
|
14
|
+
def validate(options)
|
15
|
+
if options.key?(:async_query_executor)
|
16
|
+
if options[:async_query_executor].to_sym == :immediate && !options[:global_executor_concurrency].nil?
|
17
|
+
raise Errors::InvalidGlobalExecutorConcurrency
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|