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
|
@@ -53,26 +53,12 @@ module Mongoid
|
|
|
53
53
|
# @example Convert the id.
|
|
54
54
|
# builder.convert_id(Person, "4d371b444835d98b8b000010")
|
|
55
55
|
#
|
|
56
|
-
# Ids arriving from a form are always scalars. A Hash or an Array
|
|
57
|
-
# here means the parameters were crafted, and letting one through
|
|
58
|
-
# would turn the id into a query operator, so they are rejected.
|
|
59
|
-
#
|
|
60
56
|
# @param [ Class ] klass The class we're trying to convert for.
|
|
61
57
|
# @param [ String ] id The id, usually coming from the form.
|
|
62
58
|
#
|
|
63
59
|
# @return [ BSON::ObjectId | String | Object ] The converted id.
|
|
64
|
-
#
|
|
65
|
-
# @raise [ Errors::DocumentNotFound ] if the id is not a scalar, or
|
|
66
|
-
# cannot be converted to the type the class uses for its ids.
|
|
67
|
-
# The BSON::Error rescue is defensive: a value that reaches
|
|
68
|
-
# BSON::ObjectId.mongoize and raises there must not surface as an
|
|
69
|
-
# unhandled BSON error in the caller.
|
|
70
60
|
def convert_id(klass, id)
|
|
71
|
-
raise Errors::DocumentNotFound.new(klass, id) if id.is_a?(::Hash) || id.is_a?(::Array)
|
|
72
|
-
|
|
73
61
|
klass.using_object_ids? ? BSON::ObjectId.mongoize(id) : id
|
|
74
|
-
rescue BSON::Error
|
|
75
|
-
raise Errors::DocumentNotFound.new(klass, id)
|
|
76
62
|
end
|
|
77
63
|
end
|
|
78
64
|
end
|
|
@@ -32,6 +32,8 @@ module Mongoid
|
|
|
32
32
|
parent.send(association.setter, Factory.build(@class_name, attributes))
|
|
33
33
|
elsif delete?
|
|
34
34
|
parent.send(association.setter, nil)
|
|
35
|
+
else
|
|
36
|
+
check_for_id_violation!
|
|
35
37
|
end
|
|
36
38
|
end
|
|
37
39
|
|
|
@@ -54,6 +56,17 @@ module Mongoid
|
|
|
54
56
|
|
|
55
57
|
private
|
|
56
58
|
|
|
59
|
+
# Extracts and converts the id to the expected type.
|
|
60
|
+
#
|
|
61
|
+
# @return [ BSON::ObjectId | String | Object | nil ] The converted id,
|
|
62
|
+
# or nil if no id is present in the attributes hash.
|
|
63
|
+
def extracted_id
|
|
64
|
+
@extracted_id ||= begin
|
|
65
|
+
id = association.klass.extract_id_field(attributes)
|
|
66
|
+
convert_id(existing.class, id)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
57
70
|
# Is the id in the attributes acceptable for allowing an update to
|
|
58
71
|
# the existing association?
|
|
59
72
|
#
|
|
@@ -64,8 +77,7 @@ module Mongoid
|
|
|
64
77
|
#
|
|
65
78
|
# @return [ true | false ] If the id part of the logic will allow an update.
|
|
66
79
|
def acceptable_id?
|
|
67
|
-
id =
|
|
68
|
-
id = convert_id(existing.class, id)
|
|
80
|
+
id = extracted_id
|
|
69
81
|
existing._id == id || id.nil? || (existing._id != id && update_only?)
|
|
70
82
|
end
|
|
71
83
|
|
|
@@ -110,6 +122,32 @@ module Mongoid
|
|
|
110
122
|
def update?
|
|
111
123
|
existing && !destroyable? && acceptable_id?
|
|
112
124
|
end
|
|
125
|
+
|
|
126
|
+
# Checks to see if the _id attribute (which is supposed to be
|
|
127
|
+
# immutable) is being asked to change. If so, raise an exception.
|
|
128
|
+
#
|
|
129
|
+
# If Mongoid::Config.immutable_ids is false, this will do nothing,
|
|
130
|
+
# and the update operation will fail silently.
|
|
131
|
+
#
|
|
132
|
+
# @raise [ Errors::ImmutableAttribute ] if _id has changed, and
|
|
133
|
+
# the document has been persisted.
|
|
134
|
+
def check_for_id_violation!
|
|
135
|
+
# look for the basic criteria of an update (see #update?)
|
|
136
|
+
return unless existing&.persisted? && !destroyable?
|
|
137
|
+
|
|
138
|
+
# if the id is either absent, or if it equals the existing record's
|
|
139
|
+
# id, there is no immutability violation.
|
|
140
|
+
id = extracted_id
|
|
141
|
+
return if existing._id == id || id.nil?
|
|
142
|
+
|
|
143
|
+
# otherwise, an attempt has been made to set the _id of an existing,
|
|
144
|
+
# persisted document.
|
|
145
|
+
if Mongoid::Config.immutable_ids
|
|
146
|
+
raise Errors::ImmutableAttribute.new(:_id, id)
|
|
147
|
+
else
|
|
148
|
+
Mongoid::Warnings.warn_mutable_ids
|
|
149
|
+
end
|
|
150
|
+
end
|
|
113
151
|
end
|
|
114
152
|
end
|
|
115
153
|
end
|
|
@@ -118,7 +118,7 @@ module Mongoid
|
|
|
118
118
|
# to the target of the proxy. This can be overridden in special cases.
|
|
119
119
|
#
|
|
120
120
|
# @param [ String | Symbol ] name The name of the method.
|
|
121
|
-
# @param [
|
|
121
|
+
# @param [ Object... ] *args The arguments passed to the method.
|
|
122
122
|
ruby2_keywords def method_missing(name, *args, &block)
|
|
123
123
|
_target.send(name, *args, &block)
|
|
124
124
|
end
|
|
@@ -13,7 +13,7 @@ module Mongoid
|
|
|
13
13
|
# @example Reset the given counter cache
|
|
14
14
|
# post.reset_counters(:comments)
|
|
15
15
|
#
|
|
16
|
-
# @param [ Symbol
|
|
16
|
+
# @param [ Symbol... ] *counters One or more counter caches to reset.
|
|
17
17
|
def reset_counters(*counters)
|
|
18
18
|
self.class.with(persistence_context) do |_class|
|
|
19
19
|
_class.reset_counters(self, *counters)
|
|
@@ -30,7 +30,7 @@ module Mongoid
|
|
|
30
30
|
# Post.reset_counters('50e0edd97c71c17ea9000001', :comments)
|
|
31
31
|
#
|
|
32
32
|
# @param [ String ] id The id of the object that will be reset.
|
|
33
|
-
# @param [ Symbol
|
|
33
|
+
# @param [ Symbol... ] *counters One or more counter caches to reset.
|
|
34
34
|
def reset_counters(id, *counters)
|
|
35
35
|
document = id.is_a?(Document) ? id : find(id)
|
|
36
36
|
counters.each do |name|
|
|
@@ -21,7 +21,7 @@ module Mongoid
|
|
|
21
21
|
# @example Concat with other documents.
|
|
22
22
|
# person.posts.concat([ post_one, post_two ])
|
|
23
23
|
#
|
|
24
|
-
# @param [ Document
|
|
24
|
+
# @param [ Document... ] *args Any number of documents.
|
|
25
25
|
#
|
|
26
26
|
# @return [ Array<Document> ] The loaded docs.
|
|
27
27
|
def <<(*args)
|
|
@@ -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.
|
|
@@ -477,111 +477,12 @@ module Mongoid
|
|
|
477
477
|
# @return [ Integer ] The number of documents deleted.
|
|
478
478
|
def remove_all(conditions = nil, method = :delete_all)
|
|
479
479
|
selector = conditions || {}
|
|
480
|
-
selector.merge!(criteria.selector)
|
|
481
|
-
|
|
482
|
-
# Scanning before the delete means scanning only what is already in
|
|
483
|
-
# memory, so it is only done where there is a pattern whose cost has
|
|
484
|
-
# to be bounded. Everywhere else the delete comes first and the scan
|
|
485
|
-
# sees the survivors, which is what this association has always
|
|
486
|
-
# done.
|
|
487
|
-
#
|
|
488
|
-
# The limit is read once and carried into whichever branch is taken.
|
|
489
|
-
# Letting the branch below ask again would read it a second time,
|
|
490
|
-
# across a server round trip, and a limit that had become positive
|
|
491
|
-
# in the meantime would put a deadline on the delete_if -- a query,
|
|
492
|
-
# and an unbind of every match -- which is the arrangement this
|
|
493
|
-
# branch exists to avoid.
|
|
494
|
-
limit = Matcher::RegexpBudget.limit_for(selector)
|
|
495
|
-
return remove_all_bounded(selector, method, limit) if limit
|
|
496
|
-
|
|
497
|
-
removed = klass.send(method, selector)
|
|
498
|
-
|
|
499
|
-
# No scope around this. The scan runs after the delete, so the
|
|
500
|
-
# association this loads comes back holding only what the delete did
|
|
501
|
-
# not match, and there is no pattern here to bound in any case.
|
|
502
|
-
# Opening a scope would save _matches? from deciding once per
|
|
503
|
-
# document -- 0.48us against 1.74us for the match itself -- but a
|
|
504
|
-
# scope with nothing to bound suppresses that decision for
|
|
505
|
-
# everything nested inside it, and loading the association runs
|
|
506
|
-
# find callbacks. A pattern in a selector one of those evaluates
|
|
507
|
-
# would go unguarded, which costs more than the saving is worth on a
|
|
508
|
-
# path that has just made two round trips.
|
|
480
|
+
removed = klass.send(method, selector.merge!(criteria.selector))
|
|
509
481
|
_target.delete_if do |doc|
|
|
510
482
|
doc._matches?(selector).tap do |b|
|
|
511
483
|
unbind_one(doc) if b
|
|
512
484
|
end
|
|
513
485
|
end
|
|
514
|
-
|
|
515
|
-
removed
|
|
516
|
-
end
|
|
517
|
-
|
|
518
|
-
# Deletes all related documents matching a selector that carries a
|
|
519
|
-
# regular expression, with the whole scan under one regexp budget.
|
|
520
|
-
#
|
|
521
|
-
# The scan runs before anything is deleted, so a budget that runs out
|
|
522
|
-
# leaves both the database and the association untouched rather than
|
|
523
|
-
# reporting a failure for a delete that has already happened. It also
|
|
524
|
-
# means the budget is closed by the time the association is mutated,
|
|
525
|
-
# so where the budget is enforced with Timeout there is no window for
|
|
526
|
-
# the exception to land in the middle of an unbind.
|
|
527
|
-
#
|
|
528
|
-
# @param [ Hash ] selector The selector to delete with.
|
|
529
|
-
# @param [ Symbol ] method The deletion method to call.
|
|
530
|
-
# @param [ Float ] limit The seconds the scan may spend, as read by
|
|
531
|
-
# the caller when it chose this path.
|
|
532
|
-
#
|
|
533
|
-
# @return [ Integer ] The number of documents deleted.
|
|
534
|
-
def remove_all_bounded(selector, method, limit)
|
|
535
|
-
# Only what the association already holds. Iterating it instead
|
|
536
|
-
# would load the whole association before the delete, and for a
|
|
537
|
-
# broad pattern that is every document the association has: /.*/ is
|
|
538
|
-
# both the cheapest pattern an attacker can supply and the one that
|
|
539
|
-
# matches everything, so bounding the cost of the matching would
|
|
540
|
-
# have been paid for with an unbounded amount of memory. Nothing is
|
|
541
|
-
# missed by not loading, because the server evaluates the same
|
|
542
|
-
# selector for the delete itself.
|
|
543
|
-
#
|
|
544
|
-
# It also means the scan runs no query, so no deadline of ours can
|
|
545
|
-
# land on one. Where the budget is enforced with Timeout, covering
|
|
546
|
-
# a query would report a slow network as a regexp timeout and could
|
|
547
|
-
# deliver the asynchronous exception inside the driver's socket
|
|
548
|
-
# read.
|
|
549
|
-
documents = _target.in_memory
|
|
550
|
-
|
|
551
|
-
matching = Matcher::RegexpBudget.open_with(limit) do
|
|
552
|
-
documents.select { |doc| doc._matches?(selector) }
|
|
553
|
-
end
|
|
554
|
-
|
|
555
|
-
removed = klass.send(method, selector)
|
|
556
|
-
|
|
557
|
-
# The ids are already known to be in memory, so the loaded and added
|
|
558
|
-
# documents can be dropped directly. Enumerable#delete would look
|
|
559
|
-
# each one up by id and stop at the first hash that has it, which
|
|
560
|
-
# removes the wrong instance when both hashes hold one for the same
|
|
561
|
-
# id. Enumerable#delete_if drops it from both, as this does, but
|
|
562
|
-
# only after load_all!, which is the load this scan exists to avoid.
|
|
563
|
-
#
|
|
564
|
-
# Which documents get unbound has always depended on which ones
|
|
565
|
-
# happened to be in memory, and scanning only what is in memory
|
|
566
|
-
# keeps that. It matters for has_and_belongs_to_many, whose
|
|
567
|
-
# unbind_one pulls the id out of the foreign key array on _base and
|
|
568
|
-
# marks it dirty; the scan used to run after the delete, against an
|
|
569
|
-
# association that a cold proxy had just reloaded as holding only
|
|
570
|
-
# the survivors, so nothing matched and nothing was unbound.
|
|
571
|
-
#
|
|
572
|
-
# TODO: unbinding should not depend on what was in memory. Every
|
|
573
|
-
# matched document leaves the association, so every one of them
|
|
574
|
-
# should be unbound, which would also stop _base's foreign key
|
|
575
|
-
# array from keeping ids that no longer resolve. That is a
|
|
576
|
-
# behaviour change for has_and_belongs_to_many and belongs in a
|
|
577
|
-
# ticket of its own, with a release note; it should not ride along
|
|
578
|
-
# on this one.
|
|
579
|
-
matching.each do |doc|
|
|
580
|
-
unbind_one(doc)
|
|
581
|
-
_target._loaded.delete(doc._id)
|
|
582
|
-
_target._added.delete(doc._id)
|
|
583
|
-
end
|
|
584
|
-
|
|
585
486
|
removed
|
|
586
487
|
end
|
|
587
488
|
|
|
@@ -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
|
|
|
@@ -95,10 +95,6 @@ module Mongoid
|
|
|
95
95
|
[MONGOID_WRAPPING_LIBRARY] + options[:wrapping_libraries]
|
|
96
96
|
else
|
|
97
97
|
[MONGOID_WRAPPING_LIBRARY]
|
|
98
|
-
end.tap do |wrap|
|
|
99
|
-
if defined?(::Rails) && ::Rails.respond_to?(:version)
|
|
100
|
-
wrap << { name: 'Rails', version: ::Rails.version }
|
|
101
|
-
end
|
|
102
98
|
end
|
|
103
99
|
options[:wrapping_libraries] = wrap_lib
|
|
104
100
|
end
|