mongoid 8.0.3 → 8.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +17 -15
  4. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +4 -0
  5. data/lib/mongoid/association/referenced/has_many/proxy.rb +4 -0
  6. data/lib/mongoid/criteria/queryable/extensions/array.rb +1 -1
  7. data/lib/mongoid/criteria/queryable/extensions/hash.rb +1 -1
  8. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +0 -8
  9. data/lib/mongoid/criteria/queryable/extensions/string.rb +1 -11
  10. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +0 -10
  11. data/lib/mongoid/criteria/translator.rb +45 -0
  12. data/lib/mongoid/criteria.rb +1 -0
  13. data/lib/mongoid/document.rb +50 -13
  14. data/lib/mongoid/factory.rb +21 -8
  15. data/lib/mongoid/matcher.rb +21 -6
  16. data/lib/mongoid/shardable.rb +35 -11
  17. data/lib/mongoid/threaded.rb +30 -0
  18. data/lib/mongoid/traversable.rb +1 -1
  19. data/lib/mongoid/version.rb +1 -1
  20. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +37 -32
  21. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +143 -197
  22. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +102 -114
  23. data/spec/mongoid/attributes_spec.rb +2 -2
  24. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +0 -59
  25. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +0 -59
  26. data/spec/mongoid/criteria/queryable/optional_spec.rb +15 -0
  27. data/spec/mongoid/criteria/translator_spec.rb +132 -0
  28. data/spec/mongoid/shardable_models.rb +14 -0
  29. data/spec/mongoid/shardable_spec.rb +153 -61
  30. data.tar.gz.sig +0 -0
  31. metadata +656 -648
  32. metadata.gz.sig +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 684d53a067a1e3410535a0dc06db2b587c5e43a19c85af0defe7f29c81e1c74d
4
- data.tar.gz: c285640352d90d219d7ccd6c0ce6c90fdf1b800f853d2aa44898025c9d49ccf8
3
+ metadata.gz: 9ab3c68fb6c373b704eb2d459a98d7a4cb99d73b87e720eabb553fcd44928d17
4
+ data.tar.gz: d0cd7fe683015dd257c48a7d0c301dd9c6972ea51be4b8199ae88b81dc45c8d6
5
5
  SHA512:
6
- metadata.gz: 6a13a92d079784bfc190d1ebddff3f2bdd6f0d3d2fb0cee336856ba8e870199b83cc7c809d17cb62a913a64624630ffd397bfa45779503b107b97f82fb4be615
7
- data.tar.gz: b887e765c135fe7018863908afabe9128007e85628cbcf11bc971cabf06a162833239da37d32293b1c3565838cf9ad14898fd91ac510a29bf37779b782411ee7
6
+ metadata.gz: 247213c01b169b66f1441ccf892590c068b116e4a4998e15cb50c0cdf3b11648bc543a0c935165a7674a88e783734df36dfeed481079d759fcbf473c068686de
7
+ data.tar.gz: fdf737044c01f8089e8bae7dbc14cce78e48e998ea810cd8e9a334f1bdc8c2b8e1ba6c885c8032c3b5da8b70d24b35b99dd90c260c87abea31a93edef15429cc
checksums.yaml.gz.sig CHANGED
Binary file
@@ -154,6 +154,23 @@ module Mongoid
154
154
  end
155
155
  end
156
156
 
157
+ # Mongoid::Extensions::Array defines Array#delete_one, so we need
158
+ # to make sure that method behaves reasonably on proxies, too.
159
+ alias delete_one delete
160
+
161
+ # Removes a single document from the collection *in memory only*.
162
+ # It will *not* persist the change.
163
+ #
164
+ # @param [ Document ] document The document to delete.
165
+ #
166
+ # @api private
167
+ def _remove(document)
168
+ _target.delete_one(document)
169
+ _unscoped.delete_one(document)
170
+ update_attributes_hash
171
+ reindex
172
+ end
173
+
157
174
  # Delete all the documents in the association without running callbacks.
158
175
  #
159
176
  # @example Delete all documents from the association.
@@ -397,21 +414,6 @@ module Mongoid
397
414
  _association.criteria(_base, _target)
398
415
  end
399
416
 
