mongoid 8.0.9 → 8.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 +2 -2
- 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 -2
- 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 +5 -27
- 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/book.rb +1 -0
- data/spec/support/models/building.rb +2 -0
- data/spec/support/models/cover.rb +10 -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 +746 -636
- 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
@@ -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
|