mongoid 8.0.3 → 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.
Files changed (188) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +3 -3
  4. data/README.md +3 -3
  5. data/lib/config/locales/en.yml +46 -14
  6. data/lib/mongoid/association/accessors.rb +2 -2
  7. data/lib/mongoid/association/builders.rb +1 -1
  8. data/lib/mongoid/association/embedded/batchable.rb +2 -2
  9. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +2 -2
  10. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +2 -1
  11. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +3 -2
  12. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +23 -21
  13. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +1 -1
  14. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +1 -1
  15. data/lib/mongoid/association/nested/one.rb +40 -2
  16. data/lib/mongoid/association/proxy.rb +1 -1
  17. data/lib/mongoid/association/referenced/counter_cache.rb +2 -2
  18. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +5 -1
  19. data/lib/mongoid/association/referenced/has_many/enumerable.rb +2 -2
  20. data/lib/mongoid/association/referenced/has_many/proxy.rb +7 -3
  21. data/lib/mongoid/association/reflections.rb +2 -2
  22. data/lib/mongoid/attributes/dynamic.rb +1 -1
  23. data/lib/mongoid/attributes/nested.rb +2 -2
  24. data/lib/mongoid/attributes/projector.rb +1 -1
  25. data/lib/mongoid/attributes/readonly.rb +1 -1
  26. data/lib/mongoid/attributes.rb +8 -2
  27. data/lib/mongoid/changeable.rb +104 -4
  28. data/lib/mongoid/clients/storage_options.rb +2 -5
  29. data/lib/mongoid/clients/validators/storage.rb +1 -13
  30. data/lib/mongoid/collection_configurable.rb +58 -0
  31. data/lib/mongoid/composable.rb +2 -0
  32. data/lib/mongoid/config/defaults.rb +60 -0
  33. data/lib/mongoid/config/validators/async_query_executor.rb +24 -0
  34. data/lib/mongoid/config/validators.rb +1 -0
  35. data/lib/mongoid/config.rb +101 -0
  36. data/lib/mongoid/contextual/atomic.rb +1 -1
  37. data/lib/mongoid/contextual/memory.rb +233 -33
  38. data/lib/mongoid/contextual/mongo/documents_loader.rb +177 -0
  39. data/lib/mongoid/contextual/mongo.rb +373 -113
  40. data/lib/mongoid/contextual/none.rb +162 -7
  41. data/lib/mongoid/contextual.rb +12 -0
  42. data/lib/mongoid/criteria/findable.rb +2 -2
  43. data/lib/mongoid/criteria/includable.rb +4 -3
  44. data/lib/mongoid/criteria/queryable/extensions/array.rb +1 -1
  45. data/lib/mongoid/criteria/queryable/extensions/hash.rb +1 -1
  46. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +0 -8
  47. data/lib/mongoid/criteria/queryable/extensions/string.rb +1 -11
  48. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +0 -10
  49. data/lib/mongoid/criteria/queryable/key.rb +1 -1
  50. data/lib/mongoid/criteria/queryable/mergeable.rb +1 -1
  51. data/lib/mongoid/criteria/queryable/optional.rb +8 -8
  52. data/lib/mongoid/criteria/queryable/selectable.rb +43 -12
  53. data/lib/mongoid/criteria/translator.rb +45 -0
  54. data/lib/mongoid/criteria.rb +7 -5
  55. data/lib/mongoid/deprecable.rb +1 -1
  56. data/lib/mongoid/document.rb +50 -13
  57. data/lib/mongoid/errors/create_collection_failure.rb +33 -0
  58. data/lib/mongoid/errors/drop_collection_failure.rb +27 -0
  59. data/lib/mongoid/errors/immutable_attribute.rb +26 -0
  60. data/lib/mongoid/errors/invalid_async_query_executor.rb +25 -0
  61. data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +22 -0
  62. data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
  63. data/lib/mongoid/errors.rb +4 -1
  64. data/lib/mongoid/extensions/object.rb +2 -2
  65. data/lib/mongoid/extensions/time.rb +2 -0
  66. data/lib/mongoid/factory.rb +21 -8
  67. data/lib/mongoid/fields/localized.rb +10 -0
  68. data/lib/mongoid/fields/standard.rb +10 -0
  69. data/lib/mongoid/fields.rb +69 -13
  70. data/lib/mongoid/findable.rb +27 -3
  71. data/lib/mongoid/interceptable.rb +7 -6
  72. data/lib/mongoid/matcher/eq_impl.rb +1 -1
  73. data/lib/mongoid/matcher/type.rb +1 -1
  74. data/lib/mongoid/matcher.rb +21 -6
  75. data/lib/mongoid/persistable/creatable.rb +1 -0
  76. data/lib/mongoid/persistable/deletable.rb +1 -1
  77. data/lib/mongoid/persistable/savable.rb +13 -1
  78. data/lib/mongoid/persistable/unsettable.rb +2 -2
  79. data/lib/mongoid/persistable/updatable.rb +51 -1
  80. data/lib/mongoid/persistable/upsertable.rb +20 -1
  81. data/lib/mongoid/persistable.rb +3 -0
  82. data/lib/mongoid/query_cache.rb +5 -1
  83. data/lib/mongoid/railties/database.rake +7 -2
  84. data/lib/mongoid/shardable.rb +35 -11
  85. data/lib/mongoid/stateful.rb +22 -1
  86. data/lib/mongoid/tasks/database.rake +12 -0
  87. data/lib/mongoid/tasks/database.rb +20 -0
  88. data/lib/mongoid/threaded.rb +30 -0
  89. data/lib/mongoid/traversable.rb +1 -1
  90. data/lib/mongoid/utils.rb +22 -0
  91. data/lib/mongoid/validatable/macros.rb +5 -5
  92. data/lib/mongoid/validatable.rb +4 -1
  93. data/lib/mongoid/version.rb +1 -1
  94. data/lib/mongoid/warnings.rb +17 -1
  95. data/lib/mongoid.rb +16 -3
  96. data/spec/integration/app_spec.rb +2 -2
  97. data/spec/integration/callbacks_models.rb +37 -0
  98. data/spec/integration/callbacks_spec.rb +134 -0
  99. data/spec/integration/discriminator_key_spec.rb +4 -5
  100. data/spec/integration/i18n_fallbacks_spec.rb +3 -2
  101. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +27 -0
  102. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +57 -57
  103. data/spec/mongoid/association/embedded/embeds_many_models.rb +1 -0
  104. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +15 -2
  105. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -18
  106. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +148 -224
  107. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +111 -164
  108. data/spec/mongoid/association/syncable_spec.rb +1 -1
  109. data/spec/mongoid/attributes_spec.rb +5 -8
  110. data/spec/mongoid/changeable_spec.rb +299 -24
  111. data/spec/mongoid/clients_spec.rb +122 -13
  112. data/spec/mongoid/collection_configurable_spec.rb +158 -0
  113. data/spec/mongoid/config/defaults_spec.rb +160 -0
  114. data/spec/mongoid/config_spec.rb +154 -18
  115. data/spec/mongoid/contextual/memory_spec.rb +332 -76
  116. data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +187 -0
  117. data/spec/mongoid/contextual/mongo_spec.rb +995 -36
  118. data/spec/mongoid/contextual/none_spec.rb +49 -2
  119. data/spec/mongoid/copyable_spec.rb +3 -11
  120. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +4 -69
  121. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +0 -59
  122. data/spec/mongoid/criteria/queryable/optional_spec.rb +15 -0
  123. data/spec/mongoid/criteria/queryable/options_spec.rb +1 -1
  124. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +419 -0
  125. data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -1
  126. data/spec/mongoid/criteria/queryable/selector_spec.rb +1 -1
  127. data/spec/mongoid/criteria/translator_spec.rb +132 -0
  128. data/spec/mongoid/criteria_projection_spec.rb +1 -4
  129. data/spec/mongoid/criteria_spec.rb +5 -9
  130. data/spec/mongoid/errors/readonly_document_spec.rb +2 -2
  131. data/spec/mongoid/extensions/time_spec.rb +8 -43
  132. data/spec/mongoid/extensions/time_with_zone_spec.rb +7 -52
  133. data/spec/mongoid/fields/localized_spec.rb +46 -28
  134. data/spec/mongoid/fields_spec.rb +136 -34
  135. data/spec/mongoid/findable_spec.rb +391 -34
  136. data/spec/mongoid/indexable_spec.rb +16 -10
  137. data/spec/mongoid/interceptable_spec.rb +15 -3
  138. data/spec/mongoid/persistable/deletable_spec.rb +26 -6
  139. data/spec/mongoid/persistable/destroyable_spec.rb +26 -6
  140. data/spec/mongoid/persistable/incrementable_spec.rb +37 -0
  141. data/spec/mongoid/persistable/logical_spec.rb +37 -0
  142. data/spec/mongoid/persistable/poppable_spec.rb +36 -0
  143. data/spec/mongoid/persistable/pullable_spec.rb +72 -0
  144. data/spec/mongoid/persistable/pushable_spec.rb +72 -0
  145. data/spec/mongoid/persistable/renamable_spec.rb +36 -0
  146. data/spec/mongoid/persistable/savable_spec.rb +96 -0
  147. data/spec/mongoid/persistable/settable_spec.rb +37 -0
  148. data/spec/mongoid/persistable/unsettable_spec.rb +36 -0
  149. data/spec/mongoid/persistable/updatable_spec.rb +20 -28
  150. data/spec/mongoid/persistable/upsertable_spec.rb +80 -6
  151. data/spec/mongoid/persistence_context_spec.rb +7 -57
  152. data/spec/mongoid/query_cache_spec.rb +56 -61
  153. data/spec/mongoid/reloadable_spec.rb +24 -4
  154. data/spec/mongoid/scopable_spec.rb +70 -0
  155. data/spec/mongoid/serializable_spec.rb +9 -30
  156. data/spec/mongoid/shardable_models.rb +14 -0
  157. data/spec/mongoid/shardable_spec.rb +153 -61
  158. data/spec/mongoid/stateful_spec.rb +122 -8
  159. data/spec/mongoid/tasks/database_rake_spec.rb +74 -0
  160. data/spec/mongoid/tasks/database_spec.rb +127 -0
  161. data/spec/mongoid/timestamps_spec.rb +9 -11
  162. data/spec/mongoid/touchable_spec.rb +277 -5
  163. data/spec/mongoid/touchable_spec_models.rb +3 -1
  164. data/spec/mongoid/traversable_spec.rb +9 -24
  165. data/spec/mongoid/validatable/uniqueness_spec.rb +2 -3
  166. data/spec/mongoid_spec.rb +35 -9
  167. data/spec/shared/lib/mrss/docker_runner.rb +7 -0
  168. data/spec/shared/lib/mrss/event_subscriber.rb +15 -5
  169. data/spec/shared/lib/mrss/lite_constraints.rb +10 -2
  170. data/spec/shared/lib/mrss/server_version_registry.rb +16 -23
  171. data/spec/shared/lib/mrss/utils.rb +28 -6
  172. data/spec/shared/share/Dockerfile.erb +36 -40
  173. data/spec/shared/shlib/server.sh +32 -8
  174. data/spec/shared/shlib/set_env.sh +4 -4
  175. data/spec/spec_helper.rb +5 -0
  176. data/spec/support/immutable_ids.rb +118 -0
  177. data/spec/support/macros.rb +47 -15
  178. data/spec/support/models/artist.rb +0 -1
  179. data/spec/support/models/band.rb +1 -0
  180. data/spec/support/models/book.rb +1 -0
  181. data/spec/support/models/building.rb +2 -0
  182. data/spec/support/models/cover.rb +10 -0
  183. data/spec/support/models/product.rb +1 -0
  184. data.tar.gz.sig +0 -0
  185. metadata +700 -656
  186. metadata.gz.sig +0 -0
  187. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -60
  188. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -60
