mongoid 8.0.7 → 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 +0 -25
- data/lib/config/locales/en.yml +46 -14
- data/lib/mongoid/association/accessors.rb +2 -2
- data/lib/mongoid/association/builders.rb +1 -1
- 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 +0 -7
- 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 +99 -28
- 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/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/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 +53 -24
- data/lib/mongoid/findable.rb +27 -3
- data/lib/mongoid/interceptable.rb +10 -118
- 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/utils.rb +22 -0
- data/lib/mongoid/validatable/macros.rb +5 -5
- data/lib/mongoid/validatable.rb +4 -1
- 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/callbacks_models.rb +37 -0
- data/spec/integration/callbacks_spec.rb +126 -12
- data/spec/integration/discriminator_key_spec.rb +4 -5
- data/spec/integration/i18n_fallbacks_spec.rb +3 -2
- 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_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/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/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 +173 -362
- 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 +9 -30
- 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_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/uniqueness_spec.rb +2 -3
- data/spec/mongoid_spec.rb +36 -10
- 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/person.rb +0 -1
- data/spec/support/models/product.rb +1 -0
- data.tar.gz.sig +0 -0
- metadata +685 -651
- metadata.gz.sig +0 -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
|
@@ -16,7 +16,6 @@ module Mongoid
|
|
|
16
16
|
#
|
|
17
17
|
# @return [ TrueClass ] True.
|
|
18
18
|
def delete(options = {})
|
|
19
|
-
raise Errors::ReadonlyDocument.new(self.class) if readonly?
|
|
20
19
|
prepare_delete do
|
|
21
20
|
unless options[:persist] == false
|
|
22
21
|
if embedded?
|
|
@@ -102,6 +101,7 @@ module Mongoid
|
|
|
102
101
|
#
|
|
103
102
|
# @return [ Object ] The result of the block.
|
|
104
103
|
def prepare_delete
|
|
104
|
+
raise Errors::ReadonlyDocument.new(self.class) if readonly?
|
|
105
105
|
yield(self)
|
|
106
106
|
freeze
|
|
107
107
|
self.destroyed = true
|
|
@@ -14,7 +14,13 @@ module Mongoid
|
|
|
14
14
|
#
|
|
15
15
|
# @param [ Hash ] options Options to pass to the save.
|
|
16
16
|
#
|
|
17
|
-
# @
|
|
17
|
+
# @option options [ true | false ] :touch Whether or not the updated_at
|
|
18
|
+
# attribute will be updated with the current time. When this option is
|
|
19
|
+
# false, none of the embedded documents will be touched. This option is
|
|
20
|
+
# ignored when saving a new document, and the created_at and updated_at
|
|
21
|
+
# will be set to the current time.
|
|
22
|
+
#
|
|
23
|
+
# @return [ true | false ] True if success, false if not.
|
|
18
24
|
def save(options = {})
|
|
19
25
|
if new_record?
|
|
20
26
|
!insert(options).new_record?
|
|
@@ -31,6 +37,12 @@ module Mongoid
|
|
|
31
37
|
#
|
|
32
38
|
# @param [ Hash ] options Options to pass to the save.
|
|
33
39
|
#
|
|
40
|
+
# @option options [ true | false ] :touch Whether or not the updated_at
|
|
41
|
+
# attribute will be updated with the current time. When this option is
|
|
42
|
+
# false, none of the embedded documents will be touched.This option is
|
|
43
|
+
# ignored when saving a new document, and the created_at and updated_at
|
|
44
|
+
# will be set to the current time.
|
|
45
|
+
#
|
|
34
46
|
# @raise [ Errors::Validations ] If validation failed.
|
|
35
47
|
# @raise [ Errors::Callback ] If a callback returns false.
|
|
36
48
|
#
|
|
@@ -13,8 +13,8 @@ module Mongoid
|
|
|
13
13
|
# @example Unset the values.
|
|
14
14
|
# document.unset(:first_name, :last_name, :middle)
|
|
15
15
|
#
|
|
16
|
-
# @param [ Array<String | Symbol> ] fields
|
|
17
|
-
# unset.
|
|
16
|
+
# @param [ [ String | Symbol | Array<String | Symbol>]... ] *fields
|
|
17
|
+
# The names of the field(s) to unset.
|
|
18
18
|
#
|
|
19
19
|
# @return [ Document ] The document.
|
|
20
20
|
def unset(*fields)
|
|
@@ -91,16 +91,23 @@ module Mongoid
|
|
|
91
91
|
#
|
|
92
92
|
# @param [ Hash ] options The options.
|
|
93
93
|
#
|
|
94
|
+
# @option options [ true | false ] :touch Whether or not the updated_at
|
|
95
|
+
# attribute will be updated with the current time.
|
|
96
|
+
#
|
|
94
97
|
# @return [ true | false ] The result of the update.
|
|
95
98
|
def prepare_update(options = {})
|
|
99
|
+
raise Errors::ReadonlyDocument.new(self.class) if readonly? && !Mongoid.legacy_readonly
|
|
100
|
+
enforce_immutability_of_id_field!
|
|
96
101
|
return false if performing_validations?(options) &&
|
|
97
102
|
invalid?(options[:context] || :update)
|
|
98
103
|
process_flagged_destroys
|
|
104
|
+
update_children = cascadable_children(:update)
|
|
105
|
+
process_touch_option(options, update_children)
|
|
99
106
|
run_callbacks(:save, with_children: false) do
|
|
100
107
|
run_callbacks(:update, with_children: false) do
|
|
101
108
|
run_callbacks(:persist_parent, with_children: false) do
|
|
102
109
|
_mongoid_run_child_callbacks(:save) do
|
|
103
|
-
_mongoid_run_child_callbacks(:update) do
|
|
110
|
+
_mongoid_run_child_callbacks(:update, children: update_children) do
|
|
104
111
|
result = yield(self)
|
|
105
112
|
self.previously_new_record = false
|
|
106
113
|
post_process_persist(result, options)
|
|
@@ -160,6 +167,49 @@ module Mongoid
|
|
|
160
167
|
end
|
|
161
168
|
end
|
|
162
169
|
end
|
|
170
|
+
|
|
171
|
+
# If there is a touch option and it is false, this method will call the
|
|
172
|
+
# timeless method so that the updated_at attribute is not updated. It
|
|
173
|
+
# will call the timeless method on all of the cascadable children as
|
|
174
|
+
# well. Note that timeless is cleared in the before_update callback.
|
|
175
|
+
#
|
|
176
|
+
# @param [ Hash ] options The options.
|
|
177
|
+
# @param [ Array<Document> ] children The children that the :update
|
|
178
|
+
# callbacks will be executed on.
|
|
179
|
+
#
|
|
180
|
+
# @option options [ true | false ] :touch Whether or not the updated_at
|
|
181
|
+
# attribute will be updated with the current time.
|
|
182
|
+
def process_touch_option(options, children)
|
|
183
|
+
unless options.fetch(:touch, true)
|
|
184
|
+
timeless
|
|
185
|
+
children.each(&:timeless)
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# Checks to see if the _id field has been modified. If it has, and if
|
|
190
|
+
# the document has already been persisted, this is an error. Otherwise,
|
|
191
|
+
# returns without side-effects.
|
|
192
|
+
#
|
|
193
|
+
# Note that if `Mongoid::Config.immutable_ids` is false, this will do
|
|
194
|
+
# nothing.
|
|
195
|
+
#
|
|
196
|
+
# @raise [ Errors::ImmutableAttribute ] if _id has changed, and document
|
|
197
|
+
# has been persisted.
|
|
198
|
+
def enforce_immutability_of_id_field!
|
|
199
|
+
# special case here: we *do* allow the _id to be mutated if it was
|
|
200
|
+
# previously nil. This addresses an odd case exposed in
|
|
201
|
+
# has_one/proxy_spec.rb where `person.create_address` would
|
|
202
|
+
# (somehow?) create the address with a nil _id first, before then
|
|
203
|
+
# saving it *again* with the correct _id.
|
|
204
|
+
|
|
205
|
+
if _id_changed? && !_id_was.nil? && persisted?
|
|
206
|
+
if Mongoid::Config.immutable_ids
|
|
207
|
+
raise Errors::ImmutableAttribute.new(:_id, _id)
|
|
208
|
+
else
|
|
209
|
+
Mongoid::Warnings.warn_mutable_ids
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
end
|
|
163
213
|
end
|
|
164
214
|
end
|
|
165
215
|
end
|
|
@@ -10,16 +10,32 @@ module Mongoid
|
|
|
10
10
|
# database, then Mongo will insert a new one, otherwise the fields will get
|
|
11
11
|
# overwritten with new values on the existing document.
|
|
12
12
|
#
|
|
13
|
+
# If the replace option is true, unspecified attributes will be dropped,
|
|
14
|
+
# and if it is false, unspecified attributes will be maintained. The
|
|
15
|
+
# replace option defaults to true in Mongoid 8.1 and earlier. The default
|
|
16
|
+
# will be flipped to false in Mongoid 9.
|
|
17
|
+
#
|
|
13
18
|
# @example Upsert the document.
|
|
14
19
|
# document.upsert
|
|
15
20
|
#
|
|
21
|
+
# @example Upsert the document without replace.
|
|
22
|
+
# document.upsert(replace: false)
|
|
23
|
+
#
|
|
16
24
|
# @param [ Hash ] options The validation options.
|
|
17
25
|
#
|
|
26
|
+
# @option options [ true | false ] :validate Whether or not to validate.
|
|
27
|
+
# @option options [ true | false ] :replace Whether or not to replace the document on upsert.
|
|
28
|
+
#
|
|
18
29
|
# @return [ true ] True.
|
|
19
30
|
def upsert(options = {})
|
|
20
31
|
prepare_upsert(options) do
|
|
21
|
-
|
|
32
|
+
if options.fetch(:replace, true)
|
|
33
|
+
collection.find(atomic_selector).replace_one(
|
|
22
34
|
as_attributes, upsert: true, session: _session)
|
|
35
|
+
else
|
|
36
|
+
collection.find(atomic_selector).update_one(
|
|
37
|
+
{ "$set" => as_attributes }, upsert: true, session: _session)
|
|
38
|
+
end
|
|
23
39
|
end
|
|
24
40
|
end
|
|
25
41
|
|
|
@@ -36,8 +52,11 @@ module Mongoid
|
|
|
36
52
|
#
|
|
37
53
|
# @param [ Hash ] options The options hash.
|
|
38
54
|
#
|
|
55
|
+
# @option options [ true | false ] :validate Whether or not to validate.
|
|
56
|
+
#
|
|
39
57
|
# @return [ true | false ] If the operation succeeded.
|
|
40
58
|
def prepare_upsert(options = {})
|
|
59
|
+
raise Errors::ReadonlyDocument.new(self.class) if readonly? && !Mongoid.legacy_readonly
|
|
41
60
|
return false if performing_validations?(options) && invalid?(:upsert)
|
|
42
61
|
result = run_callbacks(:upsert) do
|
|
43
62
|
yield(self)
|
data/lib/mongoid/persistable.rb
CHANGED
|
@@ -161,6 +161,8 @@ module Mongoid
|
|
|
161
161
|
# @param [ Object ] result The result of the operation.
|
|
162
162
|
# @param [ Hash ] options The options.
|
|
163
163
|
#
|
|
164
|
+
# @option options [ true | false ] :validate Whether or not to validate.
|
|
165
|
+
#
|
|
164
166
|
# @return [ true ] true.
|
|
165
167
|
def post_process_persist(result, options = {})
|
|
166
168
|
post_persist unless result == false
|
|
@@ -180,6 +182,7 @@ module Mongoid
|
|
|
180
182
|
#
|
|
181
183
|
# @return [ Object ] The result of the operation.
|
|
182
184
|
def prepare_atomic_operation
|
|
185
|
+
raise Errors::ReadonlyDocument.new(self.class) if readonly? && !Mongoid.legacy_readonly
|
|
183
186
|
operations = yield({})
|
|
184
187
|
persist_or_delay_atomic_operation(operations)
|
|
185
188
|
self
|
data/lib/mongoid/query_cache.rb
CHANGED
|
@@ -14,6 +14,7 @@ module Mongoid
|
|
|
14
14
|
#
|
|
15
15
|
# @return [ nil ] Always nil.
|
|
16
16
|
def clear_cache
|
|
17
|
+
Mongoid::Warnings.warn_mongoid_query_cache_clear
|
|
17
18
|
Mongo::QueryCache.clear
|
|
18
19
|
end
|
|
19
20
|
|
|
@@ -24,6 +25,7 @@ module Mongoid
|
|
|
24
25
|
#
|
|
25
26
|
# @param [ true | false ] value The enabled value.
|
|
26
27
|
def enabled=(value)
|
|
28
|
+
Mongoid::Warnings.warn_mongoid_query_cache
|
|
27
29
|
Mongo::QueryCache.enabled = value
|
|
28
30
|
end
|
|
29
31
|
|
|
@@ -34,6 +36,7 @@ module Mongoid
|
|
|
34
36
|
#
|
|
35
37
|
# @return [ true | false ] If the cache is enabled.
|
|
36
38
|
def enabled?
|
|
39
|
+
Mongoid::Warnings.warn_mongoid_query_cache
|
|
37
40
|
Mongo::QueryCache.enabled?
|
|
38
41
|
end
|
|
39
42
|
|
|
@@ -44,6 +47,7 @@ module Mongoid
|
|
|
44
47
|
#
|
|
45
48
|
# @return [ Object ] The result of the block.
|
|
46
49
|
def cache(&block)
|
|
50
|
+
Mongoid::Warnings.warn_mongoid_query_cache
|
|
47
51
|
Mongo::QueryCache.cache(&block)
|
|
48
52
|
end
|
|
49
53
|
|
|
@@ -54,6 +58,7 @@ module Mongoid
|
|
|
54
58
|
#
|
|
55
59
|
# @return [ Object ] The result of the block.
|
|
56
60
|
def uncached(&block)
|
|
61
|
+
Mongoid::Warnings.warn_mongoid_query_cache
|
|
57
62
|
Mongo::QueryCache.uncached(&block)
|
|
58
63
|
end
|
|
59
64
|
end
|
|
@@ -61,4 +66,3 @@ module Mongoid
|
|
|
61
66
|
Middleware = Mongo::QueryCache::Middleware
|
|
62
67
|
end
|
|
63
68
|
end
|
|
64
|
-
|
|
@@ -25,7 +25,7 @@ namespace :db do
|
|
|
25
25
|
|
|
26
26
|
unless Rake::Task.task_defined?("db:setup")
|
|
27
27
|
desc "Create the database, and initialize with the seed data"
|
|
28
|
-
task :setup => [ "db:create", "mongoid:create_indexes", "db:seed" ]
|
|
28
|
+
task :setup => [ "db:create", "mongoid:create_collections", "mongoid:create_indexes", "db:seed" ]
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
unless Rake::Task.task_defined?("db:reset")
|
|
@@ -55,10 +55,15 @@ namespace :db do
|
|
|
55
55
|
|
|
56
56
|
unless Rake::Task.task_defined?("db:test:prepare")
|
|
57
57
|
namespace :test do
|
|
58
|
-
task :prepare => "mongoid:create_indexes"
|
|
58
|
+
task :prepare => ["mongoid:create_collections", "mongoid:create_indexes"]
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
+
unless Rake::Task.task_defined?("db:create_collections")
|
|
63
|
+
desc "Create collections specified in Mongoid models"
|
|
64
|
+
task :create_collections => "mongoid:create_collections"
|
|
65
|
+
end
|
|
66
|
+
|
|
62
67
|
unless Rake::Task.task_defined?("db:create_indexes")
|
|
63
68
|
desc "Create indexes specified in Mongoid models"
|
|
64
69
|
task :create_indexes => "mongoid:create_indexes"
|
data/lib/mongoid/reloadable.rb
CHANGED
|
@@ -16,14 +16,16 @@ module Mongoid
|
|
|
16
16
|
#
|
|
17
17
|
# @return [ Document ] The document, reloaded.
|
|
18
18
|
def reload
|
|
19
|
+
if @atomic_selector
|
|
20
|
+
# Clear atomic_selector cache for sharded clusters. MONGOID-5076
|
|
21
|
+
remove_instance_variable('@atomic_selector')
|
|
22
|
+
end
|
|
23
|
+
|
|
19
24
|
reloaded = _reload
|
|
20
25
|
if Mongoid.raise_not_found_error && (reloaded.nil? || reloaded.empty?)
|
|
21
26
|
shard_keys = atomic_selector.with_indifferent_access.slice(*shard_key_fields, :_id)
|
|
22
27
|
raise Errors::DocumentNotFound.new(self.class, _id, shard_keys)
|
|
23
28
|
end
|
|
24
|
-
|
|
25
|
-
reset_atomic_updates!
|
|
26
|
-
|
|
27
29
|
@attributes = reloaded
|
|
28
30
|
@attributes_before_type_cast = @attributes.dup
|
|
29
31
|
@changed_attributes = {}
|
data/lib/mongoid/stateful.rb
CHANGED
|
@@ -95,6 +95,23 @@ module Mongoid
|
|
|
95
95
|
!_parent.delayed_atomic_sets[atomic_path]
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
+
# Flags the document as readonly. Will cause a ReadonlyDocument error to be
|
|
99
|
+
# raised if the document is attempted to be saved, updated or destroyed.
|
|
100
|
+
#
|
|
101
|
+
# @example Flag the document as readonly.
|
|
102
|
+
# document.readonly!
|
|
103
|
+
#
|
|
104
|
+
# @return [ true | false ] true if the document was successfully marked
|
|
105
|
+
# readonly, false otherwise.
|
|
106
|
+
def readonly!
|
|
107
|
+
if Mongoid.legacy_readonly
|
|
108
|
+
Mongoid::Warnings.warn_legacy_readonly
|
|
109
|
+
false
|
|
110
|
+
else
|
|
111
|
+
@readonly = true
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
98
115
|
# Is the document readonly?
|
|
99
116
|
#
|
|
100
117
|
# @example Is the document readonly?
|
|
@@ -102,7 +119,11 @@ module Mongoid
|
|
|
102
119
|
#
|
|
103
120
|
# @return [ true | false ] If the document is readonly.
|
|
104
121
|
def readonly?
|
|
105
|
-
|
|
122
|
+
if Mongoid.legacy_readonly
|
|
123
|
+
__selected_fields != nil
|
|
124
|
+
else
|
|
125
|
+
@readonly ||= false
|
|
126
|
+
end
|
|
106
127
|
end
|
|
107
128
|
|
|
108
129
|
# Determine if the document can be set.
|
|
@@ -5,6 +5,11 @@ namespace :db do
|
|
|
5
5
|
task :load_models do
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
+
desc "Create collections for Mongoid models"
|
|
9
|
+
task :create_collections => [:environment, :load_models] do
|
|
10
|
+
::Mongoid::Tasks::Database.create_collections
|
|
11
|
+
end
|
|
12
|
+
|
|
8
13
|
desc "Create indexes specified in Mongoid models"
|
|
9
14
|
task :create_indexes => [:environment, :load_models] do
|
|
10
15
|
::Mongoid::Tasks::Database.create_indexes
|
|
@@ -34,5 +39,12 @@ namespace :db do
|
|
|
34
39
|
task :purge => :environment do
|
|
35
40
|
::Mongoid.purge!
|
|
36
41
|
end
|
|
42
|
+
|
|
43
|
+
namespace :create_collections do
|
|
44
|
+
desc "Drop and create collections for Mongoid models"
|
|
45
|
+
task :force => [:environment, :load_models] do
|
|
46
|
+
::Mongoid::Tasks::Database.create_collections(force: true)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
37
49
|
end
|
|
38
50
|
end
|
|
@@ -5,6 +5,26 @@ module Mongoid
|
|
|
5
5
|
module Database
|
|
6
6
|
extend self
|
|
7
7
|
|
|
8
|
+
# Create collections for each model given the provided globs and the class is
|
|
9
|
+
# not embedded.
|
|
10
|
+
#
|
|
11
|
+
# @param [ Array<Mongoid::Document> ] models. Array of document classes for
|
|
12
|
+
# which collections should be created. Defaulted to all document classes
|
|
13
|
+
# in the application.
|
|
14
|
+
# @param [ true | false ] force If true, the method will drop existing
|
|
15
|
+
# collections before creating new ones. If false, the method will create
|
|
16
|
+
# only new collection (that do not exist in the database).
|
|
17
|
+
def create_collections(models = ::Mongoid.models, force: false)
|
|
18
|
+
models.each do |model|
|
|
19
|
+
if !model.embedded? || model.cyclic?
|
|
20
|
+
model.create_collection(force: force)
|
|
21
|
+
logger.info("MONGOID: Created collection for #{model}:")
|
|
22
|
+
else
|
|
23
|
+
logger.info("MONGOID: collection options ignored on: #{model}, please define in the root model.")
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
8
28
|
# Create indexes for each model given the provided globs and the class is
|
|
9
29
|
# not embedded.
|
|
10
30
|
#
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mongoid
|
|
4
|
+
|
|
5
|
+
# @api private
|
|
6
|
+
module Utils
|
|
7
|
+
|
|
8
|
+
# This function should be used if you need to measure time.
|
|
9
|
+
# @example Calculate elapsed time.
|
|
10
|
+
# starting = Utils.monotonic_time
|
|
11
|
+
# # do something time consuming
|
|
12
|
+
# ending = Utils.monotonic_time
|
|
13
|
+
# puts "It took #{(ending - starting).to_i} seconds"
|
|
14
|
+
#
|
|
15
|
+
# @see https://blog.dnsimple.com/2018/03/elapsed-time-with-ruby-the-right-way/
|
|
16
|
+
#
|
|
17
|
+
# @return [Float] seconds according to monotonic clock
|
|
18
|
+
module_function def monotonic_time
|
|
19
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -18,7 +18,7 @@ module Mongoid
|
|
|
18
18
|
# validates_associated :name, :addresses
|
|
19
19
|
# end
|
|
20
20
|
#
|
|
21
|
-
# @param [
|
|
21
|
+
# @param [ Object... ] *args The arguments to pass to the validator.
|
|
22
22
|
def validates_associated(*args)
|
|
23
23
|
validates_with(AssociatedValidator, _merge_attributes(args))
|
|
24
24
|
end
|
|
@@ -35,7 +35,7 @@ module Mongoid
|
|
|
35
35
|
# validates_uniqueness_of :title
|
|
36
36
|
# end
|
|
37
37
|
#
|
|
38
|
-
# @param [
|
|
38
|
+
# @param [ Object... ] *args The arguments to pass to the validator.
|
|
39
39
|
def validates_uniqueness_of(*args)
|
|
40
40
|
validates_with(UniquenessValidator, _merge_attributes(args))
|
|
41
41
|
end
|
|
@@ -50,7 +50,7 @@ module Mongoid
|
|
|
50
50
|
# validates_format_of :title, with: /\A[a-z0-9 \-_]*\z/i
|
|
51
51
|
# end
|
|
52
52
|
#
|
|
53
|
-
# @param [
|
|
53
|
+
# @param [ Object... ] *args The names of the field(s) to validate.
|
|
54
54
|
def validates_format_of(*args)
|
|
55
55
|
validates_with(FormatValidator, _merge_attributes(args))
|
|
56
56
|
end
|
|
@@ -65,7 +65,7 @@ module Mongoid
|
|
|
65
65
|
# validates_length_of :title, minimum: 100
|
|
66
66
|
# end
|
|
67
67
|
#
|
|
68
|
-
# @param [
|
|
68
|
+
# @param [ Object... ] *args The names of the field(s) to validate.
|
|
69
69
|
def validates_length_of(*args)
|
|
70
70
|
validates_with(LengthValidator, _merge_attributes(args))
|
|
71
71
|
end
|
|
@@ -80,7 +80,7 @@ module Mongoid
|
|
|
80
80
|
# validates_presence_of :title
|
|
81
81
|
# end
|
|
82
82
|
#
|
|
83
|
-
# @param [
|
|
83
|
+
# @param [ Object... ] *args The names of the field(s) to validate.
|
|
84
84
|
def validates_presence_of(*args)
|
|
85
85
|
validates_with(PresenceValidator, _merge_attributes(args))
|
|
86
86
|
end
|
data/lib/mongoid/validatable.rb
CHANGED
|
@@ -44,6 +44,8 @@ module Mongoid
|
|
|
44
44
|
#
|
|
45
45
|
# @param [ Hash ] options The options to check.
|
|
46
46
|
#
|
|
47
|
+
# @option options [ true | false ] :validate Whether or not to validate.
|
|
48
|
+
#
|
|
47
49
|
# @return [ true | false ] If we are validating.
|
|
48
50
|
def performing_validations?(options = {})
|
|
49
51
|
options[:validate].nil? ? true : options[:validate]
|
|
@@ -129,7 +131,8 @@ module Mongoid
|
|
|
129
131
|
# @example Validate with a specific validator.
|
|
130
132
|
# validates_with MyValidator, on: :create
|
|
131
133
|
#
|
|
132
|
-
# @param [
|
|
134
|
+
# @param [ ActiveModel::Validator..., Hash ] *args The validator classes
|
|
135
|
+
# and options hash.
|
|
133
136
|
#
|
|
134
137
|
# @note See ActiveModel::Validations::With for full options. This is
|
|
135
138
|
# overridden to add autosave functionality when presence validation is
|
data/lib/mongoid/version.rb
CHANGED
data/lib/mongoid/warnings.rb
CHANGED
|
@@ -23,6 +23,22 @@ module Mongoid
|
|
|
23
23
|
|
|
24
24
|
warning :geo_haystack_deprecated, 'The geoHaystack type is deprecated.'
|
|
25
25
|
warning :as_json_compact_deprecated, '#as_json :compact option is deprecated. Please call #compact on the returned Hash object instead.'
|
|
26
|
-
warning :symbol_type_deprecated, 'The BSON Symbol type is deprecated by MongoDB. Please use String or StringifiedSymbol field types instead of the Symbol field type'
|
|
26
|
+
warning :symbol_type_deprecated, 'The BSON Symbol type is deprecated by MongoDB. Please use String or StringifiedSymbol field types instead of the Symbol field type.'
|
|
27
|
+
warning :legacy_readonly, 'The readonly! method will only mark the document readonly when the legacy_readonly feature flag is switched off.'
|
|
28
|
+
warning :use_activesupport_time_zone_deprecated, 'Config option :use_activesupport_time_zone is deprecated and should be removed from your config. It will always be true beginning in Mongoid 9.0.'
|
|
29
|
+
warning :broken_aggregables_deprecated, 'Config option :broken_aggregables is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
|
|
30
|
+
warning :broken_alias_handling_deprecated, 'Config option :broken_alias_handling is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
|
|
31
|
+
warning :broken_and_deprecated, 'Config option :broken_and is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
|
|
32
|
+
warning :broken_scoping_deprecated, 'Config option :broken_scoping is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
|
|
33
|
+
warning :broken_updates_deprecated, 'Config option :broken_updates is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
|
|
34
|
+
warning :compare_time_by_ms_deprecated, 'Config option :compare_time_by_ms is deprecated. It will always be true beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
|
|
35
|
+
warning :legacy_attributes_deprecated, 'Config option :legacy_attributes is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
|
|
36
|
+
warning :legacy_pluck_distinct_deprecated, 'Config option :legacy_pluck_distinct is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
|
|
37
|
+
warning :legacy_triple_equals_deprecated, 'Config option :legacy_triple_equals is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
|
|
38
|
+
warning :object_id_as_json_oid_deprecated, 'Config option :object_id_as_json_oid is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
|
|
39
|
+
warning :overwrite_chained_operators_deprecated, 'Config option :overwrite_chained_operators is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
|
|
40
|
+
warning :mutable_ids, 'In Mongoid 9.0 the _id field will be immutable. In earlier versions of 8.x, mutating the _id field was supported inconsistently. Prepare your code for 9.0 by setting Mongoid::Config.immutable_ids to true.'
|
|
41
|
+
warning :mongoid_query_cache, 'In Mongoid 9.0, Mongoid::QueryCache will be removed. Please replace it with Mongo::QueryCache.'
|
|
42
|
+
warning :mongoid_query_cache_clear, 'In Mongoid 9.0, Mongoid::QueryCache#clear_cache should be replaced it with Mongo::QueryCache#clear.'
|
|
27
43
|
end
|
|
28
44
|
end
|
data/lib/mongoid.rb
CHANGED
|
@@ -12,8 +12,10 @@ require "active_support/inflector"
|
|
|
12
12
|
require "active_support/time_with_zone"
|
|
13
13
|
require "active_model"
|
|
14
14
|
|
|
15
|
+
require 'concurrent-ruby'
|
|
16
|
+
|
|
15
17
|
require "mongo"
|
|
16
|
-
require
|
|
18
|
+
require "mongo/active_support"
|
|
17
19
|
|
|
18
20
|
require "mongoid/version"
|
|
19
21
|
require "mongoid/deprecable"
|
|
@@ -25,6 +27,7 @@ require "mongoid/document"
|
|
|
25
27
|
require "mongoid/tasks/database"
|
|
26
28
|
require "mongoid/query_cache"
|
|
27
29
|
require "mongoid/warnings"
|
|
30
|
+
require "mongoid/utils"
|
|
28
31
|
|
|
29
32
|
# If we are using Rails then we will include the Mongoid railtie. This has all
|
|
30
33
|
# the nifty initializers that Mongoid needs.
|
|
@@ -58,9 +61,19 @@ module Mongoid
|
|
|
58
61
|
# }
|
|
59
62
|
# end
|
|
60
63
|
#
|
|
64
|
+
# @example Using a block without an argument. Use `config` inside
|
|
65
|
+
# the block to perform variable assignment.
|
|
66
|
+
#
|
|
67
|
+
# Mongoid.configure do
|
|
68
|
+
# connect_to("mongoid_test")
|
|
69
|
+
#
|
|
70
|
+
# config.preload_models = true
|
|
71
|
+
#
|
|
61
72
|
# @return [ Config ] The configuration object.
|
|
62
|
-
def configure
|
|
63
|
-
|
|
73
|
+
def configure(&block)
|
|
74
|
+
return Config unless block_given?
|
|
75
|
+
|
|
76
|
+
block.arity == 0 ? Config.instance_exec(&block) : yield(Config)
|
|
64
77
|
end
|
|
65
78
|
|
|
66
79
|
# Convenience method for getting the default client.
|
|
@@ -326,7 +326,7 @@ describe 'Mongoid application tests' do
|
|
|
326
326
|
end
|
|
327
327
|
|
|
328
328
|
def wait_for_port(port, timeout, process)
|
|
329
|
-
deadline =
|
|
329
|
+
deadline = Mongoid::Utils.monotonic_time + timeout
|
|
330
330
|
loop do
|
|
331
331
|
begin
|
|
332
332
|
Socket.tcp('localhost', port, nil, nil, connect_timeout: 0.5) do |socket|
|
|
@@ -336,7 +336,7 @@ describe 'Mongoid application tests' do
|
|
|
336
336
|
unless process.alive?
|
|
337
337
|
raise "Process #{process} died while waiting for port #{port}"
|
|
338
338
|
end
|
|
339
|
-
if
|
|
339
|
+
if Mongoid::Utils.monotonic_time > deadline
|
|
340
340
|
raise
|
|
341
341
|
end
|
|
342
342
|
end
|
|
@@ -153,3 +153,40 @@ class Building
|
|
|
153
153
|
|
|
154
154
|
has_and_belongs_to_many :architects, dependent: :nullify
|
|
155
155
|
end
|
|
156
|
+
|
|
157
|
+
class Root
|
|
158
|
+
include Mongoid::Document
|
|
159
|
+
embeds_many :embedded_once, cascade_callbacks: true
|
|
160
|
+
after_save :trace
|
|
161
|
+
|
|
162
|
+
attr_accessor :logger
|
|
163
|
+
|
|
164
|
+
def trace
|
|
165
|
+
logger << :root
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
class EmbeddedOnce
|
|
170
|
+
include Mongoid::Document
|
|
171
|
+
embeds_many :embedded_twice, cascade_callbacks: true
|
|
172
|
+
embedded_in :root
|
|
173
|
+
after_save :trace
|
|
174
|
+
|
|
175
|
+
attr_accessor :logger
|
|
176
|
+
|
|
177
|
+
def trace
|
|
178
|
+
logger << :embedded_once
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
class EmbeddedTwice
|
|
183
|
+
include Mongoid::Document
|
|
184
|
+
embedded_in :embedded_once
|
|
185
|
+
after_save :trace
|
|
186
|
+
|
|
187
|
+
attr_accessor :logger
|
|
188
|
+
|
|
189
|
+
def trace
|
|
190
|
+
logger << :embedded_twice
|
|
191
|
+
end
|
|
192
|
+
end
|