mongoid 8.0.2 → 8.0.4
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/lib/mongoid/association/embedded/embeds_many/proxy.rb +17 -15
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +4 -0
- data/lib/mongoid/association/referenced/has_many/proxy.rb +4 -0
- data/lib/mongoid/cacheable.rb +2 -2
- data/lib/mongoid/criteria/queryable/extensions/array.rb +1 -1
- data/lib/mongoid/criteria/queryable/extensions/hash.rb +1 -1
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +0 -8
- data/lib/mongoid/criteria/queryable/extensions/string.rb +1 -11
- data/lib/mongoid/criteria/queryable/extensions/symbol.rb +0 -10
- data/lib/mongoid/criteria/translator.rb +45 -0
- data/lib/mongoid/criteria.rb +1 -0
- data/lib/mongoid/document.rb +50 -13
- data/lib/mongoid/extensions/big_decimal.rb +4 -0
- data/lib/mongoid/extensions/float.rb +6 -2
- data/lib/mongoid/extensions/integer.rb +6 -2
- data/lib/mongoid/factory.rb +21 -8
- data/lib/mongoid/fields/localized.rb +7 -2
- data/lib/mongoid/matcher.rb +21 -6
- data/lib/mongoid/persistence_context.rb +41 -5
- data/lib/mongoid/scopable.rb +9 -7
- data/lib/mongoid/shardable.rb +35 -11
- data/lib/mongoid/threaded.rb +33 -3
- data/lib/mongoid/traversable.rb +1 -1
- data/lib/mongoid/version.rb +1 -1
- data/spec/integration/i18n_fallbacks_spec.rb +1 -17
- data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +37 -32
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +143 -197
- data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +102 -114
- data/spec/mongoid/attributes_spec.rb +2 -2
- data/spec/mongoid/cacheable_spec.rb +3 -3
- data/spec/mongoid/clients_spec.rb +25 -0
- data/spec/mongoid/contextual/memory_spec.rb +4 -5
- data/spec/mongoid/contextual/mongo_spec.rb +2 -4
- data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +0 -59
- data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +0 -59
- data/spec/mongoid/criteria/queryable/optional_spec.rb +15 -0
- data/spec/mongoid/criteria/translator_spec.rb +132 -0
- data/spec/mongoid/criteria_projection_spec.rb +0 -1
- data/spec/mongoid/criteria_spec.rb +1 -1
- data/spec/mongoid/extensions/big_decimal_spec.rb +15 -0
- data/spec/mongoid/extensions/float_spec.rb +10 -3
- data/spec/mongoid/extensions/integer_spec.rb +10 -3
- data/spec/mongoid/fields/localized_spec.rb +37 -12
- data/spec/mongoid/shardable_models.rb +14 -0
- data/spec/mongoid/shardable_spec.rb +153 -61
- data/spec/mongoid/validatable/uniqueness_spec.rb +0 -1
- data/spec/support/macros.rb +16 -0
- data.tar.gz.sig +0 -0
- metadata +651 -643
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9ab3c68fb6c373b704eb2d459a98d7a4cb99d73b87e720eabb553fcd44928d17
|
4
|
+
data.tar.gz: d0cd7fe683015dd257c48a7d0c301dd9c6972ea51be4b8199ae88b81dc45c8d6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
#
|
data/lib/mongoid/cacheable.rb
CHANGED
@@ -15,7 +15,7 @@ module Mongoid
|
|
15
15
|
# plural model name.
|
16
16
|
#
|
17
17
|
# If new_record? - will append /new
|
18
|
-
# If not - will append /id-updated_at.
|
18
|
+
# If not - will append /id-updated_at.to_formatted_s(cache_timestamp_format)
|
19
19
|
# Without updated_at - will append /id
|
20
20
|
#
|
21
21
|
# This is usually called inside a cache() block
|
@@ -26,7 +26,7 @@ module Mongoid
|
|
26
26
|
# @return [ String ] the string with or without updated_at
|
27
27
|
def cache_key
|
28
28
|
return "#{model_key}/new" if new_record?
|
29
|
-
return "#{model_key}/#{_id}-#{updated_at.utc.
|
29
|
+
return "#{model_key}/#{_id}-#{updated_at.utc.to_formatted_s(cache_timestamp_format)}" if do_or_do_not(:updated_at)
|
30
30
|
"#{model_key}/#{_id}"
|
31
31
|
end
|
32
32
|
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] =
|
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
|
data/lib/mongoid/criteria.rb
CHANGED
data/lib/mongoid/document.rb
CHANGED
@@ -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,
|
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 [
|
212
|
-
#
|
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,
|
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,
|
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 [
|
307
|
-
#
|
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,
|
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 [
|
344
|
-
#
|
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,
|
350
|
-
|
351
|
-
|
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.
|
@@ -72,10 +72,14 @@ module Mongoid
|
|
72
72
|
BSON::Decimal128.new(object)
|
73
73
|
elsif object.numeric?
|
74
74
|
BSON::Decimal128.new(object.to_s)
|
75
|
+
elsif !object.is_a?(String)
|
76
|
+
object.try(:to_d)
|
75
77
|
end
|
76
78
|
else
|
77
79
|
if object.is_a?(BSON::Decimal128) || object.numeric?
|
78
80
|
object.to_s
|
81
|
+
elsif !object.is_a?(String)
|
82
|
+
object.try(:to_d)
|
79
83
|
end
|
80
84
|
end
|
81
85
|
end
|
@@ -37,8 +37,12 @@ module Mongoid
|
|
37
37
|
# @return [ Float | nil ] The object mongoized or nil.
|
38
38
|
def mongoize(object)
|
39
39
|
return if object.blank?
|
40
|
-
if object.
|
41
|
-
object.
|
40
|
+
if object.is_a?(String)
|
41
|
+
if object.numeric?
|
42
|
+
object.to_f
|
43
|
+
end
|
44
|
+
else
|
45
|
+
object.try(:to_f)
|
42
46
|
end
|
43
47
|
end
|
44
48
|
alias :demongoize :mongoize
|
@@ -45,8 +45,12 @@ module Mongoid
|
|
45
45
|
# @return [ Integer | nil ] The object mongoized or nil.
|
46
46
|
def mongoize(object)
|
47
47
|
return if object.blank?
|
48
|
-
if object.
|
49
|
-
object.
|
48
|
+
if object.is_a?(String)
|
49
|
+
if object.numeric?
|
50
|
+
object.to_i
|
51
|
+
end
|
52
|
+
else
|
53
|
+
object.try(:to_i)
|
50
54
|
end
|
51
55
|
end
|
52
56
|
alias :demongoize :mongoize
|
data/lib/mongoid/factory.rb
CHANGED
@@ -25,27 +25,40 @@ module Mongoid
|
|
25
25
|
#
|
26
26
|
# @return [ Document ] The instantiated document.
|
27
27
|
def build(klass, attributes = nil)
|
28
|
-
|
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 [
|
36
|
-
#
|
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,
|
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,
|
59
|
+
type.construct_document(attributes, options)
|
47
60
|
else
|
48
|
-
klass.construct_document(attributes,
|
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
|
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:
|
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
|
@@ -14,7 +14,9 @@ module Mongoid
|
|
14
14
|
#
|
15
15
|
# @return [ Object ] The value for the current locale.
|
16
16
|
def demongoize(object)
|
17
|
-
if object
|
17
|
+
return if object.nil?
|
18
|
+
case object
|
19
|
+
when Hash
|
18
20
|
type.demongoize(lookup(object))
|
19
21
|
end
|
20
22
|
end
|
@@ -76,7 +78,10 @@ module Mongoid
|
|
76
78
|
end
|
77
79
|
return value unless value.nil?
|
78
80
|
if fallbacks? && ::I18n.respond_to?(:fallbacks)
|
79
|
-
|
81
|
+
fallback_key = ::I18n.fallbacks[locale].find do |loc|
|
82
|
+
object.key?(loc.to_s) || object.key?(loc)
|
83
|
+
end
|
84
|
+
object[fallback_key.to_s] || object[fallback_key]
|
80
85
|
end
|
81
86
|
end
|
82
87
|
end
|
data/lib/mongoid/matcher.rb
CHANGED
@@ -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 =
|
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
|
-
|
59
|
-
|
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
|
-
|
70
|
-
|
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
|
|
@@ -189,8 +189,7 @@ module Mongoid
|
|
189
189
|
#
|
190
190
|
# @return [ Mongoid::PersistenceContext ] The persistence context for the object.
|
191
191
|
def set(object, options_or_context)
|
192
|
-
|
193
|
-
existing_context = Thread.current[key]
|
192
|
+
existing_context = get_context(object)
|
194
193
|
existing_options = if existing_context
|
195
194
|
existing_context.options
|
196
195
|
else
|
@@ -201,7 +200,7 @@ module Mongoid
|
|
201
200
|
end
|
202
201
|
new_options = existing_options.merge(options_or_context)
|
203
202
|
context = PersistenceContext.new(object, new_options)
|
204
|
-
|
203
|
+
store_context(object, context)
|
205
204
|
end
|
206
205
|
|
207
206
|
# Get the persistence context for a particular class or model instance.
|
@@ -213,7 +212,7 @@ module Mongoid
|
|
213
212
|
#
|
214
213
|
# @return [ Mongoid::PersistenceContext ] The persistence context for the object.
|
215
214
|
def get(object)
|
216
|
-
|
215
|
+
get_context(object)
|
217
216
|
end
|
218
217
|
|
219
218
|
# Clear the persistence context for a particular class or model instance.
|
@@ -232,7 +231,44 @@ module Mongoid
|
|
232
231
|
end
|
233
232
|
end
|
234
233
|
ensure
|
235
|
-
|
234
|
+
store_context(object, original_context)
|
235
|
+
end
|
236
|
+
|
237
|
+
private
|
238
|
+
|
239
|
+
# Key to store persistence contexts in the thread local storage.
|
240
|
+
#
|
241
|
+
# @api private
|
242
|
+
PERSISTENCE_CONTEXT_KEY = :"[mongoid]:persistence_context"
|
243
|
+
|
244
|
+
# Get the persistence context for a given object from the thread local
|
245
|
+
# storage.
|
246
|
+
#
|
247
|
+
# @param [ Object ] object Object to get the persistance context for.
|
248
|
+
#
|
249
|
+
# @return [ Mongoid::PersistenceContext | nil ] The persistence context
|
250
|
+
# for the object if previously stored, otherwise nil.
|
251
|
+
#
|
252
|
+
# @api private
|
253
|
+
def get_context(object)
|
254
|
+
Thread.current[PERSISTENCE_CONTEXT_KEY] ||= {}
|
255
|
+
Thread.current[PERSISTENCE_CONTEXT_KEY][object.object_id]
|
256
|
+
end
|
257
|
+
|
258
|
+
# Store persistence context for a given object in the thread local
|
259
|
+
# storage.
|
260
|
+
#
|
261
|
+
# @param [ Object ] object Object to store the persistance context for.
|
262
|
+
# @param [ Mongoid::PersistenceContext ] context Context to store
|
263
|
+
#
|
264
|
+
# @api private
|
265
|
+
def store_context(object, context)
|
266
|
+
if context.nil?
|
267
|
+
Thread.current[PERSISTENCE_CONTEXT_KEY]&.delete(object.object_id)
|
268
|
+
else
|
269
|
+
Thread.current[PERSISTENCE_CONTEXT_KEY] ||= {}
|
270
|
+
Thread.current[PERSISTENCE_CONTEXT_KEY][object.object_id] = context
|
271
|
+
end
|
236
272
|
end
|
237
273
|
end
|
238
274
|
end
|
data/lib/mongoid/scopable.rb
CHANGED
@@ -168,7 +168,9 @@ module Mongoid
|
|
168
168
|
# Band.where(name: "Depeche Mode")
|
169
169
|
# end
|
170
170
|
#
|
171
|
-
# @note This will force the default scope to be removed
|
171
|
+
# @note This will force the default scope to be removed, but will not
|
172
|
+
# remove scopes declared with ``.with_scope``. This will be changed
|
173
|
+
# in Mongoid 9.
|
172
174
|
#
|
173
175
|
# @return [ Criteria | Object ] The unscoped criteria or result of the
|
174
176
|
# block.
|
@@ -249,12 +251,12 @@ module Mongoid
|
|
249
251
|
if Mongoid.scope_overwrite_exception
|
250
252
|
raise Errors::ScopeOverwrite.new(self.name, name)
|
251
253
|
else
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
254
|
+
Mongoid.logger.warn(
|
255
|
+
"Creating scope :#{name} which conflicts with #{self.name}.#{name}. " +
|
256
|
+
"Calls to `Mongoid::Criteria##{name}` will delegate to " +
|
257
|
+
"`Mongoid::Criteria##{name}` for criteria with klass #{self.name} " +
|
258
|
+
"and will ignore the declared scope."
|
259
|
+
)
|
258
260
|
end
|
259
261
|
end
|
260
262
|
end
|