400
- # Deletes one document from the target and unscoped.
401
- #
402
- # @api private
403
- #
404
- # @example Delete one document.
405
- # relation.delete_one(doc)
406
- #
407
- # @param [ Document ] document The document to delete.
408
- def delete_one(document)
409
- _target.delete_one(document)
410
- _unscoped.delete_one(document)
411
- update_attributes_hash
412
- reindex
413
- end
414
-
415
417
  # Integrate the document into the association. will set its metadata and
416
418
  # attempt to bind the inverse.
417
419
  #
@@ -137,6 +137,10 @@ module Mongoid
137
137
  doc
138
138
  end
139
139
 
140
+ # Mongoid::Extensions::Array defines Array#delete_one, so we need
141
+ # to make sure that method behaves reasonably on proxies, too.
142
+ alias delete_one delete
143
+
140
144
  # Removes all associations between the base document and the target
141
145
  # documents by deleting the foreign keys and the references, orphaning
142
146
  # the target documents in the process.
@@ -105,6 +105,10 @@ module Mongoid
105
105
  end
106
106
  end
107
107
 
108
+ # Mongoid::Extensions::Array defines Array#delete_one, so we need
109
+ # to make sure that method behaves reasonably on proxies, too.
110
+ alias delete_one delete
111
+
108
112
  # Deletes all related documents from the database given the supplied
109
113
  # conditions.
110
114
  #
@@ -105,7 +105,7 @@ module Mongoid
105
105
  #
106
106
  # @return [ Hash ] The field/direction pair.
107
107
  def __sort_pair__
108
- { first => last.to_direction }
108
+ { first => Mongoid::Criteria::Translator.to_direction(last) }
109
109
  end
110
110
 
111
111
  private
@@ -115,7 +115,7 @@ module Mongoid
115
115
  def __sort_option__
116
116
  tap do |hash|
117
117
  hash.each_pair do |key, value|
118
- hash.store(key, value.to_direction)
118
+ hash.store(key, Mongoid::Criteria::Translator.to_direction(value))
119
119
  end
120
120
  end
121
121
  end
@@ -30,14 +30,6 @@ module Mongoid
30
30
  ::Time.at(self).utc
31
31
  end
32
32
 
33
- # Get the integer as a sort direction.
34
- #
35
- # @example Get the integer as a sort direction.
36
- # 1.to_direction
37
- #
38
- # @return [ Integer ] self.
39
- def to_direction; self; end
40
-
41
33
  module ClassMethods
42
34
 
43
35
  # Get the object as a numeric.
@@ -49,7 +49,7 @@ module Mongoid
49
49
  split(/,/).inject({}) do |hash, spec|
50
50
  hash.tap do |_hash|
51
51
  field, direction = spec.strip.split(/\s/)
52
- _hash[field.to_sym] = direction.to_direction
52
+ _hash[field.to_sym] = Mongoid::Criteria::Translator.to_direction(direction)
53
53
  end
54
54
  end
55
55
  end
@@ -67,16 +67,6 @@ module Mongoid
67
67
  ::String.__expr_part__(self, value, negating)
68
68
  end
69
69
 
70
- # Get the string as a sort direction.
71
- #
72
- # @example Get the string as a sort direction.
73
- # "1".to_direction
74
- #
75
- # @return [ Integer ] The direction.
76
- def to_direction
77
- self =~ /desc/i ? -1 : 1
78
- end
79
-
80
70
  module ClassMethods
81
71
 
82
72
  # Get the value as a expression.
@@ -21,16 +21,6 @@ module Mongoid
21
21
  ::String.__expr_part__(self, value, negating)
22
22
  end
23
23
 
24
- # Get the symbol as a sort direction.
25
- #
26
- # @example Get the symbol as a sort direction.
27
- # "1".to_direction
28
- #
29
- # @return [ Integer ] The direction.
30
- def to_direction
31
- to_s.to_direction
32
- end
33
-
34
24
  module ClassMethods
35
25
 