@@ -24,7 +24,7 @@ module Mongoid
24
24
  # #=> Mongoid.logger.warn("meow is deprecated and will be removed from Mongoid 8.0 (eat :catnip instead)")
25
25
  #
26
26
  # @param [ Module ] target_module The parent which contains the method.
27
- # @param [ Symbol | Hash<Symbol, [ Symbol | String ]> ] method_descriptors
27
+ # @param [ [ Symbol | Hash<Symbol, [ Symbol | String ]> ]... ] *method_descriptors
28
28
  # The methods to deprecate, with optional replacement instructions.
29
29
  def deprecate(target_module, *method_descriptors)
30
30
  Mongoid::Deprecation.deprecate_methods(target_module, *method_descriptors)
@@ -101,7 +101,7 @@ module Mongoid
101
101
  #
102
102
  # @return [ Document ] A new document.
103
103
  def initialize(attrs = nil, &block)
104
- construct_document(attrs, execute_callbacks: true, &block)
104
+ construct_document(attrs, &block)
105
105
  end
106
106
 
107
107
  # Return the model name of the document.
@@ -208,13 +208,22 @@ module Mongoid
208
208
  # Does the construction of a document.
209
209
  #
210
210
  # @param [ Hash ] attrs The attributes to set up the document with.
211
- # @param [ true | false ] execute_callbacks Flag specifies whether callbacks
212
- # should be run.
211
+ # @param [ Hash ] options The options to use.
212
+ #
213
+ # @option options [ true | false ] :execute_callbacks Flag specifies
214
+ # whether callbacks should be run.
213
215
  #
