mongoid 8.0.13 → 8.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +3 -3
- data/README.md +3 -3
- data/Rakefile +17 -66
- data/lib/config/locales/en.yml +46 -40
- data/lib/mongoid/association/accessors.rb +3 -7
- data/lib/mongoid/association/builders.rb +1 -1
- data/lib/mongoid/association/depending.rb +4 -8
- data/lib/mongoid/association/eager_loadable.rb +0 -3
- data/lib/mongoid/association/embedded/batchable.rb +2 -2
- data/lib/mongoid/association/embedded/embedded_in/buildable.rb +2 -2
- data/lib/mongoid/association/embedded/embedded_in/proxy.rb +2 -1
- data/lib/mongoid/association/embedded/embeds_many/buildable.rb +3 -2
- data/lib/mongoid/association/embedded/embeds_many/proxy.rb +6 -6
- data/lib/mongoid/association/embedded/embeds_one/buildable.rb +1 -1
- data/lib/mongoid/association/embedded/embeds_one/proxy.rb +2 -2
- data/lib/mongoid/association/macros.rb +0 -6
- data/lib/mongoid/association/nested/many.rb +3 -38
- data/lib/mongoid/association/nested/nested_buildable.rb +0 -14
- data/lib/mongoid/association/nested/one.rb +40 -2
- data/lib/mongoid/association/proxy.rb +1 -1
- data/lib/mongoid/association/referenced/counter_cache.rb +2 -2
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +1 -1
- data/lib/mongoid/association/referenced/has_many/enumerable.rb +6 -23
- data/lib/mongoid/association/referenced/has_many/proxy.rb +4 -103
- data/lib/mongoid/association/reflections.rb +2 -2
- data/lib/mongoid/atomic.rb +7 -16
- data/lib/mongoid/attributes/dynamic.rb +1 -1
- data/lib/mongoid/attributes/nested.rb +2 -2
- data/lib/mongoid/attributes/processing.rb +5 -29
- data/lib/mongoid/attributes/projector.rb +1 -1
- data/lib/mongoid/attributes/readonly.rb +1 -1
- data/lib/mongoid/attributes.rb +8 -2
- data/lib/mongoid/changeable.rb +107 -5
- data/lib/mongoid/clients/factory.rb +0 -4
- data/lib/mongoid/clients/storage_options.rb +2 -5
- data/lib/mongoid/clients/validators/storage.rb +1 -13
- data/lib/mongoid/collection_configurable.rb +58 -0
- data/lib/mongoid/composable.rb +2 -0
- data/lib/mongoid/config/defaults.rb +60 -0
- data/lib/mongoid/config/options.rb +0 -3
- data/lib/mongoid/config/validators/async_query_executor.rb +24 -0
- data/lib/mongoid/config/validators.rb +1 -0
- data/lib/mongoid/config.rb +88 -89
- data/lib/mongoid/contextual/aggregable/memory.rb +2 -5
- data/lib/mongoid/contextual/atomic.rb +1 -1
- data/lib/mongoid/contextual/memory.rb +240 -51
- data/lib/mongoid/contextual/mongo/documents_loader.rb +177 -0
- data/lib/mongoid/contextual/mongo.rb +370 -133
- data/lib/mongoid/contextual/none.rb +162 -7
- data/lib/mongoid/contextual.rb +12 -0
- data/lib/mongoid/criteria/findable.rb +2 -2
- data/lib/mongoid/criteria/includable.rb +4 -3
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -15
- data/lib/mongoid/criteria/queryable/key.rb +1 -1
- data/lib/mongoid/criteria/queryable/mergeable.rb +1 -13
- data/lib/mongoid/criteria/queryable/optional.rb +8 -8
- data/lib/mongoid/criteria/queryable/selectable.rb +43 -121
- data/lib/mongoid/criteria/queryable/selector.rb +1 -1
- data/lib/mongoid/criteria/queryable/storable.rb +1 -1
- data/lib/mongoid/criteria.rb +6 -5
- data/lib/mongoid/deprecable.rb +1 -2
- data/lib/mongoid/deprecation.rb +3 -3
- data/lib/mongoid/document.rb +1 -8
- data/lib/mongoid/errors/create_collection_failure.rb +33 -0
- data/lib/mongoid/errors/drop_collection_failure.rb +27 -0
- data/lib/mongoid/errors/immutable_attribute.rb +26 -0
- data/lib/mongoid/errors/invalid_async_query_executor.rb +25 -0
- data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +22 -0
- data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
- data/lib/mongoid/errors.rb +4 -2
- data/lib/mongoid/extensions/hash.rb +3 -51
- data/lib/mongoid/extensions/object.rb +2 -2
- data/lib/mongoid/extensions/time.rb +2 -0
- data/lib/mongoid/fields/localized.rb +10 -0
- data/lib/mongoid/fields/standard.rb +10 -0
- data/lib/mongoid/fields.rb +59 -35
- data/lib/mongoid/findable.rb +27 -3
- data/lib/mongoid/interceptable.rb +6 -116
- data/lib/mongoid/matchable.rb +1 -6
- data/lib/mongoid/matcher/eq_impl.rb +1 -1
- data/lib/mongoid/matcher/eq_impl_with_regexp.rb +5 -3
- data/lib/mongoid/matcher/regex.rb +9 -8
- data/lib/mongoid/matcher/type.rb +1 -1
- data/lib/mongoid/matcher.rb +0 -1
- data/lib/mongoid/persistable/creatable.rb +1 -0
- data/lib/mongoid/persistable/deletable.rb +1 -1
- data/lib/mongoid/persistable/savable.rb +13 -1
- data/lib/mongoid/persistable/unsettable.rb +2 -2
- data/lib/mongoid/persistable/updatable.rb +51 -1
- data/lib/mongoid/persistable/upsertable.rb +20 -1
- data/lib/mongoid/persistable.rb +3 -0
- data/lib/mongoid/query_cache.rb +5 -1
- data/lib/mongoid/railties/database.rake +7 -2
- data/lib/mongoid/reloadable.rb +5 -3
- data/lib/mongoid/stateful.rb +22 -1
- data/lib/mongoid/tasks/database.rake +12 -0
- data/lib/mongoid/tasks/database.rb +20 -0
- data/lib/mongoid/threaded.rb +0 -3
- data/lib/mongoid/timestamps/created.rb +1 -8
- data/lib/mongoid/traversable.rb +0 -12
- data/lib/mongoid/utils.rb +22 -0
- data/lib/mongoid/validatable/associated.rb +17 -98
- data/lib/mongoid/validatable/macros.rb +5 -20
- data/lib/mongoid/validatable.rb +4 -10
- data/lib/mongoid/version.rb +1 -5
- data/lib/mongoid/warnings.rb +17 -2
- data/lib/mongoid.rb +16 -3
- data/spec/integration/app_spec.rb +2 -20
- data/spec/integration/associations/embeds_one_spec.rb +5 -25
- data/spec/integration/associations/has_and_belongs_to_many_spec.rb +0 -55
- data/spec/integration/callbacks_spec.rb +99 -12
- data/spec/integration/discriminator_key_spec.rb +4 -5
- data/spec/integration/dots_and_dollars_spec.rb +2 -12
- data/spec/integration/i18n_fallbacks_spec.rb +3 -2
- data/spec/integration/matcher_operator_data/regex.yml +0 -21
- data/spec/mongoid/association/eager_spec.rb +2 -24
- data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +27 -0
- data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +20 -25
- data/spec/mongoid/association/embedded/embeds_many_models.rb +1 -0
- data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +0 -4
- data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +15 -2
- data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -18
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +42 -103
- data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +9 -195
- data/spec/mongoid/association/syncable_spec.rb +1 -1
- data/spec/mongoid/attributes/nested_spec.rb +10 -204
- data/spec/mongoid/attributes_spec.rb +3 -33
- data/spec/mongoid/changeable_spec.rb +299 -24
- data/spec/mongoid/clients/factory_spec.rb +0 -30
- data/spec/mongoid/clients_spec.rb +122 -13
- data/spec/mongoid/collection_configurable_spec.rb +158 -0
- data/spec/mongoid/config/defaults_spec.rb +160 -0
- data/spec/mongoid/config_spec.rb +154 -27
- data/spec/mongoid/contextual/aggregable/memory_spec.rb +0 -91
- data/spec/mongoid/contextual/memory_spec.rb +332 -253
- data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +187 -0
- data/spec/mongoid/contextual/mongo_spec.rb +1009 -125
- data/spec/mongoid/contextual/none_spec.rb +49 -2
- data/spec/mongoid/copyable_spec.rb +2 -10
- data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +4 -10
- data/spec/mongoid/criteria/queryable/options_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +419 -2
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +0 -235
- data/spec/mongoid/criteria/queryable/selector_spec.rb +3 -76
- data/spec/mongoid/criteria/queryable/storable_spec.rb +0 -72
- data/spec/mongoid/criteria_projection_spec.rb +1 -4
- data/spec/mongoid/criteria_spec.rb +5 -11
- data/spec/mongoid/document_spec.rb +0 -27
- data/spec/mongoid/errors/readonly_document_spec.rb +2 -2
- data/spec/mongoid/extensions/hash_spec.rb +3 -239
- data/spec/mongoid/extensions/time_spec.rb +8 -43
- data/spec/mongoid/extensions/time_with_zone_spec.rb +7 -52
- data/spec/mongoid/fields/localized_spec.rb +46 -28
- data/spec/mongoid/fields_spec.rb +136 -77
- data/spec/mongoid/findable_spec.rb +391 -34
- data/spec/mongoid/indexable_spec.rb +16 -10
- data/spec/mongoid/interceptable_spec.rb +153 -442
- data/spec/mongoid/interceptable_spec_models.rb +111 -51
- data/spec/mongoid/persistable/deletable_spec.rb +26 -6
- data/spec/mongoid/persistable/destroyable_spec.rb +26 -6
- data/spec/mongoid/persistable/incrementable_spec.rb +37 -0
- data/spec/mongoid/persistable/logical_spec.rb +37 -0
- data/spec/mongoid/persistable/poppable_spec.rb +36 -0
- data/spec/mongoid/persistable/pullable_spec.rb +72 -0
- data/spec/mongoid/persistable/pushable_spec.rb +72 -0
- data/spec/mongoid/persistable/renamable_spec.rb +36 -0
- data/spec/mongoid/persistable/savable_spec.rb +96 -0
- data/spec/mongoid/persistable/settable_spec.rb +37 -0
- data/spec/mongoid/persistable/unsettable_spec.rb +36 -0
- data/spec/mongoid/persistable/updatable_spec.rb +20 -28
- data/spec/mongoid/persistable/upsertable_spec.rb +80 -6
- data/spec/mongoid/persistence_context_spec.rb +7 -57
- data/spec/mongoid/query_cache_spec.rb +56 -61
- data/spec/mongoid/reloadable_spec.rb +24 -28
- data/spec/mongoid/scopable_spec.rb +70 -0
- data/spec/mongoid/serializable_spec.rb +23 -44
- data/spec/mongoid/stateful_spec.rb +122 -8
- data/spec/mongoid/tasks/database_rake_spec.rb +74 -0
- data/spec/mongoid/tasks/database_spec.rb +127 -0
- data/spec/mongoid/timestamps/created_spec.rb +0 -23
- data/spec/mongoid/timestamps_spec.rb +9 -11
- data/spec/mongoid/touchable_spec.rb +277 -5
- data/spec/mongoid/touchable_spec_models.rb +3 -1
- data/spec/mongoid/traversable_spec.rb +9 -24
- data/spec/mongoid/validatable/associated_spec.rb +34 -27
- data/spec/mongoid/validatable/numericality_spec.rb +0 -16
- data/spec/mongoid/validatable/uniqueness_spec.rb +2 -3
- data/spec/mongoid_spec.rb +36 -10
- data/spec/shared/lib/mrss/docker_runner.rb +1 -1
- data/spec/shared/lib/mrss/server_version_registry.rb +1 -1
- data/spec/shared/lib/mrss/spec_organizer.rb +3 -32
- data/spec/shared/share/Dockerfile.erb +85 -15
- data/spec/shared/shlib/distro.sh +0 -10
- data/spec/shared/shlib/server.sh +27 -34
- data/spec/shared/shlib/set_env.sh +68 -9
- data/spec/spec_helper.rb +5 -0
- data/spec/support/expectations.rb +17 -20
- data/spec/support/immutable_ids.rb +118 -0
- data/spec/support/macros.rb +47 -15
- data/spec/support/models/artist.rb +0 -1
- data/spec/support/models/band.rb +1 -0
- data/spec/support/models/building.rb +2 -0
- data/spec/support/models/name.rb +0 -10
- data/spec/support/models/person.rb +0 -1
- data/spec/support/models/product.rb +1 -0
- data.tar.gz.sig +0 -0
- metadata +715 -671
- metadata.gz.sig +2 -0
- data/lib/mongoid/errors/in_memory_regexp_timeout.rb +0 -26
- data/lib/mongoid/field_readable.rb +0 -70
- data/lib/mongoid/matcher/regexp_budget.rb +0 -389
- data/lib/mongoid/validatable/numericality.rb +0 -19
- data/spec/integration/matcher_regexp_timeout_spec.rb +0 -215
- data/spec/integration/query_operator_guard_spec.rb +0 -89
- data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -61
- data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -61
- data/spec/mongoid/matcher/regexp_budget_spec.rb +0 -570
- data/spec/shared/CANDIDATE.md +0 -28
- data/spec/shared/lib/mrss/release/candidate.rb +0 -281
- data/spec/shared/lib/mrss/release/product_data.rb +0 -144
- data/spec/shared/lib/tasks/candidate.rake +0 -64
- data/spec/support/models/purse.rb +0 -9
|
@@ -80,15 +80,24 @@ module Mongoid
|
|
|
80
80
|
# @example Do any documents exist in the null context.
|
|
81
81
|
# context.exists?
|
|
82
82
|
#
|
|
83
|
+
# @example Do any documents exist for given _id.
|
|
84
|
+
# context.exists?(BSON::ObjectId(...))
|
|
85
|
+
#
|
|
86
|
+
# @example Do any documents exist for given conditions.
|
|
87
|
+
# context.exists?(name: "...")
|
|
88
|
+
#
|
|
89
|
+
# @param [ Hash | Object | false ] id_or_conditions an _id to
|
|
90
|
+
# search for, a hash of conditions, nil or false.
|
|
91
|
+
#
|
|
83
92
|
# @return [ false ] Always false.
|
|
84
|
-
def exists
|
|
93
|
+
def exists?(id_or_conditions = :none); false; end
|
|
85
94
|
|
|
86
95
|
# Pluck the field values in null context.
|
|
87
96
|
#
|
|
88
97
|
# @example Get the values for null context.
|
|
89
98
|
# context.pluck(:name)
|
|
90
99
|
#
|
|
91
|
-
# @param [ String | Symbol ] *_fields Field(s) to pluck.
|
|
100
|
+
# @param [ [ String | Symbol ]... ] *_fields Field(s) to pluck.
|
|
92
101
|
#
|
|
93
102
|
# @return [ Array ] An empty Array.
|
|
94
103
|
def pluck(*_fields)
|
|
@@ -100,9 +109,9 @@ module Mongoid
|
|
|
100
109
|
# @example Get the value for null context.
|
|
101
110
|
# context.pick(:name)
|
|
102
111
|
#
|
|
103
|
-
# @param [ String | Symbol ] *_fields Field
|
|
112
|
+
# @param [ [ String | Symbol ]... ] *_fields Field(s) to pick.
|
|
104
113
|
#
|
|
105
|
-
# @return [ nil ] Always
|
|
114
|
+
# @return [ nil ] Always return nil.
|
|
106
115
|
def pick(*_fields)
|
|
107
116
|
nil
|
|
108
117
|
end
|
|
@@ -136,11 +145,21 @@ module Mongoid
|
|
|
136
145
|
#
|
|
137
146
|
# @param [ Integer ] limit The number of documents to return.
|
|
138
147
|
#
|
|
139
|
-
# @return [ nil ]
|
|
148
|
+
# @return [ [] | nil ] Empty array or nil.
|
|
140
149
|
def first(limit = nil)
|
|
141
150
|
[] unless limit.nil?
|
|
142
151
|
end
|
|
143
152
|
|
|
153
|
+
# Always raises an error.
|
|
154
|
+
#
|
|
155
|
+
# @example Get the first document in null context.
|
|
156
|
+
# context.first!
|
|
157
|
+
#
|
|
158
|
+
# @raises [ Mongoid::Errors::DocumentNotFound ] always raises.
|
|
159
|
+
def first!
|
|
160
|
+
raise_document_not_found_error
|
|
161
|
+
end
|
|
162
|
+
|
|
144
163
|
# Always returns nil.
|
|
145
164
|
#
|
|
146
165
|
# @example Get the last document in null context.
|
|
@@ -148,11 +167,21 @@ module Mongoid
|
|
|
148
167
|
#
|
|
149
168
|
# @param [ Integer ] limit The number of documents to return.
|
|
150
169
|
#
|
|
151
|
-
# @return [ nil ]
|
|
170
|
+
# @return [ [] | nil ] Empty array or nil.
|
|
152
171
|
def last(limit = nil)
|
|
153
172
|
[] unless limit.nil?
|
|
154
173
|
end
|
|
155
174
|
|
|
175
|
+
# Always raises an error.
|
|
176
|
+
#
|
|
177
|
+
# @example Get the last document in null context.
|
|
178
|
+
# context.last!
|
|
179
|
+
#
|
|
180
|
+
# @raises [ Mongoid::Errors::DocumentNotFound ] always raises.
|
|
181
|
+
def last!
|
|
182
|
+
raise_document_not_found_error
|
|
183
|
+
end
|
|
184
|
+
|
|
156
185
|
# Returns nil or empty array.
|
|
157
186
|
#
|
|
158
187
|
# @example Take a document in null context.
|
|
@@ -172,7 +201,127 @@ module Mongoid
|
|
|
172
201
|
#
|
|
173
202
|
# @raises [ Mongoid::Errors::DocumentNotFound ] always raises.
|
|
174
203
|
def take!
|
|
175
|
-
|
|
204
|
+
raise_document_not_found_error
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# Always returns nil.
|
|
208
|
+
#
|
|
209
|
+
# @example Get the second document in null context.
|
|
210
|
+
# context.second
|
|
211
|
+
#
|
|
212
|
+
# @return [ nil ] Always nil.
|
|
213
|
+
def second
|
|
214
|
+
nil
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# Always raises an error.
|
|
218
|
+
#
|
|
219
|
+
# @example Get the second document in null context.
|
|
220
|
+
# context.second!
|
|
221
|
+
#
|
|
222
|
+
# @raises [ Mongoid::Errors::DocumentNotFound ] always raises.
|
|
223
|
+
def second!
|
|
224
|
+
raise_document_not_found_error
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# Always returns nil.
|
|
228
|
+
#
|
|
229
|
+
# @example Get the third document in null context.
|
|
230
|
+
# context.third
|
|
231
|
+
#
|
|
232
|
+
# @return [ nil ] Always nil.
|
|
233
|
+
def third
|
|
234
|
+
nil
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
# Always raises an error.
|
|
238
|
+
#
|
|
239
|
+
# @example Get the third document in null context.
|
|
240
|
+
# context.third!
|
|
241
|
+
#
|
|
242
|
+
# @raises [ Mongoid::Errors::DocumentNotFound ] always raises.
|
|
243
|
+
def third!
|
|
244
|
+
raise_document_not_found_error
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
# Always returns nil.
|
|
248
|
+
#
|
|
249
|
+
# @example Get the fourth document in null context.
|
|
250
|
+
# context.fourth
|
|
251
|
+
#
|
|
252
|
+
# @return [ nil ] Always nil.
|
|
253
|
+
def fourth
|
|
254
|
+
nil
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
# Always raises an error.
|
|
258
|
+
#
|
|
259
|
+
# @example Get the fourth document in null context.
|
|
260
|
+
# context.fourth!
|
|
261
|
+
#
|
|
262
|
+
# @raises [ Mongoid::Errors::DocumentNotFound ] always raises.
|
|
263
|
+
def fourth!
|
|
264
|
+
raise_document_not_found_error
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
# Always returns nil.
|
|
268
|
+
#
|
|
269
|
+
# @example Get the fifth document in null context.
|
|
270
|
+
# context.fifth
|
|
271
|
+
#
|
|
272
|
+
# @return [ nil ] Always nil.
|
|
273
|
+
def fifth
|
|
274
|
+
nil
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
# Always raises an error.
|
|
278
|
+
#
|
|
279
|
+
# @example Get the fifth document in null context.
|
|
280
|
+
# context.fifth!
|
|
281
|
+
#
|
|
282
|
+
# @raises [ Mongoid::Errors::DocumentNotFound ] always raises.
|
|
283
|
+
def fifth!
|
|
284
|
+
raise_document_not_found_error
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
# Always returns nil.
|
|
288
|
+
#
|
|
289
|
+
# @example Get the second to last document in null context.
|
|
290
|
+
# context.second_to_last
|
|
291
|
+
#
|
|
292
|
+
# @return [ nil ] Always nil.
|
|
293
|
+
def second_to_last
|
|
294
|
+
nil
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
# Always raises an error.
|
|
298
|
+
#
|
|
299
|
+
# @example Get the second to last document in null context.
|
|
300
|
+
# context.second_to_last!
|
|
301
|
+
#
|
|
302
|
+
# @raises [ Mongoid::Errors::DocumentNotFound ] always raises.
|
|
303
|
+
def second_to_last!
|
|
304
|
+
raise_document_not_found_error
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
# Always returns nil.
|
|
308
|
+
#
|
|
309
|
+
# @example Get the third to last document in null context.
|
|
310
|
+
# context.third_to_last
|
|
311
|
+
#
|
|
312
|
+
# @return [ nil ] Always nil.
|
|
313
|
+
def third_to_last
|
|
314
|
+
nil
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
# Always raises an error.
|
|
318
|
+
#
|
|
319
|
+
# @example Get the third to last document in null context.
|
|
320
|
+
# context.third_to_last!
|
|
321
|
+
#
|
|
322
|
+
# @raises [ Mongoid::Errors::DocumentNotFound ] always raises.
|
|
323
|
+
def third_to_last!
|
|
324
|
+
raise_document_not_found_error
|
|
176
325
|
end
|
|
177
326
|
|
|
178
327
|
# Always returns zero.
|
|
@@ -188,6 +337,12 @@ module Mongoid
|
|
|
188
337
|
|
|
189
338
|
alias :find_first :first
|
|
190
339
|
alias :one :first
|
|
340
|
+
|
|
341
|
+
private
|
|
342
|
+
|
|
343
|
+
def raise_document_not_found_error
|
|
344
|
+
raise Errors::DocumentNotFound.new(klass, nil, nil)
|
|
345
|
+
end
|
|
191
346
|
end
|
|
192
347
|
end
|
|
193
348
|
end
|
data/lib/mongoid/contextual.rb
CHANGED
|
@@ -35,6 +35,18 @@ module Mongoid
|
|
|
35
35
|
@context ||= create_context
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
+
# Instructs the context to schedule an asynchronous loading of documents
|
|
39
|
+
# specified by the criteria.
|
|
40
|
+
#
|
|
41
|
+
# Note that depending on the context and on the Mongoid configuration,
|
|
42
|
+
# documents can be loaded synchronously on the caller's thread.
|
|
43
|
+
#
|
|
44
|
+
# @return [ Criteria ] Returns self.
|
|
45
|
+
def load_async
|
|
46
|
+
context.load_async if context.respond_to?(:load_async)
|
|
47
|
+
self
|
|
48
|
+
end
|
|
49
|
+
|
|
38
50
|
private
|
|
39
51
|
|
|
40
52
|
# Create the context for the queries to execute. Will be memory for
|
|
@@ -21,7 +21,7 @@ module Mongoid
|
|
|
21
21
|
multi ? result : result.first
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
# Find the
|
|
24
|
+
# Find the matching document(s) in the criteria for the provided id(s).
|
|
25
25
|
#
|
|
26
26
|
# @note Each argument can be an individual id, an array of ids or
|
|
27
27
|
# a nested array. Each array will be flattened.
|
|
@@ -32,7 +32,7 @@ module Mongoid
|
|
|
32
32
|
# @example Find by multiple ids.
|
|
33
33
|
# criteria.find([ BSON::ObjectId.new, BSON::ObjectId.new ])
|
|
34
34
|
#
|
|
35
|
-
# @param [ Object | Array<Object> ] *args The
|
|
35
|
+
# @param [ [ Object | Array<Object> ]... ] *args The id(s) to find.
|
|
36
36
|
#
|
|
37
37
|
# @return [ Document | Array<Document> ] The matching document(s).
|
|
38
38
|
def find(*args)
|
|
@@ -21,8 +21,8 @@ module Mongoid
|
|
|
21
21
|
# @example Eager load the provided associations.
|
|
22
22
|
# Person.includes(:posts, :game)
|
|
23
23
|
#
|
|
24
|
-
# @param [
|
|
25
|
-
# load.
|
|
24
|
+
# @param [ [ Symbol | Hash ]... ] *relations The names of the association(s)
|
|
25
|
+
# to eager load.
|
|
26
26
|
#
|
|
27
27
|
# @return [ Criteria ] The cloned criteria.
|
|
28
28
|
def includes(*relations)
|
|
@@ -70,7 +70,8 @@ module Mongoid
|
|
|
70
70
|
# association originates.
|
|
71
71
|
# @param [ String ] parent The name of the association above this one in
|
|
72
72
|
# the inclusion tree, if it is a nested inclusion.
|
|
73
|
-
# @param
|
|
73
|
+
# @param [ [ Symbol | Hash | Array<Symbol | Hash> ]... ] *relations_list
|
|
74
|
+
# The names of the association(s) to eager load.
|
|
74
75
|
def extract_includes_list(_parent_class, parent, *relations_list)
|
|
75
76
|
relations_list.flatten.each do |relation_object|
|
|
76
77
|
if relation_object.is_a?(Hash)
|
|
@@ -43,21 +43,7 @@ module Mongoid
|
|
|
43
43
|
#
|
|
44
44
|
# @return [ Object ] The converted number.
|
|
45
45
|
def __numeric__(object)
|
|
46
|
-
|
|
47
|
-
raise ArgumentError if str.empty?
|
|
48
|
-
|
|
49
|
-
# These requirements seem a bit odd, but they're explicitly specified in the tests,
|
|
50
|
-
# so we're obligated to keep them, for now. (This code was rewritten from a one-line
|
|
51
|
-
# regex, due to security concerns with a polynomial regex being used on uncontrolled
|
|
52
|
-
# data).
|
|
53
|
-
|
|
54
|
-
str = str.chop if str.end_with?('.')
|
|
55
|
-
return 0 if str.empty?
|
|
56
|
-
|
|
57
|
-
result = Integer(str) rescue Float(object)
|
|
58
|
-
|
|
59
|
-
integer = result.to_i
|
|
60
|
-
integer == result ? integer : result
|
|
46
|
+
object.to_s.match?(/\A[-+]?[0-9]*[0-9.]0*\z/) ? object.to_i : Float(object)
|
|
61
47
|
end
|
|
62
48
|
|
|
63
49
|
# Evolve the object to an integer.
|
|
@@ -283,7 +283,7 @@ module Mongoid
|
|
|
283
283
|
# The new value is a simple value.
|
|
284
284
|
# Transform the implicit equality to either $eq or $regexp
|
|
285
285
|
# depending on the type of the argument. See
|
|
286
|
-
# https://
|
|
286
|
+
# https://www.mongodb.com/docs/manual/reference/operator/query/eq/#std-label-eq-usage-examples
|
|
287
287
|
# for the description of relevant server behavior.
|
|
288
288
|
op = case v
|
|
289
289
|
when Regexp, BSON::Regexp::Raw
|
|
@@ -325,10 +325,6 @@ module Mongoid
|
|
|
325
325
|
end
|
|
326
326
|
end
|
|
327
327
|
end
|
|
328
|
-
# Every query method that takes a user-supplied expression normalizes
|
|
329
|
-
# it here, so this is where the operator guard is enforced. See
|
|
330
|
-
# Selectable#_mongoid_validate_operators! for what it does not cover.
|
|
331
|
-
_mongoid_validate_operators!(result)
|
|
332
328
|
result
|
|
333
329
|
end
|
|
334
330
|
|
|
@@ -347,14 +343,6 @@ module Mongoid
|
|
|
347
343
|
if criterion.is_a?(Selectable)
|
|
348
344
|
criterion = criterion.selector
|
|
349
345
|
end
|
|
350
|
-
|
|
351
|
-
# The __override__ path writes to the selector directly, so it
|
|
352
|
-
# bypasses _mongoid_expand_keys where the operator guard normally
|
|
353
|
-
# runs. Enforce the guard here so chained override methods
|
|
354
|
-
# (elem_match, exists, eq, gt, in, etc.) cannot smuggle $where or
|
|
355
|
-
# other JavaScript operators under strict mode.
|
|
356
|
-
_mongoid_validate_operators!(criterion)
|
|
357
|
-
|
|
358
346
|
selection(criterion) do |selector, field, value|
|
|
359
347
|
expression = prepare(field, operator, value)
|
|
360
348
|
existing = selector[field]
|
|
@@ -17,7 +17,7 @@ module Mongoid
|
|
|
17
17
|
# @example Add ascending sorting.
|
|
18
18
|
# optional.ascending(:first_name, :last_name)
|
|
19
19
|
#
|
|
20
|
-
# @param [
|
|
20
|
+
# @param [ Symbol... ] *fields The field(s) to sort.
|
|
21
21
|
#
|
|
22
22
|
# @return [ Optional ] The cloned optional.
|
|
23
23
|
def ascending(*fields)
|
|
@@ -45,7 +45,7 @@ module Mongoid
|
|
|
45
45
|
# @example Add descending sorting.
|
|
46
46
|
# optional.descending(:first_name, :last_name)
|
|
47
47
|
#
|
|
48
|
-
# @param [
|
|
48
|
+
# @param [ Symbol... ] *fields The field(s) to sort.
|
|
49
49
|
#
|
|
50
50
|
# @return [ Optional ] The cloned optional.
|
|
51
51
|
def descending(*fields)
|
|
@@ -123,7 +123,7 @@ module Mongoid
|
|
|
123
123
|
# @example Limit the results to the provided fields.
|
|
124
124
|
# optional.only(:name, :dob)
|
|
125
125
|
#
|
|
126
|
-
# @param [
|
|
126
|
+
# @param [ Symbol... ] *args The field(s) to return.
|
|
127
127
|
#
|
|
128
128
|
# @return [ Optional ] The cloned optional.
|
|
129
129
|
def only(*args)
|
|
@@ -163,7 +163,7 @@ module Mongoid
|
|
|
163
163
|
# @example Add sorting options via a string.
|
|
164
164
|
# optional.order_by("name ASC, dob DESC")
|
|
165
165
|
#
|
|
166
|
-
# @param [ Array | Hash | String ] spec The sorting specification.
|
|
166
|
+
# @param [ [ Array | Hash | String ]... ] *spec The sorting specification.
|
|
167
167
|
#
|
|
168
168
|
# @return [ Optional ] The cloned optional.
|
|
169
169
|
def order_by(*spec)
|
|
@@ -184,7 +184,7 @@ module Mongoid
|
|
|
184
184
|
# @example Replace the ordering.
|
|
185
185
|
# optional.reorder(name: :asc)
|
|
186
186
|
#
|
|
187
|
-
# @param [ Array | Hash | String ] spec The sorting specification.
|
|
187
|
+
# @param [ [ Array | Hash | String ]... ] *spec The sorting specification.
|
|
188
188
|
#
|
|
189
189
|
# @return [ Optional ] The cloned optional.
|
|
190
190
|
def reorder(*spec)
|
|
@@ -245,7 +245,7 @@ module Mongoid
|
|
|
245
245
|
# @example Limit the results to the fields not provided.
|
|
246
246
|
# optional.without(:name, :dob)
|
|
247
247
|
#
|
|
248
|
-
# @param [
|
|
248
|
+
# @param [ Symbol... ] *args The field(s) to ignore.
|
|
249
249
|
#
|
|
250
250
|
# @return [ Optional ] The cloned optional.
|
|
251
251
|
def without(*args)
|
|
@@ -331,7 +331,7 @@ module Mongoid
|
|
|
331
331
|
# @example Store the option.
|
|
332
332
|
# optional.option({ skip: 10 })
|
|
333
333
|
#
|
|
334
|
-
# @param [
|
|
334
|
+
# @param [ Object... ] *args The options.
|
|
335
335
|
#
|
|
336
336
|
# @return [ Queryable ] The cloned queryable.
|
|
337
337
|
def option(*args)
|
|
@@ -349,7 +349,7 @@ module Mongoid
|
|
|
349
349
|
# @example Add multiple sort options.
|
|
350
350
|
# optional.sort_with_list(:name, :dob, 1)
|
|
351
351
|
#
|
|
352
|
-
# @param [
|
|
352
|
+
# @param [ [ Symbol | String ]... ] *fields The field name(s).
|
|
353
353
|
# @param [ Integer ] direction The sort direction.
|
|
354
354
|
#
|
|
355
355
|
# @return [ Optional ] The cloned optional.
|
|
@@ -31,7 +31,7 @@ module Mongoid
|
|
|
31
31
|
# @example Execute an $all in a where query.
|
|
32
32
|
# selectable.where(:field.all => [ 1, 2 ])
|
|
33
33
|
#
|
|
34
|
-
# @param [ Hash ]
|
|
34
|
+
# @param [ Hash... ] *criteria The key value pair(s) for $all matching.
|
|
35
35
|
#
|
|
36
36
|
# @return [ Selectable ] The cloned selectable.
|
|
37
37
|
def all(*criteria)
|
|
@@ -69,8 +69,9 @@ module Mongoid
|
|
|
69
69
|
# @example Add the criterion.
|
|
70
70
|
# selectable.and({ field: value }, { other: value })
|
|
71
71
|
#
|
|
72
|
-
# @param [ Array<Hash | Criteria> ] criteria
|
|
73
|
-
# matches or Criteria objects that all must
|
|
72
|
+
# @param [ [ Hash | Criteria | Array<Hash | Criteria> ]... ] *criteria
|
|
73
|
+
# Multiple key/value pair matches or Criteria objects that all must
|
|
74
|
+
# match to return results.
|
|
74
75
|
#
|
|
75
76
|
# @return [ Selectable ] The new selectable.
|
|
76
77
|
def and(*criteria)
|
|
@@ -199,7 +200,7 @@ module Mongoid
|
|
|
199
200
|
# the upper right (north east) as the second argument.
|
|
200
201
|
# Important: When latitude and longitude are passed, longitude is
|
|
201
202
|
# expected as the first element of the coordinate pair.
|
|
202
|
-
# Source: https://
|
|
203
|
+
# Source: https://www.mongodb.com/docs/manual/reference/operator/query/box/
|
|
203
204
|
#
|
|
204
205
|
# @example Add a geo intersect criterion for a line.
|
|
205
206
|
# query.geo_spatial(:location.intersects_line => [[ 1, 10 ], [ 2, 10 ]])
|
|
@@ -516,8 +517,8 @@ module Mongoid
|
|
|
516
517
|
# @example Add the $nor selection.
|
|
517
518
|
# selectable.nor(field: 1, field: 2)
|
|
518
519
|
#
|
|
519
|
-
# @param [ Array<Hash | Criteria> ] criteria
|
|
520
|
-
# matches or Criteria objects.
|
|
520
|
+
# @param [ [ Hash | Criteria | Array<Hash | Criteria> ]... ] *criteria
|
|
521
|
+
# Multiple key/value pair matches or Criteria objects.
|
|
521
522
|
#
|
|
522
523
|
# @return [ Selectable ] The new selectable.
|
|
523
524
|
def nor(*criteria)
|
|
@@ -545,7 +546,7 @@ module Mongoid
|
|
|
545
546
|
# @example Execute a $not in a where query.
|
|
546
547
|
# selectable.where(:field.not => /Bob/)
|
|
547
548
|
#
|
|
548
|
-
# @param [
|
|
549
|
+
# @param [ [ Hash | Criteria ]... ] *criteria The key/value pair
|
|
549
550
|
# matches or Criteria objects to negate.
|
|
550
551
|
#
|
|
551
552
|
# @return [ Selectable ] The new selectable.
|
|
@@ -580,6 +581,35 @@ module Mongoid
|
|
|
580
581
|
end
|
|
581
582
|
key :not, :override, "$not"
|
|
582
583
|
|
|
584
|
+
# Negate the arguments, constraining the query to only those documents
|
|
585
|
+
# that do NOT match the arguments.
|
|
586
|
+
#
|
|
587
|
+
# @example Exclude a single criterion.
|
|
588
|
+
# selectable.none_of(name: /Bob/)
|
|
589
|
+
#
|
|
590
|
+
# @example Exclude multiple criteria.
|
|
591
|
+
# selectable.none_of(name: /Bob/, country: "USA")
|
|
592
|
+
#
|
|
593
|
+
# @example Exclude multiple criteria as an array.
|
|
594
|
+
# selectable.none_of([{ name: /Bob/ }, { country: "USA" }])
|
|
595
|
+
#
|
|
596
|
+
# @param [ [ Hash | Criteria ]... ] *criteria The key/value pair
|
|
597
|
+
# matches or Criteria objects to negate.
|
|
598
|
+
#
|
|
599
|
+
# @return [ Selectable ] The new selectable.
|
|
600
|
+
def none_of(*criteria)
|
|
601
|
+
criteria = _mongoid_flatten_arrays(criteria)
|
|
602
|
+
return dup if criteria.empty?
|
|
603
|
+
|
|
604
|
+
exprs = criteria.map do |criterion|
|
|
605
|
+
_mongoid_expand_keys(
|
|
606
|
+
criterion.is_a?(Selectable) ?
|
|
607
|
+
criterion.selector : criterion)
|
|
608
|
+
end
|
|
609
|
+
|
|
610
|
+
self.and('$nor' => exprs)
|
|
611
|
+
end
|
|
612
|
+
|
|
583
613
|
# Creates a disjunction using $or from the existing criteria in the
|
|
584
614
|
# receiver and the provided arguments.
|
|
585
615
|
#
|
|
@@ -605,7 +635,7 @@ module Mongoid
|
|
|
605
635
|
# @example Same as previous example, also deprecated.
|
|
606
636
|
# selectable.or([{field: 1}], [{field: 2}])
|
|
607
637
|
#
|
|
608
|
-
# @param [ Hash | Criteria | Array<Hash | Criteria
|
|
638
|
+
# @param [ [ Hash | Criteria | Array<Hash | Criteria> ]... ] *criteria
|
|
609
639
|
# Multiple key/value pair matches or Criteria objects, or arrays
|
|
610
640
|
# thereof. Passing arrays is deprecated.
|
|
611
641
|
#
|
|
@@ -635,7 +665,7 @@ module Mongoid
|
|
|
635
665
|
# @example Same as previous example, also deprecated.
|
|
636
666
|
# selectable.any_of([{field: 1}], [{field: 2}])
|
|
637
667
|
#
|
|
638
|
-
# @param [ Hash | Criteria | Array<Hash | Criteria
|
|
668
|
+
# @param [ [ Hash | Criteria | Array<Hash | Criteria> ]... ] *criteria
|
|
639
669
|
# Multiple key/value pair matches or Criteria objects, or arrays
|
|
640
670
|
# thereof. Passing arrays is deprecated.
|
|
641
671
|
#
|
|
@@ -731,7 +761,7 @@ module Mongoid
|
|
|
731
761
|
# @example Construct a text search selector with options.
|
|
732
762
|
# selectable.text_search("testing", :$language => "fr")
|
|
733
763
|
#
|
|
734
|
-
# @note Per https://
|
|
764
|
+
# @note Per https://www.mongodb.com/docs/manual/reference/operator/query/text/
|
|
735
765
|
# it is not currently possible to supply multiple text search
|
|
736
766
|
# conditions in a query. Mongoid will build such a query but the
|
|
737
767
|
# server will return an error when trying to execute it.
|
|
@@ -751,7 +781,7 @@ module Mongoid
|
|
|
751
781
|
criterion = {'$text' => { '$search' => terms }}
|
|
752
782
|
criterion['$text'].merge!(opts) if opts
|
|
753
783
|
if query.selector['$text']
|
|
754
|
-
# Per https://
|
|
784
|
+
# Per https://www.mongodb.com/docs/manual/reference/operator/query/text/
|
|
755
785
|
# multiple $text expressions are not currently supported by
|
|
756
786
|
# MongoDB server, but build the query correctly instead of
|
|
757
787
|
# overwriting previous text search condition with the currently
|
|
@@ -774,7 +804,8 @@ module Mongoid
|
|
|
774
804
|
# @example Add a javascript selection.
|
|
775
805
|
# selectable.where("this.name == 'syd'")
|
|
776
806
|
#
|
|
777
|
-
# @param [
|
|
807
|
+
# @param [ [ Hash | String ]... ] *criterion The standard selection
|
|
808
|
+
# or javascript string.
|
|
778
809
|
#
|
|
779
810
|
# @return [ Selectable ] The cloned selectable.
|
|
780
811
|
def where(*criteria)
|
|
@@ -791,12 +822,6 @@ module Mongoid
|
|
|
791
822
|
# only ever specify one criterion to #where.
|
|
792
823
|
@criterion = criterion
|
|
793
824
|
if criterion.is_a?(String)
|
|
794
|
-
unless Mongoid.allow_unsafe_query_operators?
|
|
795
|
-
raise Errors::InvalidQuery,
|
|
796
|
-
"String criteria are not allowed because they compile to the '$where' operator, " \
|
|
797
|
-
'which is not allowed in a query expression. Set Mongoid.allow_unsafe_query_operators = true ' \
|
|
798
|
-
'to permit all operators.'
|
|
799
|
-
end
|
|
800
825
|
js_query(criterion)
|
|
801
826
|
else
|
|
802
827
|
expr_query(criterion)
|
|
@@ -806,19 +831,6 @@ module Mongoid
|
|
|
806
831
|
|
|
807
832
|
private
|
|
808
833
|
|
|
809
|
-
# Operators permitted at the top level of a query expression without
|
|
810
|
-
# opt-in. Excludes $where (JS execution) and other operators not needed
|
|
811
|
-
# for ordinary application queries.
|
|
812
|
-
ALLOWED_QUERY_OPERATORS = %w[
|
|
813
|
-
$and $or $nor $not $text $comment $expr $jsonSchema $alwaysFalse $alwaysTrue
|
|
814
|
-
].freeze
|
|
815
|
-
|
|
816
|
-
# Operators that execute server-side JavaScript. These are rejected at
|
|
817
|
-
# any depth, not just at the top level: the allowlist above permits
|
|
818
|
-
# $expr and the logical operators, and their values are arbitrary
|
|
819
|
-
# nested expressions that can carry $function or $where.
|
|
820
|
-
JAVASCRIPT_QUERY_OPERATORS = %w[$where $function $accumulator].freeze
|
|
821
|
-
|
|
822
834
|
# Adds the specified expression to the query.
|
|
823
835
|
#
|
|
824
836
|
# Criterion must be a hash in one of the following forms:
|
|
@@ -844,8 +856,6 @@ module Mongoid
|
|
|
844
856
|
raise Errors::InvalidQuery, "Expression must be a Hash: #{Errors::InvalidQuery.truncate_expr(criterion)}"
|
|
845
857
|
end
|
|
846
858
|
|
|
847
|
-
# The operator guard is applied by _mongoid_expand_keys, which every
|
|
848
|
-
# query method that accepts a user-supplied expression passes through.
|
|
849
859
|
normalized = _mongoid_expand_keys(criterion)
|
|
850
860
|
clone.tap do |query|
|
|
851
861
|
normalized.each do |field, value|
|
|
@@ -861,94 +871,6 @@ module Mongoid
|
|
|
861
871
|
end
|
|
862
872
|
end
|
|
863
873
|
|
|
864
|
-
# Enforces the operator rules governed by the
|
|
865
|
-
# +allow_unsafe_query_operators+ configuration option against a
|
|
866
|
-
# normalized query expression.
|
|
867
|
-
#
|
|
868
|
-
# Two rules apply, and both are skipped when the option is true:
|
|
869
|
-
#
|
|
870
|
-
# - An operator at the top level of the expression must appear in
|
|
871
|
-
# ALLOWED_QUERY_OPERATORS.
|
|
872
|
-
# - An operator in JAVASCRIPT_QUERY_OPERATORS is rejected at any depth.
|
|
873
|
-
#
|
|
874
|
-
# This is called from #_mongoid_expand_keys rather than from the
|
|
875
|
-
# individual query methods, because that is the one point every query
|
|
876
|
-
# method taking a user-supplied expression passes through on its way to
|
|
877
|
-
# the selector.
|
|
878
|
-
#
|
|
879
|
-
# It deliberately does not cover the APIs that ask for JavaScript
|
|
880
|
-
# outright, such as #js_query and Criteria#for_js: there the developer
|
|
881
|
-
# has chosen server-side JavaScript, so there is nothing to guard
|
|
882
|
-
# against. The same goes for the low-level Storable methods
|
|
883
|
-
# (#add_field_expression, #add_operator_expression), which write to the
|
|
884
|
-
# selector directly.
|
|
885
|
-
#
|
|
886
|
-
# @param [ Hash ] expr A normalized query expression.
|
|
887
|
-
#
|
|
888
|
-
# @raise [ Errors::InvalidQuery ] If a disallowed operator is present.
|
|
889
|
-
#
|
|
890
|
-
# @api private
|
|
891
|
-
def _mongoid_validate_operators!(expr)
|
|
892
|
-
return if Mongoid.allow_unsafe_query_operators?
|
|
893
|
-
|
|
894
|
-
expr.each_key do |field|
|
|
895
|
-
field_s = field.to_s
|
|
896
|
-
next unless field_s.start_with?('$')
|
|
897
|
-
next if ALLOWED_QUERY_OPERATORS.include?(field_s)
|
|
898
|
-
|
|
899
|
-
raise Errors::InvalidQuery,
|
|
900
|
-
"Operator '#{field_s}' is not allowed in a query expression. " \
|
|
901
|
-
'Set Mongoid.allow_unsafe_query_operators = true to permit all operators.'
|
|
902
|
-
end
|
|
903
|
-
|
|
904
|
-
_mongoid_validate_no_javascript!(expr)
|
|
905
|
-
end
|
|
906
|
-
|
|
907
|
-
# Walks a query expression looking for operators that execute
|
|
908
|
-
# server-side JavaScript, descending through both hashes and arrays so
|
|
909
|
-
# that nested forms such as {'$expr' => {'$function' => ...}} and
|
|
910
|
-
# {'$or' => [ {'$where' => ...} ]} are caught.
|
|
911
|
-
#
|
|
912
|
-
# The walk does not distinguish operator position from value position,
|
|
913
|
-
# so it also rejects queries where a JavaScript operator name appears as
|
|
914
|
-
# data rather than as an operator. Server 5.0+ permits $-prefixed field
|
|
915
|
-
# names in stored documents, which makes this reachable:
|
|
916
|
-
#
|
|
917
|
-
# Doc.where(payload: { '$eq' => { '$function' => 'abc' } })
|
|
918
|
-
#
|
|
919
|
-
# Here the $eq marks its argument as a literal value to compare, so the
|
|
920
|
-
# server never evaluates it, but the guard raises anyway. The only
|
|
921
|
-
# workaround today is the global allow_unsafe_query_operators flag.
|
|
922
|
-
#
|
|
923
|
-
# TODO: discuss whether to track operator position (skipping the subtree
|
|
924
|
-
# under $eq, $ne, $in, $nin, and $elemMatch values) in a future
|
|
925
|
-
# iteration. It removes the false positive but adds exactly the kind of
|
|
926
|
-
# state that a real bypass could hide in, so it was left out for now.
|
|
927
|
-
#
|
|
928
|
-
# @param [ Object ] object A fragment of a query expression.
|
|
929
|
-
#
|
|
930
|
-
# @raise [ Errors::InvalidQuery ] If a JavaScript operator is present.
|
|
931
|
-
#
|
|
932
|
-
# @api private
|
|
933
|
-
def _mongoid_validate_no_javascript!(object)
|
|
934
|
-
case object
|
|
935
|
-
when Hash
|
|
936
|
-
object.each do |key, value|
|
|
937
|
-
key_s = key.to_s
|
|
938
|
-
if JAVASCRIPT_QUERY_OPERATORS.include?(key_s)
|
|
939
|
-
raise Errors::InvalidQuery,
|
|
940
|
-
"Operator '#{key_s}' executes server-side JavaScript and is not allowed " \
|
|
941
|
-
'anywhere in a query expression. Set Mongoid.allow_unsafe_query_operators = true ' \
|
|
942
|
-
'to permit all operators.'
|
|
943
|
-
end
|
|
944
|
-
|
|
945
|
-
_mongoid_validate_no_javascript!(value)
|
|
946
|
-
end
|
|
947
|
-
when Array
|
|
948
|
-
object.each { |value| _mongoid_validate_no_javascript!(value) }
|
|
949
|
-
end
|
|
950
|
-
end
|
|
951
|
-
|
|
952
874
|
# Force the values of the criterion to be evolved.
|
|
953
875
|
#
|
|
954
876
|
# @api private
|