36
26
  # Adds a method on symbol as a convenience for the MongoDB operator.
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mongoid
4
+ class Criteria
5
+
6
+ # This is a helper module for translating atomic and composite
7
+ # Ruby values into corresponding query and option components.
8
+ # Originally implemented as patches to core classes, that approach
9
+ # has generally fallen into disfavor, as it bleeds too much into
10
+ # the public namespace.
11
+ #
12
+ # @api private
13
+ module Translator
14
+ extend self
15
+
16
+ # Converts the given value to a direction specification for use in
17
+ # sorting.
18
+ #
19
+ # @example Convert the value to a direction.
20
+ # Translator.to_direction(:desc)
21
+ # Translator.to_direction("1")
22
+ # Translator.to_direction(-1)
23
+ # Translator.to_direction(score: { "$meta": "textScore" })
24
+ #
25
+ # @param [ Hash | Numeric | String | Symbol ] value The value to convert.
26
+ #
27
+ # @return [ Hash | Numeric ] The direction.
28
+ def to_direction(value)
29
+ case value
30
+ when Hash then
31
+ value
32
+ when Numeric then
33
+ value
34
+ when String then
35
+ value =~ /desc/i ? -1 : 1
36
+ when Symbol then
37
+ to_direction(value.to_s)
38
+ else
39
+ raise ArgumentError, "cannot translate #{value.inspect} (#{value.class}) to a direction specification"
40
+ end
41
+ end
42
+ end
43
+
44
+ end
45
+ end
@@ -8,6 +8,7 @@ require "mongoid/criteria/modifiable"
8
8
  require "mongoid/criteria/queryable"
9
9
  require "mongoid/criteria/scopable"
10
10
  require "mongoid/criteria/options"
11
+ require "mongoid/criteria/translator"
11
12
 
12
13
  module Mongoid
13
14
 
@@ -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.
@@ -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
@@ -2,7 +2,6 @@ module Mongoid
2
2
 
3
3
  # @api private
4
4
  module Matcher
5
-
6
5
  # Extracts field values in the document at the specified key.
7
6
  #
8
7
  # The document can be a Hash or a model instance.
@@ -45,7 +44,7 @@ module Mongoid
45
44
  # If a document has hash fields, as_attributes would keep those fields
46
45
  # as Hash instances which do not offer indifferent access.
47
46
  # Convert to BSON::Document to get indifferent access on hash fields.
48
- document = BSON::Document.new(document.send(:as_attributes))
47
+ document = document.send(:as_attributes)
49
48
  end
50
49
 
51
50
  current = [document]
@@ -55,8 +54,9 @@ module Mongoid
55
54
  current.each do |doc|
56
55
  case doc
57
56
  when Hash
58
- if doc.key?(field)
59
- new << doc[field]
57
+ actual_key = find_exact_key(doc, field)
58
+ if !actual_key.nil?
59
+ new << doc[actual_key]
60
60
  end
61
61
  when Array
62
62
  if (index = field.to_i).to_s == field
@@ -66,8 +66,9 @@ module Mongoid
66
66
  end
67
67
  doc.each do |subdoc|
68
68
  if Hash === subdoc
69
- if subdoc.key?(field)
70
- new << subdoc[field]
69
+ actual_key = find_exact_key(subdoc, field)
70
+ if !actual_key.nil?
71
+ new << subdoc[actual_key]
71
72
  end
72
73
  end
73
74
  end
@@ -79,6 +80,20 @@ module Mongoid
79
80
 
80
81
  current
81
82
  end
83
+
84
+ # Indifferent string or symbol key lookup, returning the exact key.
85
+ #
86
+ # @param [ Hash ] hash The input hash.
87
+ # @param [ String | Symbol ] key The key to perform indifferent lookups with.
88
+ #
89
+ # @return [ String | Symbol | nil ] The exact key (with the correct type) that exists in the hash, or nil if the key does not exist.
90
+ module_function def find_exact_key(hash, key)
91
+ key_s = key.to_s
92
+ return key_s if hash.key?(key_s)
93
+
94
+ key_sym = key.to_sym
95
+ hash.key?(key_sym) ? key_sym : nil
96
+ end
82
97
  end
83
98
  end
84
99
 
@@ -47,18 +47,22 @@ module Mongoid
47
47
  self.class.shard_key_fields
48
48
  end
49
49
 
50
- # Returns the selector that would match the current version of this
51
- # document.
50
+ # Returns the selector that would match the defined shard keys. If
51
+ # `prefer_persisted` is false (the default), it uses the current values
52
+ # of the specified shard keys, otherwise, it will try to use whatever value
53
+ # was most recently persisted.
54
+ #
55
+ # @param [ true | false ] prefer_persisted Whether to use the current
56
+ # value of the shard key fields, or to use their most recently persisted
57
+ # values.
52
58
  #