214
216
  # @return [ Document ] A new document.
215
217
  #
218
+ # @note A Ruby 2.x bug prevents the options hash from being keyword
219
+ # arguments. Once we drop support for Ruby 2.x, we can reimplement
220
+ # the options hash as keyword arguments.
221
+ # See https://bugs.ruby-lang.org/issues/15753
222
+ #
216
223
  # @api private
217
- def construct_document(attrs = nil, execute_callbacks: true)
224
+ def construct_document(attrs = nil, options = {})
225
+ execute_callbacks = options.fetch(:execute_callbacks, Threaded.execute_callbacks?)
226
+
218
227
  @__parent = nil
219
228
  _building do
220
229
  @new_record = true
@@ -281,6 +290,20 @@ module Mongoid
281
290
 
282
291
  module ClassMethods
283
292
 
293
+ # Indicate whether callbacks should be invoked by default or not,
294
+ # within the block. Callbacks may always be explicitly invoked by passing
295
+ # `execute_callbacks: true` where available.
296
+ #
297
+ # @params execute_callbacks [ true | false ] Whether callbacks should be
298
+ # suppressed or not.
299
+ def with_callbacks(execute_callbacks)
300
+ saved, Threaded.execute_callbacks =
301
+ Threaded.execute_callbacks?, execute_callbacks
302
+ yield
303
+ ensure
304
+ Threaded.execute_callbacks = saved
305
+ end
306
+
284
307
  # Instantiate a new object, only when loaded from the database or when
