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
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mongoid
|
|
4
|
+
module Errors
|
|
5
|
+
|
|
6
|
+
# This error is raised when attempting the change the value of an
|
|
7
|
+
# immutable attribute. For example, the _id attribute is immutable,
|
|
8
|
+
# and attempting to change it on a document that has already been
|
|
9
|
+
# persisted will result in this error.
|
|
10
|
+
class ImmutableAttribute < MongoidError
|
|
11
|
+
|
|
12
|
+
# Create the new error.
|
|
13
|
+
#
|
|
14
|
+
# @example Create the new error.
|
|
15
|
+
# ImmutableAttribute.new(:_id, "1234")
|
|
16
|
+
#
|
|
17
|
+
# @param [ Symbol | String ] name The name of the attribute.
|
|
18
|
+
# @param [ Object ] value The attempted set value.
|
|
19
|
+
def initialize(name, value)
|
|
20
|
+
super(
|
|
21
|
+
compose_message("immutable_attribute", { name: name, value: value })
|
|
22
|
+
)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mongoid
|
|
4
|
+
module Errors
|
|
5
|
+
|
|
6
|
+
# This error is raised when a bad async query executor option is attempted
|
|
7
|
+
# to be set.
|
|
8
|
+
class InvalidQueryExecutor < MongoidError
|
|
9
|
+
|
|
10
|
+
# Create the new error.
|
|
11
|
+
#
|
|
12
|
+
# @param [ Symbol | String ] executor The attempted async query executor.
|
|
13
|
+
#
|
|
14
|
+
# @api private
|
|
15
|
+
def initialize(executor)
|
|
16
|
+
super(
|
|
17
|
+
compose_message(
|
|
18
|
+
"invalid_async_query_executor",
|
|
19
|
+
{ executor: executor, options: [:immediate, :global_thread_pool] }
|
|
20
|
+
)
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mongoid
|
|
4
|
+
module Errors
|
|
5
|
+
|
|
6
|
+
# This error is raised when a bad global executor concurrency option is attempted
|
|
7
|
+
# to be set.
|
|
8
|
+
class InvalidGlobalExecutorConcurrency < MongoidError
|
|
9
|
+
|
|
10
|
+
# Create the new error.
|
|
11
|
+
#
|
|
12
|
+
# @api private
|
|
13
|
+
def initialize
|
|
14
|
+
super(
|
|
15
|
+
compose_message(
|
|
16
|
+
"invalid_global_executor_concurrency"
|
|
17
|
+
)
|
|
18
|
+
)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
data/lib/mongoid/errors.rb
CHANGED
|
@@ -3,11 +3,14 @@
|
|
|
3
3
|
require "mongoid/errors/mongoid_error"
|
|
4
4
|
require "mongoid/errors/ambiguous_relationship"
|
|
5
5
|
require "mongoid/errors/callback"
|
|
6
|
+
require "mongoid/errors/create_collection_failure"
|
|
6
7
|
require "mongoid/errors/criteria_argument_required"
|
|
7
8
|
require "mongoid/errors/document_not_destroyed"
|
|
8
9
|
require "mongoid/errors/document_not_found"
|
|
9
10
|
require "mongoid/errors/empty_config_file"
|
|
11
|
+
require "mongoid/errors/immutable_attribute"
|
|
10
12
|
require "mongoid/errors/in_memory_collation_not_supported"
|
|
13
|
+
require "mongoid/errors/invalid_async_query_executor"
|
|
11
14
|
require "mongoid/errors/invalid_collection"
|
|
12
15
|
require "mongoid/errors/invalid_config_file"
|
|
13
16
|
require "mongoid/errors/invalid_config_option"
|
|
@@ -16,6 +19,7 @@ require "mongoid/errors/invalid_field"
|
|
|
16
19
|
require "mongoid/errors/invalid_field_option"
|
|
17
20
|
require "mongoid/errors/invalid_field_type"
|
|
18
21
|
require "mongoid/errors/invalid_find"
|
|
22
|
+
require "mongoid/errors/invalid_global_executor_concurrency"
|
|
19
23
|
require "mongoid/errors/invalid_includes"
|
|
20
24
|
require "mongoid/errors/invalid_index"
|
|
21
25
|
require "mongoid/errors/invalid_options"
|
|
@@ -35,7 +39,6 @@ require "mongoid/errors/invalid_scope"
|
|
|
35
39
|
require "mongoid/errors/invalid_session_use"
|
|
36
40
|
require "mongoid/errors/invalid_set_polymorphic_relation"
|
|
37
41
|
require "mongoid/errors/invalid_storage_options"
|
|
38
|
-
require "mongoid/errors/invalid_storage_parent"
|
|
39
42
|
require "mongoid/errors/invalid_time"
|
|
40
43
|
require "mongoid/errors/inverse_not_found"
|
|
41
44
|
require "mongoid/errors/mixed_relations"
|
|
@@ -38,12 +38,8 @@ module Mongoid
|
|
|
38
38
|
consolidated = {}
|
|
39
39
|
each_pair do |key, value|
|
|
40
40
|
if key =~ /\$/
|
|
41
|
-
value.
|
|
42
|
-
|
|
43
|
-
real_key = klass.database_field_name(key2)
|
|
44
|
-
|
|
45
|
-
value.delete(key2) if real_key != key2
|
|
46
|
-
value[real_key] = value_for(key, klass, real_key, value2)
|
|
41
|
+
value.each_pair do |_key, _value|
|
|
42
|
+
value[_key] = (key == "$rename") ? _value.to_s : mongoize_for(key, klass, _key, _value)
|
|
47
43
|
end
|
|
48
44
|
consolidated[key] ||= {}
|
|
49
45
|
consolidated[key].update(value)
|
|
@@ -185,24 +181,6 @@ module Mongoid
|
|
|
185
181
|
|
|
186
182
|
private
|
|
187
183
|
|
|
188
|
-
# Get the value for the provided operator, klass, key and value.
|
|
189
|
-
#
|
|
190
|
-
# This is necessary for special cases like $rename, $addToSet and $push.
|
|
191
|
-
#
|
|
192
|
-
# @param [ String ] operator The operator.
|
|
193
|
-
# @param [ Class ] klass The model class.
|
|
194
|
-
# @param [ String | Symbol ] key The field key.
|
|
195
|
-
# @param [ Object ] value The original value.
|
|
196
|
-
#
|
|
197
|
-
# @return [ Object ] Value prepared for the provided operator.
|
|
198
|
-
def value_for(operator, klass, key, value)
|
|
199
|
-
case operator
|
|
200
|
-
when "$rename" then value.to_s
|
|
201
|
-
when "$addToSet", "$push" then value.mongoize
|
|
202
|
-
else mongoize_for(operator, klass, operator, value)
|
|
203
|
-
end
|
|
204
|
-
end
|
|
205
|
-
|
|
206
184
|
# Mongoize for the klass, key and value.
|
|
207
185
|
#
|
|
208
186
|
# @api private
|
|
@@ -91,7 +91,7 @@ module Mongoid
|
|
|
91
91
|
# object.do_or_do_not(:use, "The Force")
|
|
92
92
|
#
|
|
93
93
|
# @param [ String | Symbol ] name The method name.
|
|
94
|
-
# @param [
|
|
94
|
+
# @param [ Object... ] *args The arguments.
|
|
95
95
|
#
|
|
96
96
|
# @return [ Object | nil ] The result of the method call or nil if the
|
|
97
97
|
# method does not exist.
|
|
@@ -190,7 +190,7 @@ module Mongoid
|
|
|
190
190
|
# object.you_must(:use, "The Force")
|
|
191
191
|
#
|
|
192
192
|
# @param [ String | Symbol ] name The method name.
|
|
193
|
-
# @param [
|
|
193
|
+
# @param [ Object... ] *args The arguments.
|
|
194
194
|
#
|
|
195
195
|
# @return [ Object | nil ] The result of the method call or nil if the
|
|
196
196
|
# method does not exist. Nil if the object is frozen.
|
|
@@ -31,6 +31,16 @@ module Mongoid
|
|
|
31
31
|
true
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
+
# Is the localized field enforcing values to be present?
|
|
35
|
+
#
|
|
36
|
+
# @example Is the localized field enforcing values to be present?
|
|
37
|
+
# field.localize_present?
|
|
38
|
+
#
|
|
39
|
+
# @return [ true | false ] If the field enforces present.
|
|
40
|
+
def localize_present?
|
|
41
|
+
options[:localize] == :present
|
|
42
|
+
end
|
|
43
|
+
|
|
34
44
|
# Convert the provided string into a hash for the locale.
|
|
35
45
|
#
|
|
36
46
|
# @example Serialize the value.
|
|
@@ -97,6 +97,16 @@ module Mongoid
|
|
|
97
97
|
false
|
|
98
98
|
end
|
|
99
99
|
|
|
100
|
+
# Is the localized field enforcing values to be present?
|
|
101
|
+
#
|
|
102
|
+
# @example Is the localized field enforcing values to be present?
|
|
103
|
+
# field.localize_present?
|
|
104
|
+
#
|
|
105
|
+
# @return [ true | false ] If the field enforces present.
|
|
106
|
+
def localize_present?
|
|
107
|
+
false
|
|
108
|
+
end
|
|
109
|
+
|
|
100
110
|
# Get the metadata for the field if its a foreign key.
|
|
101
111
|
#
|
|
102
112
|
# @example Get the metadata.
|
data/lib/mongoid/fields.rb
CHANGED
|
@@ -538,6 +538,8 @@ module Mongoid
|
|
|
538
538
|
# Model.add_defaults(field)
|
|
539
539
|
#
|
|
540
540
|
# @param [ Field ] field The field to add for.
|
|
541
|
+
#
|
|
542
|
+
# @api private
|
|
541
543
|
def add_defaults(field)
|
|
542
544
|
default, name = field.default_val, field.name.to_s
|
|
543
545
|
remove_defaults(name)
|
|
@@ -557,6 +559,8 @@ module Mongoid
|
|
|
557
559
|
#
|
|
558
560
|
# @param [ Symbol ] name The name of the field.
|
|
559
561
|
# @param [ Hash ] options The hash of options.
|
|
562
|
+
#
|
|
563
|
+
# @api private
|
|
560
564
|
def add_field(name, options = {})
|
|
561
565
|
aliased = options[:as]
|
|
562
566
|
aliased_fields[aliased.to_s] = name if aliased
|
|
@@ -584,6 +588,8 @@ module Mongoid
|
|
|
584
588
|
# # => "called"
|
|
585
589
|
#
|
|
586
590
|
# @param [ Field ] field the field to process
|
|
591
|
+
#
|
|
592
|
+
# @api private
|
|
587
593
|
def process_options(field)
|
|
588
594
|
field_options = field.options
|
|
589
595
|
|
|
@@ -606,6 +612,8 @@ module Mongoid
|
|
|
606
612
|
# @param [ Symbol ] name The name of the field.
|
|
607
613
|
# @param [ Symbol ] meth The name of the accessor.
|
|
608
614
|
# @param [ Hash ] options The options.
|
|
615
|
+
#
|
|
616
|
+
# @api private
|
|
609
617
|
def create_accessors(name, meth, options = {})
|
|
610
618
|
field = fields[name]
|
|
611
619
|
|
|
@@ -629,6 +637,8 @@ module Mongoid
|
|
|
629
637
|
# @param [ String ] name The name of the attribute.
|
|
630
638
|
# @param [ String ] meth The name of the method.
|
|
631
639
|
# @param [ Field ] field The field.
|
|
640
|
+
#
|
|
641
|
+
# @api private
|
|
632
642
|
def create_field_getter(name, meth, field)
|
|
633
643
|
generated_methods.module_eval do
|
|
634
644
|
re_define_method(meth) do
|
|
@@ -651,6 +661,8 @@ module Mongoid
|
|
|
651
661
|
#
|
|
652
662
|
# @param [ String ] name The name of the attribute.
|
|
653
663
|
# @param [ String ] meth The name of the method.
|
|
664
|
+
#
|
|
665
|
+
# @api private
|
|
654
666
|
def create_field_getter_before_type_cast(name, meth)
|
|
655
667
|
generated_methods.module_eval do
|
|
656
668
|
re_define_method("#{meth}_before_type_cast") do
|
|
@@ -671,6 +683,8 @@ module Mongoid
|
|
|
671
683
|
# @param [ String ] name The name of the attribute.
|
|
672
684
|
# @param [ String ] meth The name of the method.
|
|
673
685
|
# @param [ Field ] field The field.
|
|
686
|
+
#
|
|
687
|
+
# @api private
|
|
674
688
|
def create_field_setter(name, meth, field)
|
|
675
689
|
generated_methods.module_eval do
|
|
676
690
|
re_define_method("#{meth}=") do |value|
|
|
@@ -690,6 +704,8 @@ module Mongoid
|
|
|
690
704
|
#
|
|
691
705
|
# @param [ String ] name The name of the attribute.
|
|
692
706
|
# @param [ String ] meth The name of the method.
|
|
707
|
+
#
|
|
708
|
+
# @api private
|
|
693
709
|
def create_field_check(name, meth)
|
|
694
710
|
generated_methods.module_eval do
|
|
695
711
|
re_define_method("#{meth}?") do
|
|
@@ -706,6 +722,8 @@ module Mongoid
|
|
|
706
722
|
#
|
|
707
723
|
# @param [ String ] name The name of the attribute.
|
|
708
724
|
# @param [ String ] meth The name of the method.
|
|
725
|
+
#
|
|
726
|
+
# @api private
|
|
709
727
|
def create_translations_getter(name, meth)
|
|
710
728
|
generated_methods.module_eval do
|
|
711
729
|
re_define_method("#{meth}_translations") do
|
|
@@ -724,6 +742,8 @@ module Mongoid
|
|
|
724
742
|
# @param [ String ] name The name of the attribute.
|
|
725
743
|
# @param [ String ] meth The name of the method.
|
|
726
744
|
# @param [ Field ] field The field.
|
|
745
|
+
#
|
|
746
|
+
# @api private
|
|
727
747
|
def create_translations_setter(name, meth, field)
|
|
728
748
|
generated_methods.module_eval do
|
|
729
749
|
re_define_method("#{meth}_translations=") do |value|
|
|
@@ -743,6 +763,8 @@ module Mongoid
|
|
|
743
763
|
# Person.generated_methods
|
|
744
764
|
#
|
|
745
765
|
# @return [ Module ] The module of generated methods.
|
|
766
|
+
#
|
|
767
|
+
# @api private
|
|
746
768
|
def generated_methods
|
|
747
769
|
@generated_methods ||= begin
|
|
748
770
|
mod = Module.new
|
|
@@ -757,11 +779,21 @@ module Mongoid
|
|
|
757
779
|
# Model.remove_defaults(name)
|
|
758
780
|
#
|
|
759
781
|
# @param [ String ] name The field name.
|
|
782
|
+
#
|
|
783
|
+
# @api private
|
|
760
784
|
def remove_defaults(name)
|
|
761
785
|
pre_processed_defaults.delete_one(name)
|
|
762
786
|
post_processed_defaults.delete_one(name)
|
|
763
787
|
end
|
|
764
788
|
|
|
789
|
+
# Create a field for the given name and options.
|
|
790
|
+
#
|
|
791
|
+
# @param [ Symbol ] name The name of the field.
|
|
792
|
+
# @param [ Hash ] options The hash of options.
|
|
793
|
+
#
|
|
794
|
+
# @return [ Field ] The created field.
|
|
795
|
+
#
|
|
796
|
+
# @api private
|
|
765
797
|
def field_for(name, options)
|
|
766
798
|
opts = options.merge(klass: self)
|
|
767
799
|
opts[:type] = retrieve_and_validate_type(name, options[:type])
|
|
@@ -782,22 +814,32 @@ module Mongoid
|
|
|
782
814
|
#
|
|
783
815
|
# @api private
|
|
784
816
|
def retrieve_and_validate_type(name, type)
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
if result
|
|
791
|
-
warn_message
|
|
792
|
-
|
|
793
|
-
|
|
817
|
+
type_mapping = TYPE_MAPPINGS[type]
|
|
818
|
+
result = type_mapping || unmapped_type(type)
|
|
819
|
+
if !result.is_a?(Class)
|
|
820
|
+
raise Errors::InvalidFieldType.new(self, name, type)
|
|
821
|
+
else
|
|
822
|
+
if INVALID_BSON_CLASSES.include?(result)
|
|
823
|
+
warn_message = "Using #{result} as the field type is not supported. "
|
|
824
|
+
if result == BSON::Decimal128
|
|
825
|
+
warn_message += "In BSON <= 4, the BSON::Decimal128 type will work as expected for both storing and querying, but will return a BigDecimal on query in BSON 5+."
|
|
826
|
+
else
|
|
827
|
+
warn_message += "Saving values of this type to the database will work as expected, however, querying them will return a value of the native Ruby Integer type."
|
|
828
|
+
end
|
|
829
|
+
Mongoid.logger.warn(warn_message)
|
|
794
830
|
end
|
|
795
|
-
Mongoid.logger.warn(warn_message)
|
|
796
831
|
end
|
|
797
|
-
|
|
798
832
|
result
|
|
799
833
|
end
|
|
800
834
|
|
|
835
|
+
# Returns the type of the field if the type was not in the TYPE_MAPPINGS
|
|
836
|
+
# hash.
|
|
837
|
+
#
|
|
838
|
+
# @param [ Symbol | Class ] type The type of the field.
|
|
839
|
+
#
|
|
840
|
+
# @return [ Class ] The type of the field.
|
|
841
|
+
#
|
|
842
|
+
# @api private
|
|
801
843
|
def unmapped_type(type)
|
|
802
844
|
if "Boolean" == type.to_s
|
|
803
845
|
Mongoid::Boolean
|
|
@@ -805,19 +847,6 @@ module Mongoid
|
|
|
805
847
|
type || Object
|
|
806
848
|
end
|
|
807
849
|
end
|
|
808
|
-
|
|
809
|
-
# Queries whether or not the given type is permitted as a declared field
|
|
810
|
-
# type.
|
|
811
|
-
#
|
|
812
|
-
# @param [ Class ] type The type to query
|
|
813
|
-
#
|
|
814
|
-
# @return [ true | false ] whether or not the type is supported
|
|
815
|
-
#
|
|
816
|
-
# @api private
|
|
817
|
-
def unsupported_type?(type)
|
|
818
|
-
return !Mongoid::Config.allow_bson5_decimal128? if type == BSON::Decimal128
|
|
819
|
-
INVALID_BSON_CLASSES.include?(type)
|
|
820
|
-
end
|
|
821
850
|
end
|
|
822
851
|
end
|
|
823
852
|
end
|
data/lib/mongoid/findable.rb
CHANGED
|
@@ -22,18 +22,24 @@ module Mongoid
|
|
|
22
22
|
:each,
|
|
23
23
|
:each_with_index,
|
|
24
24
|
:extras,
|
|
25
|
+
:fifth,
|
|
26
|
+
:fifth!,
|
|
25
27
|
:find_one_and_delete,
|
|
26
28
|
:find_one_and_replace,
|
|
27
29
|
:find_one_and_update,
|
|
28
30
|
:find_or_create_by,
|
|
29
31
|
:find_or_create_by!,
|
|
30
32
|
:find_or_initialize_by,
|
|
33
|
+
:first!,
|
|
31
34
|
:first_or_create,
|
|
32
35
|
:first_or_create!,
|
|
33
36
|
:first_or_initialize,
|
|
34
37
|
:for_js,
|
|
38
|
+
:fourth,
|
|
39
|
+
:fourth!,
|
|
35
40
|
:geo_near,
|
|
36
41
|
:includes,
|
|
42
|
+
:last!,
|
|
37
43
|
:map_reduce,
|
|
38
44
|
:max,
|
|
39
45
|
:min,
|
|
@@ -41,11 +47,19 @@ module Mongoid
|
|
|
41
47
|
:pick,
|
|
42
48
|
:pluck,
|
|
43
49
|
:read,
|
|
50
|
+
:second,
|
|
51
|
+
:second!,
|
|
52
|
+
:second_to_last,
|
|
53
|
+
:second_to_last!,
|
|
44
54
|
:sum,
|
|
45
55
|
:take,
|
|
46
56
|
:take!,
|
|
47
57
|
:tally,
|
|
48
58
|
:text_search,
|
|
59
|
+
:third,
|
|
60
|
+
:third!,
|
|
61
|
+
:third_to_last,
|
|
62
|
+
:third_to_last!,
|
|
49
63
|
:update,
|
|
50
64
|
:update_all,
|
|
51
65
|
|
|
@@ -87,9 +101,19 @@ module Mongoid
|
|
|
87
101
|
# @example Do any documents exist for the conditions?
|
|
88
102
|
# Person.exists?
|
|
89
103
|
#
|
|
104
|
+
# @example Do any documents exist for given _id.
|
|
105
|
+
# Person.exists?(BSON::ObjectId(...))
|
|
106
|
+
#
|
|
107
|
+
# @example Do any documents exist for given conditions.
|
|
108
|
+
# Person.exists?(name: "...")
|
|
109
|
+
#
|
|
110
|
+
# @param [ Hash | Object | false ] id_or_conditions an _id to
|
|
111
|
+
# search for, a hash of conditions, nil or false.
|
|
112
|
+
#
|
|
90
113
|
# @return [ true | false ] If any documents exist for the conditions.
|
|
91
|
-
|
|
92
|
-
|
|
114
|
+
# Always false if passed nil or false.
|
|
115
|
+
def exists?(id_or_conditions = :none)
|
|
116
|
+
with_default_scope.exists?(id_or_conditions)
|
|
93
117
|
end
|
|
94
118
|
|
|
95
119
|
# Finds a +Document+ or multiple documents by their _id values.
|
|
@@ -135,7 +159,7 @@ module Mongoid
|
|
|
135
159
|
# @note Each argument can be an individual id, an array of ids or
|
|
136
160
|
# a nested array. Each array will be flattened.
|
|
137
161
|
#
|
|
138
|
-
# @param [ Object | Array<Object> ] *args The
|
|
162
|
+
# @param [ [ Object | Array<Object> ]... ] *args The id(s) to find.
|
|
139
163
|
#
|
|
140
164
|
# @return [ Document | Array<Document> | nil ] A document or matching documents.
|
|
141
165
|
#
|
|
@@ -140,120 +140,31 @@ module Mongoid
|
|
|
140
140
|
#
|
|
141
141
|
# @api private
|
|
142
142
|
def _mongoid_run_child_callbacks(kind, children: nil, &block)
|
|
143
|
-
if Mongoid::Config.around_callbacks_for_embeds
|
|
144
|
-
_mongoid_run_child_callbacks_with_around(kind, children: children, &block)
|
|
145
|
-
else
|
|
146
|
-
_mongoid_run_child_callbacks_without_around(kind, children: children, &block)
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
# Execute the callbacks of given kind for embedded documents including
|
|
151
|
-
# around callbacks.
|
|
152
|
-
#
|
|
153
|
-
# @note This method is prone to stack overflow errors if the document
|
|
154
|
-
# has a large number of embedded documents. It is recommended to avoid
|
|
155
|
-
# using around callbacks for embedded documents until a proper solution
|
|
156
|
-
# is implemented.
|
|
157
|
-
#
|
|
158
|
-
# @param [ Symbol ] kind The type of callback to execute.
|
|
159
|
-
# @param [ Array<Document> ] children Children to execute callbacks on. If
|
|
160
|
-
# nil, callbacks will be executed on all cascadable children of
|
|
161
|
-
# the document.
|
|
162
|
-
#
|
|
163
|
-
# @api private
|
|
164
|
-
def _mongoid_run_child_callbacks_with_around(kind, children: nil, &block)
|
|
165
143
|
child, *tail = (children || cascadable_children(kind))
|
|
144
|
+
with_children = !Mongoid::Config.prevent_multiple_calls_of_embedded_callbacks
|
|
166
145
|
if child.nil?
|
|
167
146
|
block&.call
|
|
168
147
|
elsif tail.empty?
|
|
169
|
-
child.run_callbacks(child_callback_type(kind, child), &block)
|
|
148
|
+
child.run_callbacks(child_callback_type(kind, child), with_children: with_children, &block)
|
|
170
149
|
else
|
|
171
|
-
child.run_callbacks(child_callback_type(kind, child)) do
|
|
172
|
-
|
|
173
|
-
end
|
|
174
|
-
end
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
# Execute the callbacks of given kind for embedded documents without
|
|
178
|
-
# around callbacks.
|
|
179
|
-
#
|
|
180
|
-
# @param [ Symbol ] kind The type of callback to execute.
|
|
181
|
-
# @param [ Array<Document> ] children Children to execute callbacks on. If
|
|
182
|
-
# nil, callbacks will be executed on all cascadable children of
|
|
183
|
-
# the document.
|
|
184
|
-
#
|
|
185
|
-
# @api private
|
|
186
|
-
def _mongoid_run_child_callbacks_without_around(kind, children: nil, &block)
|
|
187
|
-
children = (children || cascadable_children(kind))
|
|
188
|
-
callback_list = _mongoid_run_child_before_callbacks(kind, children: children)
|
|
189
|
-
return false if callback_list == false
|
|
190
|
-
value = block&.call
|
|
191
|
-
callback_list.each do |_next_sequence, env|
|
|
192
|
-
env.value &&= value
|
|
193
|
-
end
|
|
194
|
-
return false if _mongoid_run_child_after_callbacks(callback_list: callback_list) == false
|
|
195
|
-
|
|
196
|
-
value
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
# Execute the before callbacks of given kind for embedded documents.
|
|
200
|
-
#
|
|
201
|
-
# @param [ Symbol ] kind The type of callback to execute.
|
|
202
|
-
# @param [ Array<Document> ] children Children to execute callbacks on.
|
|
203
|
-
# @param [ Array<ActiveSupport::Callbacks::CallbackSequence, ActiveSupport::Callbacks::Filters::Environment> ] callback_list List of
|
|
204
|
-
# pairs of callback sequence and environment. This list will be later used
|
|
205
|
-
# to execute after callbacks in reverse order.
|
|
206
|
-
#
|
|
207
|
-
# @api private
|
|
208
|
-
def _mongoid_run_child_before_callbacks(kind, children: [], callback_list: [])
|
|
209
|
-
children.each do |child|
|
|
210
|
-
chain = child.__callbacks[child_callback_type(kind, child)]
|
|
211
|
-
env = ActiveSupport::Callbacks::Filters::Environment.new(child, false, nil)
|
|
212
|
-
next_sequence = compile_callbacks(chain)
|
|
213
|
-
unless next_sequence.final?
|
|
214
|
-
Mongoid.logger.warn("Around callbacks are disabled for embedded documents. Skipping around callbacks for #{child.class.name}.")
|
|
215
|
-
Mongoid.logger.warn("To enable around callbacks for embedded documents, set Mongoid::Config.around_callbacks_for_embeds to true.")
|
|
216
|
-
end
|
|
217
|
-
next_sequence.invoke_before(env)
|
|
218
|
-
return false if env.halted
|
|
219
|
-
env.value = !env.halted
|
|
220
|
-
callback_list << [next_sequence, env]
|
|
221
|
-
if (grandchildren = child.send(:cascadable_children, kind))
|
|
222
|
-
_mongoid_run_child_before_callbacks(kind, children: grandchildren, callback_list: callback_list)
|
|
150
|
+
child.run_callbacks(child_callback_type(kind, child), with_children: with_children) do
|
|
151
|
+
_mongoid_run_child_callbacks(kind, children: tail, &block)
|
|
223
152
|
end
|
|
224
153
|
end
|
|
225
|
-
callback_list
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
# Execute the after callbacks.
|
|
229
|
-
#
|
|
230
|
-
# @param [ Array<ActiveSupport::Callbacks::CallbackSequence, ActiveSupport::Callbacks::Filters::Environment> ] callback_list List of
|
|
231
|
-
# pairs of callback sequence and environment.
|
|
232
|
-
def _mongoid_run_child_after_callbacks(callback_list: [])
|
|
233
|
-
callback_list.reverse_each do |next_sequence, env|
|
|
234
|
-
next_sequence.invoke_after(env)
|
|
235
|
-
return false if env.halted
|
|
236
|
-
end
|
|
237
154
|
end
|
|
238
155
|
|
|
239
|
-
#
|
|
156
|
+
# This is used to store callbacks to be executed later. A good use case for
|
|
157
|
+
# this is delaying the after_find and after_initialize callbacks until the
|
|
158
|
+
# associations are set on the document. This can also be used to delay
|
|
159
|
+
# applying the defaults on a document.
|
|
240
160
|
#
|
|
241
|
-
# @return [ Array<Symbol> ]
|
|
161
|
+
# @return [ Array<Symbol> ] an array of symbols that represent the pending callbacks.
|
|
242
162
|
#
|
|
243
163
|
# @api private
|
|
244
164
|
def pending_callbacks
|
|
245
165
|
@pending_callbacks ||= [].to_set
|
|
246
166
|
end
|
|
247
167
|
|
|
248
|
-
# Stores callbacks to be executed later. A good use case for
|
|
249
|
-
# this is delaying the after_find and after_initialize callbacks until the
|
|
250
|
-
# associations are set on the document. This can also be used to delay
|
|
251
|
-
# applying the defaults on a document.
|
|
252
|
-
#
|
|
253
|
-
# @param [ Array<Symbol> ] value Method symbols of the pending callbacks to store.
|
|
254
|
-
#
|
|
255
|
-
# @return [ Array<Symbol> ] Method symbols of the stored pending callbacks.
|
|
256
|
-
#
|
|
257
168
|
# @api private
|
|
258
169
|
def pending_callbacks=(value)
|
|
259
170
|
@pending_callbacks = value
|
|
@@ -388,7 +299,7 @@ module Mongoid
|
|
|
388
299
|
end
|
|
389
300
|
self.class.send :define_method, name do
|
|
390
301
|
env = ActiveSupport::Callbacks::Filters::Environment.new(self, false, nil)
|
|
391
|
-
sequence =
|
|
302
|
+
sequence = chain.compile
|
|
392
303
|
sequence.invoke_before(env)
|
|
393
304
|
env.value = !env.halted
|
|
394
305
|
sequence.invoke_after(env)
|
|
@@ -398,24 +309,5 @@ module Mongoid
|
|
|
398
309
|
end
|
|
399
310
|
send(name)
|
|
400
311
|
end
|
|
401
|
-
|
|
402
|
-
# Compile the callback chain.
|
|
403
|
-
#
|
|
404
|
-
# This method hides the differences between ActiveSupport implementations
|
|
405
|
-
# before and after 7.1.
|
|
406
|
-
#
|
|
407
|
-
# @param [ ActiveSupport::Callbacks::CallbackChain ] chain The callback chain.
|
|
408
|
-
# @param [ Symbol | nil ] type The type of callback chain to compile.
|
|
409
|
-
#
|
|
410
|
-
# @return [ ActiveSupport::Callbacks::CallbackSequence ] The compiled callback sequence.
|
|
411
|
-
def compile_callbacks(chain, type = nil)
|
|
412
|
-
if chain.method(:compile).arity == 0
|
|
413
|
-
# ActiveSupport < 7.1
|
|
414
|
-
chain.compile
|
|
415
|
-
else
|
|
416
|
-
# ActiveSupport >= 7.1
|
|
417
|
-
chain.compile(type)
|
|
418
|
-
end
|
|
419
|
-
end
|
|
420
312
|
end
|
|
421
313
|
end
|
|
@@ -46,7 +46,7 @@ module Mongoid
|
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
-
# Per https://
|
|
49
|
+
# Per https://www.mongodb.com/docs/ruby-driver/current/tutorials/bson-v4/#time-instances,
|
|
50
50
|
# > Times in BSON (and MongoDB) can only have millisecond precision. When Ruby Time instances
|
|
51
51
|
# are serialized to BSON or Extended JSON, the times are floored to the nearest millisecond.
|
|
52
52
|
#
|
data/lib/mongoid/matcher/type.rb
CHANGED
|
@@ -100,6 +100,7 @@ module Mongoid
|
|
|
100
100
|
#
|
|
101
101
|
# @return [ Document ] The document.
|
|
102
102
|
def prepare_insert(options = {})
|
|
103
|
+
raise Errors::ReadonlyDocument.new(self.class) if readonly? && !Mongoid.legacy_readonly
|
|
103
104
|
return self if performing_validations?(options) &&
|
|
104
105
|
invalid?(options[:context] || :create)
|
|
105
106
|
run_callbacks(:save, with_children: false) do
|