mongoid 9.0.2 → 9.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/mongoid/clients/options.rb +14 -1
- data/lib/mongoid/clients/sessions.rb +1 -0
- data/lib/mongoid/matcher.rb +15 -1
- data/lib/mongoid/persistence_context.rb +13 -8
- data/lib/mongoid/railties/controller_runtime.rb +2 -2
- data/lib/mongoid/serializable.rb +7 -7
- data/lib/mongoid/threaded.rb +96 -28
- data/lib/mongoid/timestamps/timeless.rb +4 -1
- data/lib/mongoid/touchable.rb +1 -1
- data/lib/mongoid/traversable.rb +6 -2
- data/lib/mongoid/validatable/associated.rb +5 -2
- data/lib/mongoid/version.rb +1 -1
- data/spec/integration/active_job_spec.rb +24 -20
- data/spec/integration/app_spec.rb +9 -1
- data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +4 -0
- data/spec/mongoid/clients/options_spec.rb +127 -2
- data/spec/mongoid/interceptable_spec.rb +12 -0
- data/spec/mongoid/interceptable_spec_models.rb +12 -0
- data/spec/mongoid/persistence_context_spec.rb +31 -0
- data/spec/mongoid/railties/bson_object_id_serializer_spec.rb +18 -12
- data/spec/mongoid/threaded_spec.rb +24 -5
- data/spec/mongoid/validatable/associated_spec.rb +14 -4
- data/spec/rails/controller_extension/controller_runtime_spec.rb +14 -14
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 421d53636b0e90abcfa52bf637229588d434ff73f14574b1d316b72009f7236b
|
4
|
+
data.tar.gz: fafa07a7cc9b17de0abbb140ca3d021e3041bfe00b67a424c81f6c15018e607d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d4f2011d1f85178a8693d653518f06e7ad55c1363958e3577f80d040e3986b595bdcaade0e71696ff762e008c195ee23b4579458708bb9e916f7ddfa8e3b9352
|
7
|
+
data.tar.gz: 8b981e1bc4e904085ecedfe459d31c91d06ed353ba0ceef3d67865ea195f31a36539284246b54537fc5af8b54eafcf1a60415eb88c4850d7cdf3af378d449206
|
@@ -86,7 +86,7 @@ module Mongoid
|
|
86
86
|
else
|
87
87
|
PersistenceContext.get(self) ||
|
88
88
|
PersistenceContext.get(self.class) ||
|
89
|
-
PersistenceContext.new(self.class,
|
89
|
+
PersistenceContext.new(self.class, default_storage_options)
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
@@ -112,6 +112,19 @@ module Mongoid
|
|
112
112
|
|
113
113
|
private
|
114
114
|
|
115
|
+
def default_storage_options
|
116
|
+
# Nothing is overridden, we use either the default storage_options
|
117
|
+
# or storage_options defined for the document class.
|
118
|
+
return storage_options if Threaded.client_override.nil? && Threaded.database_override.nil?
|
119
|
+
|
120
|
+
storage_options.tap do |opts|
|
121
|
+
# Globally overridden client replaces client defined for the document class.
|
122
|
+
opts[:client] = Threaded.client_override unless Threaded.client_override.nil?
|
123
|
+
# Globally overridden database replaces database defined for the document class.
|
124
|
+
opts[:database] = Threaded.database_override unless Threaded.database_override.nil?
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
115
128
|
def set_persistence_context(options_or_context)
|
116
129
|
PersistenceContext.set(self, options_or_context)
|
117
130
|
end
|
data/lib/mongoid/matcher.rb
CHANGED
@@ -39,11 +39,25 @@ module Mongoid
|
|
39
39
|
# from and behaves identically to association traversal for the purposes
|
40
40
|
# of, for example, subsequent array element retrieval.
|
41
41
|
#
|
42
|
-
# @param [ Document | Hash ] document The document to extract from.
|
42
|
+
# @param [ Document | Hash | String ] document The document to extract from.
|
43
43
|
# @param [ String ] key The key path to extract.
|
44
44
|
#
|
45
45
|
# @return [ Object | Array ] Field value or values.
|
46
46
|
module_function def extract_attribute(document, key)
|
47
|
+
# The matcher system will wind up sending atomic values to this as well,
|
48
|
+
# when attepting to match more complex types. If anything other than a
|
49
|
+
# Document or a Hash is given, we'll short-circuit the logic and just
|
50
|
+
# return an empty array.
|
51
|
+
return [] unless document.is_a?(Hash) || document.is_a?(Document)
|
52
|
+
|
53
|
+
# Performance optimization; if the key does not include a '.' character,
|
54
|
+
# it must reference an immediate attribute of the document.
|
55
|
+
unless key.include?('.')
|
56
|
+
hash = document.respond_to?(:attributes) ? document.attributes : document
|
57
|
+
key = find_exact_key(hash, key)
|
58
|
+
return key ? [ hash[key] ] : []
|
59
|
+
end
|
60
|
+
|
47
61
|
if document.respond_to?(:as_attributes, true)
|
48
62
|
# If a document has hash fields, as_attributes would keep those fields
|
49
63
|
# as Hash instances which do not offer indifferent access.
|
@@ -117,12 +117,15 @@ module Mongoid
|
|
117
117
|
def client
|
118
118
|
@client ||= begin
|
119
119
|
client = Clients.with_name(client_name)
|
120
|
+
options = client_options
|
121
|
+
|
120
122
|
if database_name_option
|
121
123
|
client = client.use(database_name)
|
124
|
+
options = options.except(:database, 'database')
|
122
125
|
end
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
+
|
127
|
+
client = client.with(options) unless options.empty?
|
128
|
+
|
126
129
|
client
|
127
130
|
end
|
128
131
|
end
|
@@ -282,6 +285,10 @@ module Mongoid
|
|
282
285
|
# @api private
|
283
286
|
PERSISTENCE_CONTEXT_KEY = :"[mongoid]:persistence_context"
|
284
287
|
|
288
|
+
def context_store
|
289
|
+
Threaded.get(PERSISTENCE_CONTEXT_KEY) { {} }
|
290
|
+
end
|
291
|
+
|
285
292
|
# Get the persistence context for a given object from the thread local
|
286
293
|
# storage.
|
287
294
|
#
|
@@ -292,8 +299,7 @@ module Mongoid
|
|
292
299
|
#
|
293
300
|
# @api private
|
294
301
|
def get_context(object)
|
295
|
-
|
296
|
-
Thread.current[PERSISTENCE_CONTEXT_KEY][object.object_id]
|
302
|
+
context_store[object.object_id]
|
297
303
|
end
|
298
304
|
|
299
305
|
# Store persistence context for a given object in the thread local
|
@@ -305,10 +311,9 @@ module Mongoid
|
|
305
311
|
# @api private
|
306
312
|
def store_context(object, context)
|
307
313
|
if context.nil?
|
308
|
-
|
314
|
+
context_store.delete(object.object_id)
|
309
315
|
else
|
310
|
-
|
311
|
-
Thread.current[PERSISTENCE_CONTEXT_KEY][object.object_id] = context
|
316
|
+
context_store[object.object_id] = context
|
312
317
|
end
|
313
318
|
end
|
314
319
|
end
|
@@ -78,7 +78,7 @@ module Mongoid
|
|
78
78
|
#
|
79
79
|
# @return [ Integer ] The runtime value.
|
80
80
|
def self.runtime
|
81
|
-
|
81
|
+
Threaded.get(VARIABLE_NAME) { 0 }
|
82
82
|
end
|
83
83
|
|
84
84
|
# Set the runtime value on the current thread.
|
@@ -87,7 +87,7 @@ module Mongoid
|
|
87
87
|
#
|
88
88
|
# @return [ Integer ] The runtime value.
|
89
89
|
def self.runtime= value
|
90
|
-
|
90
|
+
Threaded.set(VARIABLE_NAME, value)
|
91
91
|
end
|
92
92
|
|
93
93
|
# Reset the runtime value to zero the current thread.
|
data/lib/mongoid/serializable.rb
CHANGED
@@ -13,13 +13,13 @@ module Mongoid
|
|
13
13
|
included do
|
14
14
|
|
15
15
|
class << self
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
16
|
+
def include_root_in_json
|
17
|
+
@include_root_in_json.nil? ? ::Mongoid.include_root_in_json : @include_root_in_json
|
18
|
+
end
|
19
|
+
|
20
|
+
def include_root_in_json=(new_value)
|
21
|
+
@include_root_in_json = new_value
|
22
|
+
end
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
data/lib/mongoid/threaded.rb
CHANGED
@@ -18,6 +18,7 @@ module Mongoid
|
|
18
18
|
CURRENT_SCOPE_KEY = '[mongoid]:current-scope'
|
19
19
|
|
20
20
|
AUTOSAVES_KEY = '[mongoid]:autosaves'
|
21
|
+
|
21
22
|
VALIDATIONS_KEY = '[mongoid]:validations'
|
22
23
|
|
23
24
|
STACK_KEYS = Hash.new do |hash, key|
|
@@ -36,6 +37,75 @@ module Mongoid
|
|
36
37
|
|
37
38
|
extend self
|
38
39
|
|
40
|
+
# Queries the thread-local variable with the given name. If a block is
|
41
|
+
# given, and the variable does not already exist, the return value of the
|
42
|
+
# block will be set as the value of the variable before returning it.
|
43
|
+
#
|
44
|
+
# It is very important that applications (and espcially Mongoid)
|
45
|
+
# use this method instead of Thread#[], since Thread#[] is actually for
|
46
|
+
# fiber-local variables, and Mongoid uses Fibers as an implementation
|
47
|
+
# detail in some callbacks. Putting thread-local state in a fiber-local
|
48
|
+
# store will result in the state being invisible when relevant callbacks are
|
49
|
+
# run in a different fiber.
|
50
|
+
#
|
51
|
+
# Affected callbacks are cascading callbacks on embedded children.
|
52
|
+
#
|
53
|
+
# @param [ String | Symbol ] key the name of the variable to query
|
54
|
+
# @param [ Proc ] default an optional block that must return the default
|
55
|
+
# (initial) value of this variable.
|
56
|
+
#
|
57
|
+
# @return [ Object | nil ] the value of the queried variable, or nil if
|
58
|
+
# it is not set and no default was given.
|
59
|
+
def get(key, &default)
|
60
|
+
result = Thread.current.thread_variable_get(key)
|
61
|
+
|
62
|
+
if result.nil? && default
|
63
|
+
result = yield
|
64
|
+
set(key, result)
|
65
|
+
end
|
66
|
+
|
67
|
+
result
|
68
|
+
end
|
69
|
+
|
70
|
+
# Sets a thread-local variable with the given name to the given value.
|
71
|
+
# See #get for a discussion of why this method is necessary, and why
|
72
|
+
# Thread#[]= should be avoided in cascading callbacks on embedded children.
|
73
|
+
#
|
74
|
+
# @param [ String | Symbol ] key the name of the variable to set.
|
75
|
+
# @param [ Object | nil ] value the value of the variable to set (or `nil`
|
76
|
+
# if you wish to unset the variable)
|
77
|
+
def set(key, value)
|
78
|
+
Thread.current.thread_variable_set(key, value)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Removes the named variable from thread-local storage.
|
82
|
+
#
|
83
|
+
# @param [ String | Symbol ] key the name of the variable to remove.
|
84
|
+
def delete(key)
|
85
|
+
set(key, nil)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Queries the presence of a named variable in thread-local storage.
|
89
|
+
#
|
90
|
+
# @param [ String | Symbol ] key the name of the variable to query.
|
91
|
+
#
|
92
|
+
# @return [ true | false ] whether the given variable is present or not.
|
93
|
+
def has?(key)
|
94
|
+
# Here we have a classic example of JRuby not behaving like MRI. In
|
95
|
+
# MRI, if you set a thread variable to nil, it removes it from the list
|
96
|
+
# and subsequent calls to thread_variable?(key) will return false. Not
|
97
|
+
# so with JRuby. Once set, you cannot unset the thread variable.
|
98
|
+
#
|
99
|
+
# However, because setting a variable to nil is supposed to remove it,
|
100
|
+
# we can assume a nil-valued variable doesn't actually exist.
|
101
|
+
|
102
|
+
# So, instead of this:
|
103
|
+
# Thread.current.thread_variable?(key)
|
104
|
+
|
105
|
+
# We have to do this:
|
106
|
+
!get(key).nil?
|
107
|
+
end
|
108
|
+
|
39
109
|
# Begin entry into a named thread local stack.
|
40
110
|
#
|
41
111
|
# @example Begin entry into the stack.
|
@@ -55,7 +125,7 @@ module Mongoid
|
|
55
125
|
#
|
56
126
|
# @return [ String | Symbol ] The override.
|
57
127
|
def database_override
|
58
|
-
|
128
|
+
get(DATABASE_OVERRIDE_KEY)
|
59
129
|
end
|
60
130
|
|
61
131
|
# Set the global database override.
|
@@ -67,7 +137,7 @@ module Mongoid
|
|
67
137
|
#
|
68
138
|
# @return [ String | Symbol ] The override.
|
69
139
|
def database_override=(name)
|
70
|
-
|
140
|
+
set(DATABASE_OVERRIDE_KEY, name)
|
71
141
|
end
|
72
142
|
|
73
143
|
# Are in the middle of executing the named stack
|
@@ -103,7 +173,7 @@ module Mongoid
|
|
103
173
|
#
|
104
174
|
# @return [ Array ] The stack.
|
105
175
|
def stack(name)
|
106
|
-
|
176
|
+
get(STACK_KEYS[name]) { [] }
|
107
177
|
end
|
108
178
|
|
109
179
|
# Begin autosaving a document on the current thread.
|
@@ -177,7 +247,7 @@ module Mongoid
|
|
177
247
|
#
|
178
248
|
# @return [ String | Symbol ] The override.
|
179
249
|
def client_override
|
180
|
-
|
250
|
+
get(CLIENT_OVERRIDE_KEY)
|
181
251
|
end
|
182
252
|
|
183
253
|
# Set the global client override.
|
@@ -189,7 +259,7 @@ module Mongoid
|
|
189
259
|
#
|
190
260
|
# @return [ String | Symbol ] The override.
|
191
261
|
def client_override=(name)
|
192
|
-
|
262
|
+
set(CLIENT_OVERRIDE_KEY, name)
|
193
263
|
end
|
194
264
|
|
195
265
|
# Get the current Mongoid scope.
|
@@ -202,12 +272,12 @@ module Mongoid
|
|
202
272
|
#
|
203
273
|
# @return [ Criteria ] The scope.
|
204
274
|
def current_scope(klass = nil)
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
]
|
275
|
+
current_scope = get(CURRENT_SCOPE_KEY)
|
276
|
+
|
277
|
+
if klass && current_scope.respond_to?(:keys)
|
278
|
+
current_scope[current_scope.keys.find { |k| k <= klass }]
|
209
279
|
else
|
210
|
-
|
280
|
+
current_scope
|
211
281
|
end
|
212
282
|
end
|
213
283
|
|
@@ -220,7 +290,7 @@ module Mongoid
|
|
220
290
|
#
|
221
291
|
# @return [ Criteria ] The scope.
|
222
292
|
def current_scope=(scope)
|
223
|
-
|
293
|
+
set(CURRENT_SCOPE_KEY, scope)
|
224
294
|
end
|
225
295
|
|
226
296
|
# Set the current Mongoid scope. Safe for multi-model scope chaining.
|
@@ -236,8 +306,8 @@ module Mongoid
|
|
236
306
|
if scope.nil?
|
237
307
|
unset_current_scope(klass)
|
238
308
|
else
|
239
|
-
|
240
|
-
|
309
|
+
current_scope = get(CURRENT_SCOPE_KEY) { {} }
|
310
|
+
current_scope[klass] = scope
|
241
311
|
end
|
242
312
|
end
|
243
313
|
|
@@ -284,7 +354,7 @@ module Mongoid
|
|
284
354
|
#
|
285
355
|
# @return [ Hash ] The current autosaves.
|
286
356
|
def autosaves
|
287
|
-
|
357
|
+
get(AUTOSAVES_KEY) { {} }
|
288
358
|
end
|
289
359
|
|
290
360
|
# Get all validations on the current thread.
|
@@ -294,7 +364,7 @@ module Mongoid
|
|
294
364
|
#
|
295
365
|
# @return [ Hash ] The current validations.
|
296
366
|
def validations
|
297
|
-
|
367
|
+
get(VALIDATIONS_KEY) { {} }
|
298
368
|
end
|
299
369
|
|
300
370
|
# Get all autosaves on the current thread for the class.
|
@@ -376,9 +446,7 @@ module Mongoid
|
|
376
446
|
# @return [ Set<Mongoid::Document> ] Collection of modified documents before
|
377
447
|
# it was cleared.
|
378
448
|
def clear_modified_documents(session)
|
379
|
-
modified_documents[
|
380
|
-
ensure
|
381
|
-
modified_documents[session].clear
|
449
|
+
modified_documents.delete(session) || []
|
382
450
|
end
|
383
451
|
|
384
452
|
# Queries whether document callbacks should be executed by default for the
|
@@ -390,8 +458,8 @@ module Mongoid
|
|
390
458
|
# @return [ true | false ] Whether or not document callbacks should be
|
391
459
|
# executed by default.
|
392
460
|
def execute_callbacks?
|
393
|
-
if
|
394
|
-
|
461
|
+
if has?(EXECUTE_CALLBACKS)
|
462
|
+
get(EXECUTE_CALLBACKS)
|
395
463
|
else
|
396
464
|
true
|
397
465
|
end
|
@@ -404,7 +472,7 @@ module Mongoid
|
|
404
472
|
# @param flag [ true | false ] Whether or not document callbacks should be
|
405
473
|
# executed by default.
|
406
474
|
def execute_callbacks=(flag)
|
407
|
-
|
475
|
+
set(EXECUTE_CALLBACKS, flag)
|
408
476
|
end
|
409
477
|
|
410
478
|
# Returns the thread store of sessions.
|
@@ -413,7 +481,7 @@ module Mongoid
|
|
413
481
|
#
|
414
482
|
# @api private
|
415
483
|
def sessions
|
416
|
-
|
484
|
+
get(SESSIONS_KEY) { {}.compare_by_identity }
|
417
485
|
end
|
418
486
|
|
419
487
|
# Returns the thread store of modified documents.
|
@@ -423,9 +491,7 @@ module Mongoid
|
|
423
491
|
#
|
424
492
|
# @api private
|
425
493
|
def modified_documents
|
426
|
-
|
427
|
-
h[k] = Set.new
|
428
|
-
end
|
494
|
+
get(MODIFIED_DOCUMENTS_KEY) { Hash.new { |h, k| h[k] = Set.new } }
|
429
495
|
end
|
430
496
|
|
431
497
|
private
|
@@ -435,10 +501,12 @@ module Mongoid
|
|
435
501
|
#
|
436
502
|
# @param klass [ Class ] the class to remove from the current scope.
|
437
503
|
def unset_current_scope(klass)
|
438
|
-
return unless
|
504
|
+
return unless has?(CURRENT_SCOPE_KEY)
|
505
|
+
|
506
|
+
scope = get(CURRENT_SCOPE_KEY)
|
507
|
+
scope.delete(klass)
|
439
508
|
|
440
|
-
|
441
|
-
Thread.current[CURRENT_SCOPE_KEY] = nil if Thread.current[CURRENT_SCOPE_KEY].empty?
|
509
|
+
delete(CURRENT_SCOPE_KEY) if scope.empty?
|
442
510
|
end
|
443
511
|
end
|
444
512
|
end
|
@@ -46,6 +46,9 @@ module Mongoid
|
|
46
46
|
class << self
|
47
47
|
extend Forwardable
|
48
48
|
|
49
|
+
# The key to use to store the timeless table
|
50
|
+
TIMELESS_TABLE_KEY = '[mongoid]:timeless'
|
51
|
+
|
49
52
|
# Returns the in-memory thread cache of classes
|
50
53
|
# for which to skip timestamping.
|
51
54
|
#
|
@@ -53,7 +56,7 @@ module Mongoid
|
|
53
56
|
#
|
54
57
|
# @api private
|
55
58
|
def timeless_table
|
56
|
-
|
59
|
+
Threaded.get(TIMELESS_TABLE_KEY) { Hash.new }
|
57
60
|
end
|
58
61
|
|
59
62
|
def_delegators :timeless_table, :[]=, :[]
|
data/lib/mongoid/touchable.rb
CHANGED
@@ -195,7 +195,7 @@ module Mongoid
|
|
195
195
|
# @return [ Hash ] The hash that contains touch callback suppression
|
196
196
|
# statuses
|
197
197
|
def touch_callback_statuses
|
198
|
-
|
198
|
+
Threaded.get(SUPPRESS_TOUCH_CALLBACKS_KEY) { {} }
|
199
199
|
end
|
200
200
|
|
201
201
|
# Define the method that will get called for touching belongs_to
|
data/lib/mongoid/traversable.rb
CHANGED
@@ -105,7 +105,11 @@ module Mongoid
|
|
105
105
|
if value
|
106
106
|
Mongoid::Fields::Validators::Macro.validate_field_name(self, value)
|
107
107
|
value = value.to_s
|
108
|
-
|
108
|
+
if defined?(::ActiveSupport::ClassAttribute)
|
109
|
+
::ActiveSupport::ClassAttribute.redefine(self, 'discriminator_key', value)
|
110
|
+
else
|
111
|
+
super
|
112
|
+
end
|
109
113
|
else
|
110
114
|
# When discriminator key is set to nil, replace the class's definition
|
111
115
|
# of the discriminator key reader (provided by class_attribute earlier)
|
@@ -119,7 +123,7 @@ module Mongoid
|
|
119
123
|
# an existing field.
|
120
124
|
# This condition also checks if the class has any descendants, because
|
121
125
|
# if it doesn't then it doesn't need a discriminator key.
|
122
|
-
return
|
126
|
+
return if fields.key?(discriminator_key) || descendants.empty?
|
123
127
|
|
124
128
|
default_proc = -> { self.class.discriminator_value }
|
125
129
|
field(discriminator_key, default: default_proc, type: String)
|
@@ -70,13 +70,16 @@ module Mongoid
|
|
70
70
|
# Now, treating the target as an array, look at each element
|
71
71
|
# and see if it is valid, but only if it has already been
|
72
72
|
# persisted, or changed, and hasn't been flagged for destroy.
|
73
|
-
|
73
|
+
#
|
74
|
+
# use map.all? instead of just all?, because all? will do short-circuit
|
75
|
+
# evaluation and terminate on the first failed validation.
|
76
|
+
list.map do |value|
|
74
77
|
if value && !value.flagged_for_destroy? && (!value.persisted? || value.changed?)
|
75
78
|
value.validated? ? true : value.valid?
|
76
79
|
else
|
77
80
|
true
|
78
81
|
end
|
79
|
-
end
|
82
|
+
end.all?
|
80
83
|
end
|
81
84
|
|
82
85
|
document.errors.add(attribute, :invalid) unless valid
|
data/lib/mongoid/version.rb
CHANGED
@@ -2,31 +2,35 @@
|
|
2
2
|
# rubocop:todo all
|
3
3
|
|
4
4
|
require 'spec_helper'
|
5
|
-
|
6
|
-
require '
|
5
|
+
begin
|
6
|
+
require 'active_job'
|
7
|
+
require 'mongoid/railties/bson_object_id_serializer'
|
7
8
|
|
8
|
-
describe 'ActiveJob Serialization' do
|
9
|
-
|
9
|
+
describe 'ActiveJob Serialization' do
|
10
|
+
skip unless defined?(ActiveJob)
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
class TestBsonObjectIdSerializerJob < ActiveJob::Base
|
13
|
+
def perform(*args)
|
14
|
+
args
|
15
|
+
end
|
14
16
|
end
|
15
|
-
end
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
let(:band) do
|
19
|
+
Band.create!
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
before do
|
23
|
+
ActiveJob::Serializers.add_serializers(
|
24
|
+
[::Mongoid::Railties::ActiveJobSerializers::BsonObjectIdSerializer]
|
25
|
+
)
|
26
|
+
end
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
it 'serializes and deserializes BSON::ObjectId' do
|
29
|
+
expect do
|
30
|
+
TestBsonObjectIdSerializerJob.perform_later(band.id)
|
31
|
+
end.not_to raise_error
|
32
|
+
end
|
31
33
|
end
|
34
|
+
rescue LoadError
|
35
|
+
RSpec.context.skip 'This test requires active_job'
|
32
36
|
end
|
@@ -36,6 +36,8 @@ describe 'Mongoid application tests' do
|
|
36
36
|
context 'demo application' do
|
37
37
|
context 'sinatra' do
|
38
38
|
it 'runs' do
|
39
|
+
skip 'https://jira.mongodb.org/browse/MONGOID-5826'
|
40
|
+
|
39
41
|
clone_application(
|
40
42
|
'https://github.com/mongoid/mongoid-demo',
|
41
43
|
subdir: 'sinatra-minimal',
|
@@ -55,6 +57,8 @@ describe 'Mongoid application tests' do
|
|
55
57
|
|
56
58
|
context 'rails-api' do
|
57
59
|
it 'runs' do
|
60
|
+
skip 'https://jira.mongodb.org/browse/MONGOID-5826'
|
61
|
+
|
58
62
|
clone_application(
|
59
63
|
'https://github.com/mongoid/mongoid-demo',
|
60
64
|
subdir: 'rails-api',
|
@@ -172,7 +176,7 @@ describe 'Mongoid application tests' do
|
|
172
176
|
if (rails_version = SpecConfig.instance.rails_version) == 'master'
|
173
177
|
else
|
174
178
|
check_call(%w(gem list))
|
175
|
-
check_call(%w(gem install rails --no-document -v) + ["~> #{rails_version}.0"])
|
179
|
+
check_call(%w(gem install rails --no-document --force -v) + ["~> #{rails_version}.0"])
|
176
180
|
end
|
177
181
|
end
|
178
182
|
|
@@ -319,6 +323,10 @@ describe 'Mongoid application tests' do
|
|
319
323
|
end
|
320
324
|
|
321
325
|
def adjust_rails_defaults(rails_version: SpecConfig.instance.rails_version)
|
326
|
+
if !rails_version.match?(/^\d+\.\d+$/)
|
327
|
+
# This must be pre-release version, we trim it
|
328
|
+
rails_version = rails_version.split('.')[0..1].join('.')
|
329
|
+
end
|
322
330
|
if File.exist?('config/application.rb')
|
323
331
|
lines = IO.readlines('config/application.rb')
|
324
332
|
lines.each do |line|
|
@@ -751,6 +751,10 @@ describe Mongoid::Association::Referenced::BelongsTo::Proxy do
|
|
751
751
|
person.save!
|
752
752
|
end
|
753
753
|
|
754
|
+
# NOTE: there as a bad interdependency here, with the auto_save_spec.rb
|
755
|
+
# file. If auto_save_spec.rb runs before this, the following specs fail
|
756
|
+
# with "undefined method `nullify' for an instance of Person".
|
757
|
+
|
754
758
|
context "when parent exists" do
|
755
759
|
|
756
760
|
context "when child is destroyed" do
|
@@ -27,7 +27,7 @@ describe Mongoid::Clients::Options, retry: 3 do
|
|
27
27
|
let(:options) { { database: 'other' } }
|
28
28
|
|
29
29
|
it 'sets the options on the client' do
|
30
|
-
expect(persistence_context.client.options['database']).to eq(options[:database])
|
30
|
+
expect(persistence_context.client.options['database'].to_s).to eq(options[:database].to_s)
|
31
31
|
end
|
32
32
|
|
33
33
|
it 'does not set the options on class level' do
|
@@ -319,7 +319,7 @@ describe Mongoid::Clients::Options, retry: 3 do
|
|
319
319
|
end
|
320
320
|
|
321
321
|
it 'sets the options on the client' do
|
322
|
-
expect(persistence_context.client.options['database']).to eq(options[:database])
|
322
|
+
expect(persistence_context.client.options['database'].to_s).to eq(options[:database].to_s)
|
323
323
|
end
|
324
324
|
|
325
325
|
it 'does not set the options on instance level' do
|
@@ -522,4 +522,129 @@ describe Mongoid::Clients::Options, retry: 3 do
|
|
522
522
|
end
|
523
523
|
end
|
524
524
|
end
|
525
|
+
|
526
|
+
context 'with global overrides' do
|
527
|
+
let(:default_subscriber) do
|
528
|
+
Mrss::EventSubscriber.new
|
529
|
+
end
|
530
|
+
|
531
|
+
let(:override_subscriber) do
|
532
|
+
Mrss::EventSubscriber.new
|
533
|
+
end
|
534
|
+
|
535
|
+
context 'when global client is overridden' do
|
536
|
+
before do
|
537
|
+
Mongoid.clients['override_client'] = { hosts: SpecConfig.instance.addresses, database: 'default_override_database' }
|
538
|
+
Mongoid.override_client('override_client')
|
539
|
+
Mongoid.client(:default).subscribe(Mongo::Monitoring::COMMAND, default_subscriber)
|
540
|
+
Mongoid.client('override_client').subscribe(Mongo::Monitoring::COMMAND, override_subscriber)
|
541
|
+
end
|
542
|
+
|
543
|
+
after do
|
544
|
+
Mongoid.client(:default).unsubscribe(Mongo::Monitoring::COMMAND, default_subscriber)
|
545
|
+
Mongoid.client('override_client').unsubscribe(Mongo::Monitoring::COMMAND, override_subscriber)
|
546
|
+
Mongoid.override_client(nil)
|
547
|
+
Mongoid.clients['override_client'] = nil
|
548
|
+
end
|
549
|
+
|
550
|
+
it 'uses the overridden client for create' do
|
551
|
+
Minim.create!
|
552
|
+
|
553
|
+
expect(override_subscriber.single_command_started_event('insert').database_name).to eq('default_override_database')
|
554
|
+
expect(default_subscriber.command_started_events('insert')).to be_empty
|
555
|
+
end
|
556
|
+
|
557
|
+
it 'uses the overridden client for queries' do
|
558
|
+
Minim.where(name: 'Dmitry').to_a
|
559
|
+
|
560
|
+
expect(override_subscriber.single_command_started_event('find').database_name).to eq('default_override_database')
|
561
|
+
expect(default_subscriber.command_started_events('find')).to be_empty
|
562
|
+
end
|
563
|
+
|
564
|
+
context 'when the client is set on the model level' do
|
565
|
+
let(:model_level_subscriber) do
|
566
|
+
Mrss::EventSubscriber.new
|
567
|
+
end
|
568
|
+
|
569
|
+
around(:example) do |example|
|
570
|
+
opts = Minim.storage_options
|
571
|
+
Minim.storage_options = Minim.storage_options.merge( { client: 'model_level_client' } )
|
572
|
+
Mongoid.clients['model_level_client'] = { hosts: SpecConfig.instance.addresses, database: 'model_level_database' }
|
573
|
+
Mongoid.client('model_level_client').subscribe(Mongo::Monitoring::COMMAND, override_subscriber)
|
574
|
+
example.run
|
575
|
+
Mongoid.client('model_level_client').unsubscribe(Mongo::Monitoring::COMMAND, override_subscriber)
|
576
|
+
Mongoid.clients['model_level_client'] = nil
|
577
|
+
Minim.storage_options = opts
|
578
|
+
end
|
579
|
+
|
580
|
+
# This behaviour is consistent with 8.x
|
581
|
+
it 'uses the overridden client for create' do
|
582
|
+
Minim.create!
|
583
|
+
|
584
|
+
expect(override_subscriber.single_command_started_event('insert').database_name).to eq('default_override_database')
|
585
|
+
expect(default_subscriber.command_started_events('insert')).to be_empty
|
586
|
+
expect(model_level_subscriber.command_started_events('insert')).to be_empty
|
587
|
+
end
|
588
|
+
|
589
|
+
# This behaviour is consistent with 8.x
|
590
|
+
it 'uses the overridden client for queries' do
|
591
|
+
Minim.where(name: 'Dmitry').to_a
|
592
|
+
|
593
|
+
expect(override_subscriber.single_command_started_event('find').database_name).to eq('default_override_database')
|
594
|
+
expect(default_subscriber.command_started_events('find')).to be_empty
|
595
|
+
expect(model_level_subscriber.command_started_events('find')).to be_empty
|
596
|
+
end
|
597
|
+
end
|
598
|
+
end
|
599
|
+
|
600
|
+
context 'when global database is overridden' do
|
601
|
+
before do
|
602
|
+
Mongoid.override_database('override_database')
|
603
|
+
Mongoid.client(:default).subscribe(Mongo::Monitoring::COMMAND, default_subscriber)
|
604
|
+
end
|
605
|
+
|
606
|
+
after do
|
607
|
+
Mongoid.client(:default).unsubscribe(Mongo::Monitoring::COMMAND, default_subscriber)
|
608
|
+
Mongoid.override_database(nil)
|
609
|
+
end
|
610
|
+
|
611
|
+
it 'uses the overridden database for create' do
|
612
|
+
Minim.create!
|
613
|
+
|
614
|
+
expect(default_subscriber.single_command_started_event('insert').database_name).to eq('override_database')
|
615
|
+
end
|
616
|
+
|
617
|
+
it 'uses the overridden database for queries' do
|
618
|
+
Minim.where(name: 'Dmitry').to_a
|
619
|
+
|
620
|
+
expect(default_subscriber.single_command_started_event('find').database_name).to eq('override_database')
|
621
|
+
end
|
622
|
+
|
623
|
+
context 'when the database is set on the model level' do
|
624
|
+
around(:example) do |example|
|
625
|
+
opts = Minim.storage_options
|
626
|
+
Minim.storage_options = Minim.storage_options.merge( { database: 'model_level_database' } )
|
627
|
+
Mongoid.clients['model_level_client'] = { hosts: SpecConfig.instance.addresses, database: 'model_level_database' }
|
628
|
+
Mongoid.client(:default).subscribe(Mongo::Monitoring::COMMAND, default_subscriber)
|
629
|
+
example.run
|
630
|
+
Mongoid.client(:default).unsubscribe(Mongo::Monitoring::COMMAND, default_subscriber)
|
631
|
+
Mongoid.clients['model_level_client'] = nil
|
632
|
+
Minim.storage_options = opts
|
633
|
+
end
|
634
|
+
|
635
|
+
# This behaviour is consistent with 8.x
|
636
|
+
it 'uses the overridden database for create' do
|
637
|
+
Minim.create!
|
638
|
+
|
639
|
+
expect(default_subscriber.single_command_started_event('insert').database_name).to eq('override_database')
|
640
|
+
end
|
641
|
+
|
642
|
+
it 'uses the overridden database for queries' do
|
643
|
+
Minim.where(name: 'Dmitry').to_a
|
644
|
+
|
645
|
+
expect(default_subscriber.single_command_started_event('find').database_name).to eq('override_database')
|
646
|
+
end
|
647
|
+
end
|
648
|
+
end
|
649
|
+
end
|
525
650
|
end
|
@@ -1789,6 +1789,12 @@ describe Mongoid::Interceptable do
|
|
1789
1789
|
context 'with around callbacks' do
|
1790
1790
|
config_override :around_callbacks_for_embeds, true
|
1791
1791
|
|
1792
|
+
after do
|
1793
|
+
Mongoid::Threaded.stack('interceptable').clear
|
1794
|
+
end
|
1795
|
+
|
1796
|
+
let(:stack) { Mongoid::Threaded.stack('interceptable') }
|
1797
|
+
|
1792
1798
|
let(:expected) do
|
1793
1799
|
[
|
1794
1800
|
[InterceptableSpec::CbCascadedChild, :before_validation],
|
@@ -1824,6 +1830,12 @@ describe Mongoid::Interceptable do
|
|
1824
1830
|
parent.save!
|
1825
1831
|
expect(registry.calls).to eq expected
|
1826
1832
|
end
|
1833
|
+
|
1834
|
+
it 'shows that cascaded callbacks can access Mongoid state' do
|
1835
|
+
expect(stack).to be_empty
|
1836
|
+
parent.save!
|
1837
|
+
expect(stack).not_to be_empty
|
1838
|
+
end
|
1827
1839
|
end
|
1828
1840
|
|
1829
1841
|
context 'without around callbacks' do
|
@@ -224,7 +224,19 @@ module InterceptableSpec
|
|
224
224
|
|
225
225
|
attr_accessor :callback_registry
|
226
226
|
|
227
|
+
before_save :test_mongoid_state
|
228
|
+
|
227
229
|
include CallbackTracking
|
230
|
+
|
231
|
+
private
|
232
|
+
|
233
|
+
# Helps test that cascading child callbacks have access to the Mongoid
|
234
|
+
# state objects; if the implementation uses fiber-local (instead of truly
|
235
|
+
# thread-local) variables, the related tests will fail because the
|
236
|
+
# cascading child callbacks use fibers to linearize the recursion.
|
237
|
+
def test_mongoid_state
|
238
|
+
Mongoid::Threaded.stack('interceptable').push(self)
|
239
|
+
end
|
228
240
|
end
|
229
241
|
end
|
230
242
|
|
@@ -536,6 +536,20 @@ describe Mongoid::PersistenceContext do
|
|
536
536
|
end
|
537
537
|
end
|
538
538
|
end
|
539
|
+
|
540
|
+
context 'when the database is specified as a proc' do
|
541
|
+
let(:options) { { database: ->{ 'other' } } }
|
542
|
+
|
543
|
+
after { persistence_context.client.close }
|
544
|
+
|
545
|
+
it 'evaluates the proc' do
|
546
|
+
expect(persistence_context.database_name).to eq(:other)
|
547
|
+
end
|
548
|
+
|
549
|
+
it 'does not pass the proc to the client' do
|
550
|
+
expect(persistence_context.client.database.name).to eq('other')
|
551
|
+
end
|
552
|
+
end
|
539
553
|
end
|
540
554
|
|
541
555
|
describe '#client' do
|
@@ -608,6 +622,23 @@ describe Mongoid::PersistenceContext do
|
|
608
622
|
end
|
609
623
|
end
|
610
624
|
|
625
|
+
context 'when the client is set as a proc in the storage options' do
|
626
|
+
let(:options) { {} }
|
627
|
+
|
628
|
+
before do
|
629
|
+
Band.store_in client: ->{ :alternative }
|
630
|
+
end
|
631
|
+
|
632
|
+
after do
|
633
|
+
persistence_context.client.close
|
634
|
+
Band.store_in client: nil
|
635
|
+
end
|
636
|
+
|
637
|
+
it 'uses the client option' do
|
638
|
+
expect(persistence_context.client).to eq(Mongoid::Clients.with_name(:alternative))
|
639
|
+
end
|
640
|
+
end
|
641
|
+
|
611
642
|
context 'when there is no client option set' do
|
612
643
|
|
613
644
|
let(:options) do
|
@@ -2,23 +2,29 @@
|
|
2
2
|
# rubocop:todo all
|
3
3
|
|
4
4
|
require 'spec_helper'
|
5
|
-
require 'active_job'
|
6
|
-
require 'mongoid/railties/bson_object_id_serializer'
|
7
5
|
|
8
|
-
|
6
|
+
begin
|
7
|
+
require 'active_job'
|
8
|
+
require 'mongoid/railties/bson_object_id_serializer'
|
9
9
|
|
10
|
-
let(:serializer) { Mongoid::Railties::ActiveJobSerializers::BsonObjectIdSerializer.instance }
|
11
|
-
let(:object_id) { BSON::ObjectId.new }
|
12
10
|
|
13
|
-
describe '
|
14
|
-
|
15
|
-
|
11
|
+
describe 'Mongoid::Railties::ActiveJobSerializers::BsonObjectIdSerializer' do
|
12
|
+
|
13
|
+
let(:serializer) { Mongoid::Railties::ActiveJobSerializers::BsonObjectIdSerializer.instance }
|
14
|
+
let(:object_id) { BSON::ObjectId.new }
|
15
|
+
|
16
|
+
describe '#serialize' do
|
17
|
+
it 'serializes BSON::ObjectId' do
|
18
|
+
expect(serializer.serialize(object_id)).to be_a(String)
|
19
|
+
end
|
16
20
|
end
|
17
|
-
end
|
18
21
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
+
describe '#deserialize' do
|
23
|
+
it 'deserializes BSON::ObjectId' do
|
24
|
+
expect(serializer.deserialize(serializer.serialize(object_id))).to eq(object_id)
|
25
|
+
end
|
22
26
|
end
|
23
27
|
end
|
28
|
+
rescue LoadError
|
29
|
+
RSpec.context.skip 'This test requires active_job'
|
24
30
|
end
|
@@ -36,11 +36,11 @@ describe Mongoid::Threaded do
|
|
36
36
|
context "when the stack has elements" do
|
37
37
|
|
38
38
|
before do
|
39
|
-
|
39
|
+
described_class.stack('load').push(true)
|
40
40
|
end
|
41
41
|
|
42
42
|
after do
|
43
|
-
|
43
|
+
described_class.stack('load').clear
|
44
44
|
end
|
45
45
|
|
46
46
|
it "returns true" do
|
@@ -51,7 +51,7 @@ describe Mongoid::Threaded do
|
|
51
51
|
context "when the stack has no elements" do
|
52
52
|
|
53
53
|
before do
|
54
|
-
|
54
|
+
described_class.stack('load').clear
|
55
55
|
end
|
56
56
|
|
57
57
|
it "returns false" do
|
@@ -76,7 +76,7 @@ describe Mongoid::Threaded do
|
|
76
76
|
context "when a stack has been initialized" do
|
77
77
|
|
78
78
|
before do
|
79
|
-
|
79
|
+
described_class.stack('load').push(true)
|
80
80
|
end
|
81
81
|
|
82
82
|
let(:loading) do
|
@@ -84,7 +84,7 @@ describe Mongoid::Threaded do
|
|
84
84
|
end
|
85
85
|
|
86
86
|
after do
|
87
|
-
|
87
|
+
described_class.stack('load').clear
|
88
88
|
end
|
89
89
|
|
90
90
|
it "returns the stack" do
|
@@ -341,4 +341,23 @@ describe Mongoid::Threaded do
|
|
341
341
|
end
|
342
342
|
end
|
343
343
|
end
|
344
|
+
|
345
|
+
describe '#clear_modified_documents' do
|
346
|
+
let(:session) do
|
347
|
+
double(Mongo::Session).tap do |session|
|
348
|
+
allow(session).to receive(:in_transaction?).and_return(true)
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
context 'when there are modified documents' do
|
353
|
+
before do
|
354
|
+
described_class.add_modified_document(session, Minim.new)
|
355
|
+
described_class.clear_modified_documents(session)
|
356
|
+
end
|
357
|
+
|
358
|
+
it 'removes the documents and keys' do
|
359
|
+
expect(described_class.modified_documents).to be_empty
|
360
|
+
end
|
361
|
+
end
|
362
|
+
end
|
344
363
|
end
|
@@ -38,12 +38,18 @@ describe Mongoid::Validatable::AssociatedValidator do
|
|
38
38
|
User.new(name: "test")
|
39
39
|
end
|
40
40
|
|
41
|
-
let(:
|
41
|
+
let(:description1) do
|
42
|
+
Description.new
|
43
|
+
end
|
44
|
+
|
45
|
+
let(:description2) do
|
42
46
|
Description.new
|
43
47
|
end
|
44
48
|
|
45
49
|
before do
|
46
|
-
user.descriptions <<
|
50
|
+
user.descriptions << description1
|
51
|
+
user.descriptions << description2
|
52
|
+
user.valid?
|
47
53
|
end
|
48
54
|
|
49
55
|
it "only validates the parent once" do
|
@@ -51,12 +57,16 @@ describe Mongoid::Validatable::AssociatedValidator do
|
|
51
57
|
end
|
52
58
|
|
53
59
|
it "adds the errors from the relation" do
|
54
|
-
user.valid?
|
55
60
|
expect(user.errors[:descriptions]).to_not be_nil
|
56
61
|
end
|
57
62
|
|
63
|
+
it 'reports all failed validations' do
|
64
|
+
errors = user.descriptions.flat_map { |d| d.errors[:details] }
|
65
|
+
expect(errors.length).to be == 2
|
66
|
+
end
|
67
|
+
|
58
68
|
it "only validates the child once" do
|
59
|
-
expect(
|
69
|
+
expect(description1).to_not be_valid
|
60
70
|
end
|
61
71
|
end
|
62
72
|
|
@@ -5,11 +5,11 @@ require "spec_helper"
|
|
5
5
|
require "mongoid/railties/controller_runtime"
|
6
6
|
|
7
7
|
describe "Mongoid::Railties::ControllerRuntime" do
|
8
|
-
|
9
|
-
|
8
|
+
CONTROLLER_RUNTIME = Mongoid::Railties::ControllerRuntime
|
9
|
+
COLLECTOR = CONTROLLER_RUNTIME::Collector
|
10
10
|
|
11
|
-
def set_metric
|
12
|
-
|
11
|
+
def set_metric(value)
|
12
|
+
Mongoid::Threaded.set(COLLECTOR::VARIABLE_NAME, value)
|
13
13
|
end
|
14
14
|
|
15
15
|
def clear_metric!
|
@@ -20,30 +20,30 @@ describe "Mongoid::Railties::ControllerRuntime" do
|
|
20
20
|
|
21
21
|
it "stores the metric in thread-safe manner" do
|
22
22
|
clear_metric!
|
23
|
-
expect(
|
23
|
+
expect(COLLECTOR.runtime).to eq(0)
|
24
24
|
set_metric 42
|
25
|
-
expect(
|
25
|
+
expect(COLLECTOR.runtime).to eq(42)
|
26
26
|
end
|
27
27
|
|
28
28
|
it "sets metric on both succeeded and failed" do
|
29
|
-
instance =
|
29
|
+
instance = COLLECTOR.new
|
30
30
|
event_payload = OpenStruct.new duration: 42
|
31
31
|
|
32
32
|
clear_metric!
|
33
33
|
instance.succeeded event_payload
|
34
|
-
expect(
|
34
|
+
expect(COLLECTOR.runtime).to eq(42000)
|
35
35
|
|
36
36
|
clear_metric!
|
37
37
|
instance.failed event_payload
|
38
|
-
expect(
|
38
|
+
expect(COLLECTOR.runtime).to eq(42000)
|
39
39
|
end
|
40
40
|
|
41
41
|
it "resets the metric and returns the value" do
|
42
42
|
clear_metric!
|
43
|
-
expect(
|
43
|
+
expect(COLLECTOR.reset_runtime).to eq(0)
|
44
44
|
set_metric 42
|
45
|
-
expect(
|
46
|
-
expect(
|
45
|
+
expect(COLLECTOR.reset_runtime).to eq(42)
|
46
|
+
expect(COLLECTOR.runtime).to eq(0)
|
47
47
|
end
|
48
48
|
|
49
49
|
end
|
@@ -67,7 +67,7 @@ describe "Mongoid::Railties::ControllerRuntime" do
|
|
67
67
|
end
|
68
68
|
|
69
69
|
controller_class = Class.new reference_controller_class do
|
70
|
-
include
|
70
|
+
include CONTROLLER_RUNTIME::ControllerExtension
|
71
71
|
end
|
72
72
|
|
73
73
|
let(:controller){ controller_class.new }
|
@@ -75,7 +75,7 @@ describe "Mongoid::Railties::ControllerRuntime" do
|
|
75
75
|
it "resets the metric before each action" do
|
76
76
|
set_metric 42
|
77
77
|
controller.send(:process_action, 'foo')
|
78
|
-
expect(
|
78
|
+
expect(COLLECTOR.runtime).to be(0)
|
79
79
|
expect(controller.instance_variable_get "@process_action").to be(true)
|
80
80
|
end
|
81
81
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 9.0.
|
4
|
+
version: 9.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- The MongoDB Ruby Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-11-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
version: '5.1'
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '
|
22
|
+
version: '8.1'
|
23
23
|
- - "!="
|
24
24
|
- !ruby/object:Gem::Version
|
25
25
|
version: 7.0.0
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: '5.1'
|
33
33
|
- - "<"
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: '
|
35
|
+
version: '8.1'
|
36
36
|
- - "!="
|
37
37
|
- !ruby/object:Gem::Version
|
38
38
|
version: 7.0.0
|