285
308
  # the attributes have already been typecast.
286
309
  #
@@ -295,7 +318,7 @@ module Mongoid
295
318
  #
296
319
  # @return [ Document ] A new document.
297
320
  def instantiate(attrs = nil, selected_fields = nil, &block)
298
- instantiate_document(attrs, selected_fields, execute_callbacks: true, &block)
321
+ instantiate_document(attrs, selected_fields, &block)
299
322
  end
300
323
 
301
324
  # Instantiate the document.
@@ -303,13 +326,20 @@ module Mongoid
303
326
  # @param [ Hash ] attrs The hash of attributes to instantiate with.
304
327
  # @param [ Integer ] selected_fields The selected fields from the
305
328
  # criteria.
306
- # @param [ true | false ] execute_callbacks Flag specifies whether callbacks
307
- # should be run.
329
+ # @param [ Hash ] options The options to use.
330
+ #
331
+ # @option options [ true | false ] :execute_callbacks Flag specifies
332
+ # whether callbacks should be run.
308
333
  #
309
334
  # @return [ Document ] A new document.
310
335
  #
336
+ # @note A Ruby 2.x bug prevents the options hash from being keyword
337
+ # arguments. Once we drop support for Ruby 2.x, we can reimplement
338
+ # the options hash as keyword arguments.
339
+ #
311
340
  # @api private
312
- def instantiate_document(attrs = nil, selected_fields = nil, execute_callbacks: true)
341
+ def instantiate_document(attrs = nil, selected_fields = nil, options = {})
342
+ execute_callbacks = options.fetch(:execute_callbacks, Threaded.execute_callbacks?)
313
343
  attributes = if Mongoid.legacy_attributes
314
344
  attrs
315
345
  else
@@ -340,15 +370,22 @@ module Mongoid
340
370
  # Allocates and constructs a document.
341
371
  #
342
372
  # @param [ Hash ] attrs The attributes to set up the document with.
343
- # @param [ true | false ] execute_callbacks Flag specifies whether callbacks
344
- # should be run.
373
+ # @param [ Hash ] options The options to use.
374
+ #
375
+ # @option options [ true | false ] :execute_callbacks Flag specifies
376
+ # whether callbacks should be run.
377
+ #
378
+ # @note A Ruby 2.x bug prevents the options hash from being keyword
379
+ # arguments. Once we drop support for Ruby 2.x, we can reimplement
380
+ # the options hash as keyword arguments.
381
+ # See https://bugs.ruby-lang.org/issues/15753
345
382
  #