53
59
  # @return [ Hash ] The shard key selector.
54
60
  #
55
61
  # @api private
56
- def shard_key_selector
57
- selector = {}
58
- shard_key_fields.each do |field|
59
- selector[field.to_s] = send(field)
62
+ def shard_key_selector(prefer_persisted: false)
63
+ shard_key_fields.each_with_object({}) do |field, selector|
64
+ selector[field.to_s] = shard_key_field_value(field.to_s, prefer_persisted: prefer_persisted)
60
65
  end
61
- selector
62
66
  end
63
67
 
64
68
  # Returns the selector that would match the existing version of this
@@ -72,11 +76,31 @@ module Mongoid
72
76
  #
73
77
  # @api private
74
78
  def shard_key_selector_in_db
75
- selector = {}
76
- shard_key_fields.each do |field|
77
- selector[field.to_s] = new_record? ? send(field) : attribute_was(field)
79
+ shard_key_selector(prefer_persisted: true)
80
+ end
81
+
82
+ # Returns the value for the named shard key. If the field identifies
83
+ # an embedded document, the key will be parsed and recursively evaluated.
84
+ # If `prefer_persisted` is true, the value last persisted to the database
85
+ # will be returned, regardless of what the current value of the attribute
86
+ # may be.
87
+ #
88
+ # @param [String] field The name of the field to evaluate
89
+ # @param [ true|false ] prefer_persisted Whether or not to prefer the
90
+ # persisted value over the current value.
91
+ #
92
+ # @return [ Object ] The value of the named field.
93
+ #
94
+ # @api private
95
+ def shard_key_field_value(field, prefer_persisted:)
96
+ if field.include?(".")
97
+ relation, remaining = field.split(".", 2)
98
+ send(relation)&.shard_key_field_value(remaining, prefer_persisted: prefer_persisted)
99
+ elsif prefer_persisted && !new_record?
100
+ attribute_was(field)
101
+ else
102
+ send(field)
78
103
  end
79
- selector
80
104
  end
81
105
 
82
106
  module ClassMethods
@@ -26,6 +26,10 @@ module Mongoid
26
26
  hash[key] = "[mongoid]:#{key}-stack"
27
27
  end
28
28
 
29
+ # The key storing the default value for whether or not callbacks are
30
+ # executed on documents.
31
+ EXECUTE_CALLBACKS = '[mongoid]:execute-callbacks'
32
+
29
33
  extend self
30
34
 
31
35
  # Begin entry into a named thread local stack.
@@ -346,5 +350,31 @@ module Mongoid
346
350
  session.end_session if session
347
351
  Thread.current["[mongoid]:session"] = nil
348
352
  end
353
+
354
+ # Queries whether document callbacks should be executed by default for the
355
+ # current thread.
356
+ #
357
+ # Unless otherwise indicated (by #execute_callbacks=), this will return
358
+ # true.
359
+ #
360
+ # @return [ true | false ] Whether or not document callbacks should be
361
+ # executed by default.
362
+ def execute_callbacks?
363
+ if Thread.current.key?(EXECUTE_CALLBACKS)
364
+ Thread.current[EXECUTE_CALLBACKS]
365
+ else
366
+ true
367
+ end
368
+ end
369
+
370
+ # Indicates whether document callbacks should be invoked by default for
371
+ # the current thread. Individual documents may further override the
372
+ # callback behavior, but this will be used for the default behavior.
373
+ #
374
+ # @param flag [ true | false ] Whether or not document callbacks should be
375
+ # executed by default.
376
+ def execute_callbacks=(flag)
377
+ Thread.current[EXECUTE_CALLBACKS] = flag
378
+ end
349
379
  end
350
380
  end
@@ -237,7 +237,7 @@ module Mongoid
237
237
  remove_ivar(name)
238
238
  else
239
239
  relation = send(name)
240
- relation.send(:delete_one, child)
240
+ relation._remove(child)
241
241
  end
242
242
  end
243
243
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mongoid
4
- VERSION = "8.0.3"
4
+ VERSION = "8.0.4"
5
5
  end