346
383
  # @return [ Document ] A new document.
347
384
  #
348
385
  # @api private
349
- def construct_document(attrs = nil, execute_callbacks: true)
350
- doc = allocate
351
- doc.send(:construct_document, attrs, execute_callbacks: execute_callbacks)
386
+ def construct_document(attrs = nil, options = {})
387
+ execute_callbacks = options.fetch(:execute_callbacks, Threaded.execute_callbacks?)
388
+ with_callbacks(execute_callbacks) { new(attrs) }
352
389
  end
353
390
 
354
391
  # Returns all types to query for when using this class as the base.
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mongoid
4
+ module Errors
5
+
6
+ # Raised when an attempt to create a collection failed.
7
+ class CreateCollectionFailure < MongoidError
8
+
9
+ # Instantiate the create collection error.
10
+ #
11
+ # @param [ String ] collection_name The name of the collection that
12
+ # Mongoid failed to create.
13
+ # @param [ Hash ] collection_options The options that were used when
14
+ # tried to create the collection.
15
+ # @param [ Mongo::Error::OperationFailure ] error The error raised when
16
+ # tried to create the collection.
17
+ #
18
+ # @api private
19
+ def initialize(collection_name, collection_options, error)
20
+ super(
21
+ compose_message(
22
+ "create_collection_failure",
23
+ {
24
+ collection_name: collection_name,
25
+ collection_options: collection_options,
26
+ error: "#{error.class}: #{error.message}"
27
+ }
28
+ )
29
+ )
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mongoid
4
+ module Errors
5
+
6
+ # Raised when an attempt to drop a collection failed.
7
+ class DropCollectionFailure < MongoidError
8
+
9
+ # Instantiate the drop collection error.
10
+ #
11
+ # @param [ String ] collection_name The name of the collection that
12
+ # Mongoid failed to drop.
13
+ #
14
+ # @api private
15
+ def initialize(collection_name, collection_options, error)
16
+ super(
17
+ compose_message(
18
+ "drop_collection_failure",
19
+ {
20
+ collection_name: collection_name
21
+ }
22
+ )
23
+ )
24
+ end
25
+ end
26
+ end
27
+ end
@@ -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
@@ -4,6 +4,8 @@ module Mongoid
4
4
  module Errors
5
5
 
6
6
  # Raised when calling store_in in a sub-class of Mongoid::Document
7
+ #
8
+ # @deprecated
7
9
  class InvalidStorageParent < MongoidError
8
10
 
9
11
  # Create the new error.
@@ -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"
@@ -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 [ Array ] args The arguments.
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 [ Array ] args The arguments.
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.
@@ -34,6 +34,8 @@ module Mongoid
34
34
  # ::Time.configured
35
35
  #
36
36
  # @return [ Time ] The configured time.
37
+ #
38
+ # @deprecated
37
39
  def configured
38
40
  Mongoid.use_activesupport_time_zone? ? (::Time.zone || ::Time) : ::Time
39
41
  end
@@ -25,27 +25,40 @@ module Mongoid
25
25
  #
26
26
  # @return [ Document ] The instantiated document.
27
27
  def build(klass, attributes = nil)
28
- execute_build(klass, attributes, execute_callbacks: true)
28
+ # A bug in Ruby 2.x (including 2.7.7) causes the attributes hash to be
29
+ # interpreted as keyword arguments, because execute_build accepts
30
+ # a keyword argument. Forcing an empty set of keyword arguments works
31
+ # around the bug. Once Ruby 2.x support is dropped, this hack can be
32
+ # removed.
33
+ # See https://bugs.ruby-lang.org/issues/15753
34
+ execute_build(klass, attributes)
29
35
  end
30
36
 
31
37
  # Execute the build.
32
38
  #
33
39
  # @param [ Class ] klass The class to instantiate from if _type is not present.
34
40
  # @param [ Hash ] attributes The document attributes.
35
- # @param [ true | false ] execute_callbacks Flag specifies whether callbacks
36
- # should be run.
41
+ # @param [ Hash ] options The options to use.
42
+ #
43
+ # @option options [ true | false ] :execute_callbacks Flag specifies
44
+ # whether callbacks should be run.
45
+ #
46
+ # @note A Ruby 2.x bug prevents the options hash from being keyword
47
+ # arguments. Once we drop support for Ruby 2.x, we can reimplement
48
+ # the options hash as keyword arguments.
49
+ # See https://bugs.ruby-lang.org/issues/15753
37
50
  #
38
51
  # @return [ Document ] The instantiated document.
39
52
  #
40
53
  # @api private
41
- def execute_build(klass, attributes = nil, execute_callbacks: true)
54
+ def execute_build(klass, attributes = nil, options = {})
42
55
  attributes ||= {}
43
56
  dvalue = attributes[klass.discriminator_key] || attributes[klass.discriminator_key.to_sym]
44
57
  type = klass.get_discriminator_mapping(dvalue)
45
58
  if type
46
- type.construct_document(attributes, execute_callbacks: execute_callbacks)
59
+ type.construct_document(attributes, options)
47
60
  else
48
- klass.construct_document(attributes, execute_callbacks: execute_callbacks)
61
+ klass.construct_document(attributes, options)
49
62
  end
50
63
  end
51
64
 
@@ -76,7 +89,7 @@ module Mongoid
76
89
  #
77
90
  # @return [ Document ] The instantiated document.
78
91
  def from_db(klass, attributes = nil, criteria = nil, selected_fields = nil)
79
- execute_from_db(klass, attributes, criteria, selected_fields, execute_callbacks: true)
92
+ execute_from_db(klass, attributes, criteria, selected_fields)
80
93
  end
81
94
 
82
95
  # Execute from_db.
@@ -97,7 +110,7 @@ module Mongoid
97
110
  # @return [ Document ] The instantiated document.
98
111
  #
99
112
  # @api private
100
- def execute_from_db(klass, attributes = nil, criteria = nil, selected_fields = nil, execute_callbacks: true)
113
+ def execute_from_db(klass, attributes = nil, criteria = nil, selected_fields = nil, execute_callbacks: Threaded.execute_callbacks?)
101
114
  if criteria
102
115
  selected_fields ||= criteria.options[:fields]
103
116
  end
@@ -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.
@@ -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,21 +779,49 @@ 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
- type_mapping = TYPE_MAPPINGS[options[:type]]
768
- opts[:type] = type_mapping || unmapped_type(options)
769
- if !opts[:type].is_a?(Class)
770
- raise Errors::InvalidFieldType.new(self, name, options[:type])
799
+ opts[:type] = retrieve_and_validate_type(name, options[:type])
800
+ return Fields::Localized.new(name, opts) if options[:localize]
801
+ return Fields::ForeignKey.new(name, opts) if options[:identity]
802
+ Fields::Standard.new(name, opts)
803
+ end
804
+
805
+ # Get the class for the given type.
806
+ #
807
+ # @param [ Symbol ] name The name of the field.
808
+ # @param [ Symbol | Class ] type The type of the field.
809
+ #
810
+ # @return [ Class ] The type of the field.
811
+ #
812
+ # @raises [ Mongoid::Errors::InvalidFieldType ] if given an invalid field
813
+ # type.
814
+ #
815
+ # @api private
816
+ def retrieve_and_validate_type(name, type)
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)
771
821
  else
772
- if INVALID_BSON_CLASSES.include?(opts[:type])
773
- warn_message = "Using #{opts[:type]} as the field type is not supported. "
774
- if opts[:type] == BSON::Decimal128
822
+ if INVALID_BSON_CLASSES.include?(result)
823
+ warn_message = "Using #{result} as the field type is not supported. "
824
+ if result == BSON::Decimal128
775
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+."
776
826
  else
777
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."
@@ -779,16 +829,22 @@ module Mongoid
779
829
  Mongoid.logger.warn(warn_message)
780
830
  end
781
831
  end
782
- return Fields::Localized.new(name, opts) if options[:localize]
783
- return Fields::ForeignKey.new(name, opts) if options[:identity]
784
- Fields::Standard.new(name, opts)
832
+ result
785
833
  end
786
834
 
787
- def unmapped_type(options)
788
- if "Boolean" == options[:type].to_s
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
843
+ def unmapped_type(type)
844
+ if "Boolean" == type.to_s
789
845
  Mongoid::Boolean
790
846
  else
791
- options[:type] || Object
847
+ type || Object
792
848
  end
793
849
  end
794
850
  end