mongoid 7.4.3 → 7.5.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/lib/config/locales/en.yml +7 -0
- data/lib/mongoid/association/embedded/batchable.rb +3 -20
- data/lib/mongoid/association/macros.rb +20 -0
- data/lib/mongoid/association/referenced/has_many/enumerable.rb +12 -8
- data/lib/mongoid/association/referenced/has_many/proxy.rb +2 -2
- data/lib/mongoid/atomic/paths/embedded/many.rb +0 -19
- data/lib/mongoid/config.rb +6 -1
- data/lib/mongoid/contextual/memory.rb +144 -12
- data/lib/mongoid/contextual/mongo.rb +118 -26
- data/lib/mongoid/contextual/none.rb +45 -1
- data/lib/mongoid/criteria/queryable/extensions/array.rb +2 -0
- data/lib/mongoid/criteria/queryable/extensions/hash.rb +2 -0
- data/lib/mongoid/criteria/queryable/mergeable.rb +21 -0
- data/lib/mongoid/criteria/queryable/selectable.rb +26 -10
- data/lib/mongoid/criteria.rb +2 -0
- data/lib/mongoid/document.rb +2 -0
- data/lib/mongoid/equality.rb +4 -4
- data/lib/mongoid/errors/document_not_found.rb +23 -6
- data/lib/mongoid/fields.rb +145 -21
- data/lib/mongoid/findable.rb +20 -5
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid/warnings.rb +29 -0
- data/lib/mongoid.rb +1 -0
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +4 -3
- data/spec/integration/i18n_fallbacks_spec.rb +15 -1
- data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +0 -21
- data/spec/mongoid/association/embedded/embeds_many_models.rb +0 -121
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +0 -8
- data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +54 -0
- data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +8 -24
- data/spec/mongoid/clients/options_spec.rb +1 -0
- data/spec/mongoid/config_spec.rb +10 -4
- data/spec/mongoid/contextual/memory_spec.rb +826 -65
- data/spec/mongoid/contextual/mongo_spec.rb +781 -18
- data/spec/mongoid/contextual/none_spec.rb +46 -0
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +212 -39
- data/spec/mongoid/criteria_spec.rb +8 -0
- data/spec/mongoid/equality_spec.rb +12 -12
- data/spec/mongoid/errors/document_not_found_spec.rb +49 -0
- data/spec/mongoid/findable_spec.rb +30 -0
- data/spec/support/models/code.rb +2 -0
- data.tar.gz.sig +0 -0
- metadata +3 -2
- metadata.gz.sig +0 -0
@@ -52,6 +52,27 @@ module Mongoid
|
|
52
52
|
self
|
53
53
|
end
|
54
54
|
|
55
|
+
# Merge criteria with operators using the and operator.
|
56
|
+
#
|
57
|
+
# @param [ Hash ] criterion The criterion to add to the criteria.
|
58
|
+
# @param [ String ] operator The MongoDB operator.
|
59
|
+
#
|
60
|
+
# @return [ Criteria ] The resulting criteria.
|
61
|
+
def and_with_operator(criterion, operator)
|
62
|
+
crit = self
|
63
|
+
if criterion
|
64
|
+
criterion.each_pair do |field, value|
|
65
|
+
val = prepare(field, operator, value)
|
66
|
+
# The prepare method already takes the negation into account. We
|
67
|
+
# set negating to false here so that ``and`` doesn't also apply
|
68
|
+
# negation and we have a double negative.
|
69
|
+
crit.negating = false
|
70
|
+
crit = crit.and(field => val)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
crit
|
74
|
+
end
|
75
|
+
|
55
76
|
private
|
56
77
|
|
57
78
|
# Adds the criterion to the existing selection.
|
@@ -154,7 +154,7 @@ module Mongoid
|
|
154
154
|
raise Errors::CriteriaArgumentRequired, :elem_match
|
155
155
|
end
|
156
156
|
|
157
|
-
|
157
|
+
and_or_override(criterion, "$elemMatch")
|
158
158
|
end
|
159
159
|
key :elem_match, :override, "$elemMatch"
|
160
160
|
|
@@ -270,7 +270,7 @@ module Mongoid
|
|
270
270
|
raise Errors::CriteriaArgumentRequired, :eq
|
271
271
|
end
|
272
272
|
|
273
|
-
|
273
|
+
and_or_override(criterion, "$eq")
|
274
274
|
end
|
275
275
|
key :eq, :override, "$eq"
|
276
276
|
|
@@ -290,7 +290,7 @@ module Mongoid
|
|
290
290
|
raise Errors::CriteriaArgumentRequired, :gt
|
291
291
|
end
|
292
292
|
|
293
|
-
|
293
|
+
and_or_override(criterion, "$gt")
|
294
294
|
end
|
295
295
|
key :gt, :override, "$gt"
|
296
296
|
|
@@ -310,7 +310,7 @@ module Mongoid
|
|
310
310
|
raise Errors::CriteriaArgumentRequired, :gte
|
311
311
|
end
|
312
312
|
|
313
|
-
|
313
|
+
and_or_override(criterion, "$gte")
|
314
314
|
end
|
315
315
|
key :gte, :override, "$gte"
|
316
316
|
|
@@ -366,7 +366,7 @@ module Mongoid
|
|
366
366
|
raise Errors::CriteriaArgumentRequired, :lt
|
367
367
|
end
|
368
368
|
|
369
|
-
|
369
|
+
and_or_override(criterion, "$lt")
|
370
370
|
end
|
371
371
|
key :lt, :override, "$lt"
|
372
372
|
|
@@ -386,7 +386,7 @@ module Mongoid
|
|
386
386
|
raise Errors::CriteriaArgumentRequired, :lte
|
387
387
|
end
|
388
388
|
|
389
|
-
|
389
|
+
and_or_override(criterion, "$lte")
|
390
390
|
end
|
391
391
|
key :lte, :override, "$lte"
|
392
392
|
|
@@ -423,7 +423,7 @@ module Mongoid
|
|
423
423
|
raise Errors::CriteriaArgumentRequired, :mod
|
424
424
|
end
|
425
425
|
|
426
|
-
|
426
|
+
and_or_override(criterion, "$mod")
|
427
427
|
end
|
428
428
|
key :mod, :override, "$mod"
|
429
429
|
|
@@ -443,7 +443,7 @@ module Mongoid
|
|
443
443
|
raise Errors::CriteriaArgumentRequired, :ne
|
444
444
|
end
|
445
445
|
|
446
|
-
|
446
|
+
and_or_override(criterion, "$ne")
|
447
447
|
end
|
448
448
|
alias :excludes :ne
|
449
449
|
key :ne, :override, "$ne"
|
@@ -464,7 +464,7 @@ module Mongoid
|
|
464
464
|
raise Errors::CriteriaArgumentRequired, :near
|
465
465
|
end
|
466
466
|
|
467
|
-
|
467
|
+
and_or_override(criterion, "$near")
|
468
468
|
end
|
469
469
|
key :near, :override, "$near"
|
470
470
|
|
@@ -484,7 +484,7 @@ module Mongoid
|
|
484
484
|
raise Errors::CriteriaArgumentRequired, :near_sphere
|
485
485
|
end
|
486
486
|
|
487
|
-
|
487
|
+
and_or_override(criterion, "$nearSphere")
|
488
488
|
end
|
489
489
|
key :near_sphere, :override, "$nearSphere"
|
490
490
|
|
@@ -924,6 +924,22 @@ module Mongoid
|
|
924
924
|
end
|
925
925
|
end
|
926
926
|
|
927
|
+
# Combine operator expessions onto a Criteria using either
|
928
|
+
# an override or ands depending on the status of the
|
929
|
+
# Mongoid.overwrite_chained_operators feature flag.
|
930
|
+
#
|
931
|
+
# @param [ Hash ] The criterion to add to the criteria.
|
932
|
+
# @param [ String ] operator The MongoDB operator.
|
933
|
+
#
|
934
|
+
# @return [ Criteria ] The resulting criteria.
|
935
|
+
def and_or_override(criterion, operator)
|
936
|
+
if Mongoid.overwrite_chained_operators
|
937
|
+
__override__(criterion, operator)
|
938
|
+
else
|
939
|
+
and_with_operator(criterion, operator)
|
940
|
+
end
|
941
|
+
end
|
942
|
+
|
927
943
|
class << self
|
928
944
|
|
929
945
|
# Get the methods on the selectable that can be forwarded to from a model.
|
data/lib/mongoid/criteria.rb
CHANGED
@@ -122,6 +122,7 @@ module Mongoid
|
|
122
122
|
#
|
123
123
|
# @return [ Criteria ] The cloned criteria.
|
124
124
|
def cache
|
125
|
+
Mongoid::Warnings.warn_criteria_cache_deprecated
|
125
126
|
crit = clone
|
126
127
|
crit.options.merge!(cache: true)
|
127
128
|
crit
|
@@ -134,6 +135,7 @@ module Mongoid
|
|
134
135
|
#
|
135
136
|
# @return [ true, false ] If the criteria is flagged as cached.
|
136
137
|
def cached?
|
138
|
+
Mongoid::Warnings.warn_criteria_cache_deprecated
|
137
139
|
options[:cache] == true
|
138
140
|
end
|
139
141
|
|
data/lib/mongoid/document.rb
CHANGED
data/lib/mongoid/equality.rb
CHANGED
@@ -44,9 +44,9 @@ module Mongoid
|
|
44
44
|
# @return [ true, false ] True if the classes are equal, false if not.
|
45
45
|
def ===(other)
|
46
46
|
if Mongoid.legacy_triple_equals
|
47
|
-
other.class == Class ? self.class === other : self == other
|
48
|
-
else
|
49
47
|
super
|
48
|
+
else
|
49
|
+
other.class == Class ? self.class === other : self == other
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
@@ -73,9 +73,9 @@ module Mongoid
|
|
73
73
|
# @return [ true, false ] True if the classes are equal, false if not.
|
74
74
|
def ===(other)
|
75
75
|
if Mongoid.legacy_triple_equals
|
76
|
-
other.class == Class ? self <= other : other.is_a?(self)
|
77
|
-
else
|
78
76
|
other.is_a?(self)
|
77
|
+
else
|
78
|
+
other.class == Class ? self <= other : other.is_a?(self)
|
79
79
|
end
|
80
80
|
end
|
81
81
|
end
|
@@ -23,13 +23,13 @@ module Mongoid
|
|
23
23
|
# @param [ Array ] unmatched The unmatched ids, if appropriate
|
24
24
|
def initialize(klass, params, unmatched = nil)
|
25
25
|
if !unmatched && !params.is_a?(Hash)
|
26
|
-
unmatched = Array(params)
|
26
|
+
unmatched = Array(params) if params
|
27
27
|
end
|
28
28
|
|
29
29
|
@klass, @params = klass, params
|
30
30
|
super(
|
31
31
|
compose_message(
|
32
|
-
message_key(params),
|
32
|
+
message_key(params, unmatched),
|
33
33
|
{
|
34
34
|
klass: klass.name,
|
35
35
|
searched: searched(params),
|
@@ -93,10 +93,27 @@ module Mongoid
|
|
93
93
|
# error.problem
|
94
94
|
#
|
95
95
|
# @return [ String ] The problem.
|
96
|
-
def message_key(params)
|
97
|
-
|
98
|
-
|
99
|
-
|
96
|
+
def message_key(params, unmatched)
|
97
|
+
if !params && !unmatched
|
98
|
+
"no_documents_found"
|
99
|
+
elsif Hash === params
|
100
|
+
"document_with_attributes_not_found"
|
101
|
+
elsif Hash === unmatched && unmatched.size >= 2
|
102
|
+
"document_with_shard_key_not_found"
|
103
|
+
else
|
104
|
+
"document_not_found"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Get the shard key from the unmatched hash.
|
109
|
+
#
|
110
|
+
# @return [ String ] the shard key and value.
|
111
|
+
def shard_key(unmatched)
|
112
|
+
if Hash === unmatched
|
113
|
+
h = unmatched.dup
|
114
|
+
h.delete("_id")
|
115
|
+
h.delete(:_id)
|
116
|
+
h.map{|k,v| "#{k}: #{v}" }.join(", ")
|
100
117
|
end
|
101
118
|
end
|
102
119
|
end
|
data/lib/mongoid/fields.rb
CHANGED
@@ -270,21 +270,64 @@ module Mongoid
|
|
270
270
|
def options
|
271
271
|
@options ||= {}
|
272
272
|
end
|
273
|
-
end
|
274
|
-
|
275
|
-
module ClassMethods
|
276
273
|
|
277
|
-
#
|
274
|
+
# Traverse down the association tree and search for the field for the
|
275
|
+
# given key. To do this, split the key by '.' and for each part (meth) of
|
276
|
+
# the key:
|
278
277
|
#
|
279
|
-
#
|
280
|
-
#
|
278
|
+
# - If the meth is a field, yield the meth, field, and is_field as true.
|
279
|
+
# - If the meth is an association, update the klass to the association's
|
280
|
+
# klass, and yield the meth, klass, and is_field as false.
|
281
281
|
#
|
282
|
-
#
|
283
|
-
#
|
282
|
+
# The next iteration will use klass's fields and associations to continue
|
283
|
+
# traversing the tree.
|
284
284
|
#
|
285
|
-
# @
|
286
|
-
|
287
|
-
|
285
|
+
# @param [ String ] key The key used to search the association tree.
|
286
|
+
# @param [ Hash ] fields The fields to begin the search with.
|
287
|
+
# @param [ Hash ] associations The associations to begin the search with.
|
288
|
+
# @param [ Hash ] aliased_associations The alaised associations to begin
|
289
|
+
# the search with.
|
290
|
+
# @param [ Proc ] block The block takes in three paramaters, the current
|
291
|
+
# meth, the field or the relation, and whether the second parameter is a
|
292
|
+
# field or not.
|
293
|
+
#
|
294
|
+
# @return [ Field ] The field found for the given key at the end of the
|
295
|
+
# search. This will return nil if the last thing found is an association
|
296
|
+
# or no field was found for the given key.
|
297
|
+
#
|
298
|
+
# @api private
|
299
|
+
def traverse_association_tree(key, fields, associations, aliased_associations)
|
300
|
+
klass = nil
|
301
|
+
field = nil
|
302
|
+
key.split('.').each_with_index do |meth, i|
|
303
|
+
fs = i == 0 ? fields : klass&.fields
|
304
|
+
rs = i == 0 ? associations : klass&.relations
|
305
|
+
as = i == 0 ? aliased_associations : klass&.aliased_associations
|
306
|
+
|
307
|
+
# Associations can possibly have two "keys", their name and their alias.
|
308
|
+
# The fields name is what is used to store it in the klass's relations
|
309
|
+
# and field hashes, and the alias is what's used to store that field
|
310
|
+
# in the database. The key inputted to this function is the aliased
|
311
|
+
# key. We can convert them back to their names by looking in the
|
312
|
+
# aliased_associations hash.
|
313
|
+
aliased = meth
|
314
|
+
if as && a = as.fetch(meth, nil)
|
315
|
+
aliased = a.to_s
|
316
|
+
end
|
317
|
+
|
318
|
+
field = nil
|
319
|
+
klass = nil
|
320
|
+
if fs && f = fs[aliased]
|
321
|
+
field = f
|
322
|
+
yield(meth, f, true) if block_given?
|
323
|
+
elsif rs && rel = rs[aliased]
|
324
|
+
klass = rel.klass
|
325
|
+
yield(meth, rel, false) if block_given?
|
326
|
+
else
|
327
|
+
yield(meth, nil, false) if block_given?
|
328
|
+
end
|
329
|
+
end
|
330
|
+
field
|
288
331
|
end
|
289
332
|
|
290
333
|
# Get the name of the provided field as it is stored in the database.
|
@@ -292,16 +335,43 @@ module Mongoid
|
|
292
335
|
# finds aliases for embedded documents and fields, delimited with
|
293
336
|
# period "." character.
|
294
337
|
#
|
295
|
-
#
|
296
|
-
#
|
338
|
+
# Note that this method returns the name of associations as they're
|
339
|
+
# stored in the database, whereas the `relations` hash uses their in-code
|
340
|
+
# aliases. In order to check for membership in the relations hash, you
|
341
|
+
# would first have to look up the string returned from this method in
|
342
|
+
# the aliased_associations hash.
|
343
|
+
#
|
344
|
+
# This method will not expand the alias of a belongs_to association that
|
345
|
+
# is not the last item. For example, if we had a School that has_many
|
346
|
+
# Students, and the field name passed was (from the Student's perspective):
|
347
|
+
#
|
348
|
+
# school._id
|
349
|
+
#
|
350
|
+
# The alias for a belongs_to association is that association's _id field.
|
351
|
+
# Therefore, expanding out this association would yield:
|
352
|
+
#
|
353
|
+
# school_id._id
|
297
354
|
#
|
298
|
-
#
|
299
|
-
#
|
355
|
+
# This is not the correct field name, because the intention here was not
|
356
|
+
# to get a property of the _id field. The intention was to get a property
|
357
|
+
# of the referenced document. Therefore, if a part of the name passed is
|
358
|
+
# a belongs_to association that is not the last part of the name, we
|
359
|
+
# won't expand its alias, and return:
|
360
|
+
#
|
361
|
+
# school._id
|
362
|
+
#
|
363
|
+
# If the belongs_to association is the last part of the name, we will
|
364
|
+
# pass back the _id field.
|
300
365
|
#
|
301
366
|
# @param [ String, Symbol ] name The name to get.
|
367
|
+
# @param [ Hash ] relations The associations.
|
368
|
+
# @param [ Hash ] alaiased_fields The aliased fields.
|
369
|
+
# @param [ Hash ] alaiased_associations The aliased associations.
|
302
370
|
#
|
303
371
|
# @return [ String ] The name of the field as stored in the database.
|
304
|
-
|
372
|
+
#
|
373
|
+
# @api private
|
374
|
+
def database_field_name(name, relations, aliased_fields, aliased_associations)
|
305
375
|
if Mongoid.broken_alias_handling
|
306
376
|
return nil unless name
|
307
377
|
normalized = name.to_s
|
@@ -310,31 +380,68 @@ module Mongoid
|
|
310
380
|
return nil unless name.present?
|
311
381
|
key = name.to_s
|
312
382
|
segment, remaining = key.split('.', 2)
|
313
|
-
|
383
|
+
|
384
|
+
# Don't get the alias for the field when a belongs_to association
|
385
|
+
# is not the last item. Therefore, get the alias when one of the
|
386
|
+
# following is true:
|
387
|
+
# 1. This is the last item, i.e. there is no remaining.
|
388
|
+
# 2. It is not an association.
|
389
|
+
# 3. It is not a belongs association
|
390
|
+
if !remaining || !relations.key?(segment) || !relations[segment].is_a?(Association::Referenced::BelongsTo)
|
391
|
+
segment = aliased_fields[segment]&.dup || segment
|
392
|
+
end
|
393
|
+
|
314
394
|
return segment unless remaining
|
315
395
|
|
316
396
|
relation = relations[aliased_associations[segment] || segment]
|
317
397
|
if relation
|
318
|
-
|
398
|
+
k = relation.klass
|
399
|
+
"#{segment}.#{database_field_name(remaining, k.relations, k.aliased_fields, k.aliased_associations)}"
|
319
400
|
else
|
320
401
|
"#{segment}.#{remaining}"
|
321
402
|
end
|
322
403
|
end
|
323
404
|
end
|
405
|
+
end
|
406
|
+
|
407
|
+
module ClassMethods
|
408
|
+
|
409
|
+
# Returns an array of names for the attributes available on this object.
|
410
|
+
#
|
411
|
+
# Provides the field names in an ORM-agnostic way. Rails v3.1+ uses this
|
412
|
+
# method to automatically wrap params in JSON requests.
|
413
|
+
#
|
414
|
+
# @example Get the field names
|
415
|
+
# Model.attribute_names
|
416
|
+
#
|
417
|
+
# @return [ Array<String> ] The field names
|
418
|
+
def attribute_names
|
419
|
+
fields.keys
|
420
|
+
end
|
421
|
+
|
422
|
+
# Get the name of the provided field as it is stored in the database.
|
423
|
+
# Used in determining if the field is aliased or not.
|
424
|
+
#
|
425
|
+
# @param [ String, Symbol ] name The name to get.
|
426
|
+
#
|
427
|
+
# @return [ String ] The name of the field as it's stored in the db.
|
428
|
+
def database_field_name(name)
|
429
|
+
Fields.database_field_name(name, relations, aliased_fields, aliased_associations)
|
430
|
+
end
|
324
431
|
|
325
432
|
# Defines all the fields that are accessible on the Document
|
326
433
|
# For each field that is defined, a getter and setter will be
|
327
434
|
# added as an instance method to the Document.
|
328
435
|
#
|
329
436
|
# @example Define a field.
|
330
|
-
# field :score, :
|
437
|
+
# field :score, type: Integer, default: 0
|
331
438
|
#
|
332
439
|
# @param [ Symbol ] name The name of the field.
|
333
440
|
# @param [ Hash ] options The options to pass to the field.
|
334
441
|
#
|
335
|
-
# @option options [ Class ] :type The type of the field.
|
442
|
+
# @option options [ Class | Symbol | String ] :type The type of the field.
|
336
443
|
# @option options [ String ] :label The label for the field.
|
337
|
-
# @option options [ Object
|
444
|
+
# @option options [ Object | Proc ] :default The field's default.
|
338
445
|
#
|
339
446
|
# @return [ Field ] The generated field
|
340
447
|
def field(name, options = {})
|
@@ -372,6 +479,23 @@ module Mongoid
|
|
372
479
|
fields["_id"].object_id_field?
|
373
480
|
end
|
374
481
|
|
482
|
+
# Traverse down the association tree and search for the field for the
|
483
|
+
# given key.
|
484
|
+
#
|
485
|
+
# @param [ String ] key The key used to search the association tree.
|
486
|
+
# @param [ Proc ] block The block takes in three paramaters, the current
|
487
|
+
# meth, the field or the relation, and whether the second parameter is a
|
488
|
+
# field or not.
|
489
|
+
#
|
490
|
+
# @return [ Field ] The field found for the given key at the end of the
|
491
|
+
# search. This will return nil if the last thing found is an association
|
492
|
+
# or no field was found for the given key.
|
493
|
+
#
|
494
|
+
# @api private
|
495
|
+
def traverse_association_tree(key, &block)
|
496
|
+
Fields.traverse_association_tree(key, fields, relations, aliased_associations, &block)
|
497
|
+
end
|
498
|
+
|
375
499
|
protected
|
376
500
|
|
377
501
|
# Add the defaults to the model. This breaks them up between ones that
|
data/lib/mongoid/findable.rb
CHANGED
@@ -41,9 +41,12 @@ module Mongoid
|
|
41
41
|
:pluck,
|
42
42
|
:read,
|
43
43
|
:sum,
|
44
|
+
:take,
|
45
|
+
:take!,
|
46
|
+
:tally,
|
44
47
|
:text_search,
|
45
48
|
:update,
|
46
|
-
:update_all
|
49
|
+
:update_all,
|
47
50
|
|
48
51
|
# Returns a count of records in the database.
|
49
52
|
# If you want to specify conditions use where.
|
@@ -179,9 +182,15 @@ module Mongoid
|
|
179
182
|
# @example Find the first document.
|
180
183
|
# Person.first
|
181
184
|
#
|
185
|
+
# @param [ Integer | Hash ] limit_or_opts The number of documents to
|
186
|
+
# return, or a hash of options.
|
187
|
+
#
|
188
|
+
# @option limit_or_opts [ :none ] :id_sort This option is deprecated.
|
189
|
+
# Don't apply a sort on _id if no other sort is defined on the criteria.
|
190
|
+
#
|
182
191
|
# @return [ Document ] The first matching document.
|
183
|
-
def first
|
184
|
-
with_default_scope.first
|
192
|
+
def first(limit_or_opts = nil)
|
193
|
+
with_default_scope.first(limit_or_opts)
|
185
194
|
end
|
186
195
|
alias :one :first
|
187
196
|
|
@@ -190,9 +199,15 @@ module Mongoid
|
|
190
199
|
# @example Find the last document.
|
191
200
|
# Person.last
|
192
201
|
#
|
202
|
+
# @param [ Integer | Hash ] limit_or_opts The number of documents to
|
203
|
+
# return, or a hash of options.
|
204
|
+
#
|
205
|
+
# @option limit_or_opts [ :none ] :id_sort This option is deprecated.
|
206
|
+
# Don't apply a sort on _id if no other sort is defined on the criteria.
|
207
|
+
#
|
193
208
|
# @return [ Document ] The last matching document.
|
194
|
-
def last
|
195
|
-
with_default_scope.last
|
209
|
+
def last(limit_or_opts = nil)
|
210
|
+
with_default_scope.last(limit_or_opts)
|
196
211
|
end
|
197
212
|
end
|
198
213
|
end
|
data/lib/mongoid/version.rb
CHANGED
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mongoid
|
4
|
+
|
5
|
+
# Encapsulates behavior around logging and caching warnings so they are only
|
6
|
+
# logged once.
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
module Warnings
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def warning(id, message)
|
13
|
+
singleton_class.class_eval do
|
14
|
+
define_method("warn_#{id}") do
|
15
|
+
unless instance_variable_get("@#{id}")
|
16
|
+
Mongoid.logger.warn(message)
|
17
|
+
instance_variable_set("@#{id}", true)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
warning :id_sort_deprecated, 'The :id_sort option has been deprecated. Use Mongo#take to get a document without a sort on _id.'
|
25
|
+
warning :criteria_cache_deprecated, 'The criteria cache has been deprecated and will be removed in Mongoid 8. Please enable the Mongoid QueryCache to have caching functionality.'
|
26
|
+
warning :map_field_deprecated, 'The field argument to the Mongo#map method has been deprecated, please pass in a block instead. Support will be dropped in Mongoid 8.'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
data/lib/mongoid.rb
CHANGED
@@ -23,6 +23,7 @@ require "mongoid/clients"
|
|
23
23
|
require "mongoid/document"
|
24
24
|
require "mongoid/tasks/database"
|
25
25
|
require "mongoid/query_cache"
|
26
|
+
require "mongoid/warnings"
|
26
27
|
|
27
28
|
# If we are using Rails then we will include the Mongoid railtie. This has all
|
28
29
|
# the nifty initializers that Mongoid needs.
|
@@ -125,9 +125,6 @@ development:
|
|
125
125
|
# database name is not explicitly defined. (default: nil)
|
126
126
|
# app_name: MyApplicationName
|
127
127
|
|
128
|
-
# Create indexes in background by default. (default: false)
|
129
|
-
# background_indexing: false
|
130
|
-
|
131
128
|
# Mark belongs_to associations as required by default, so that saving a
|
132
129
|
# model with a missing belongs_to association will trigger a validation
|
133
130
|
# error. (default: true)
|
@@ -172,6 +169,10 @@ development:
|
|
172
169
|
# (default: false)
|
173
170
|
# use_utc: false
|
174
171
|
|
172
|
+
# (Deprecated) In MongoDB 4.0 and earlier, set whether to create
|
173
|
+
# indexes in the background by default. (default: false)
|
174
|
+
# background_indexing: false
|
175
|
+
|
175
176
|
test:
|
176
177
|
clients:
|
177
178
|
default:
|
@@ -23,6 +23,10 @@ describe 'i18n fallbacks' do
|
|
23
23
|
I18n.fallbacks[:de] = [ :en ]
|
24
24
|
end
|
25
25
|
|
26
|
+
after do
|
27
|
+
I18n.locale = :en
|
28
|
+
end
|
29
|
+
|
26
30
|
context 'when translation is present in active locale' do
|
27
31
|
it 'uses active locale' do
|
28
32
|
product = Product.new
|
@@ -36,6 +40,9 @@ describe 'i18n fallbacks' do
|
|
36
40
|
end
|
37
41
|
|
38
42
|
context 'when translation is missing in active locale and present in fallback locale' do
|
43
|
+
after do
|
44
|
+
I18n.locale = :en
|
45
|
+
end
|
39
46
|
|
40
47
|
it 'falls back on default locale' do
|
41
48
|
product = Product.new
|
@@ -57,6 +64,10 @@ describe 'i18n fallbacks' do
|
|
57
64
|
end
|
58
65
|
end
|
59
66
|
|
67
|
+
after do
|
68
|
+
I18n.locale = :en
|
69
|
+
end
|
70
|
+
|
60
71
|
it 'returns nil' do
|
61
72
|
product = Product.new
|
62
73
|
I18n.locale = :en
|
@@ -75,6 +86,10 @@ describe 'i18n fallbacks' do
|
|
75
86
|
end
|
76
87
|
end
|
77
88
|
|
89
|
+
after do
|
90
|
+
I18n.locale = :en
|
91
|
+
end
|
92
|
+
|
78
93
|
it 'falls back on default locale' do
|
79
94
|
product = Product.new
|
80
95
|
I18n.locale = :en
|
@@ -82,7 +97,6 @@ describe 'i18n fallbacks' do
|
|
82
97
|
I18n.locale = :ru
|
83
98
|
product.description.should == 'Marvelous!'
|
84
99
|
end
|
85
|
-
|
86
100
|
end
|
87
101
|
end
|
88
102
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "spec_helper"
|
4
|
-
require_relative '../embeds_many_models.rb'
|
5
4
|
|
6
5
|
describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
|
7
6
|
|
@@ -4650,24 +4649,4 @@ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
|
|
4650
4649
|
end
|
4651
4650
|
end
|
4652
4651
|
end
|
4653
|
-
|
4654
|
-
context "when using assign_attributes with an already populated array" do
|
4655
|
-
let(:post) { EmmPost.create! }
|
4656
|
-
|
4657
|
-
before do
|
4658
|
-
post.assign_attributes(company_tags: [{id: BSON::ObjectId.new, title: 'a'}],
|
4659
|
-
user_tags: [{id: BSON::ObjectId.new, title: 'b'}])
|
4660
|
-
post.save!
|
4661
|
-
post.reload
|
4662
|
-
post.assign_attributes(company_tags: [{id: BSON::ObjectId.new, title: 'c'}],
|
4663
|
-
user_tags: [])
|
4664
|
-
post.save!
|
4665
|
-
post.reload
|
4666
|
-
end
|
4667
|
-
|
4668
|
-
it "has the correct embedded documents" do
|
4669
|
-
expect(post.company_tags.length).to eq(1)
|
4670
|
-
expect(post.company_tags.first.title).to eq("c")
|
4671
|
-
end
|
4672
|
-
end
|
4673
4652
|
end
|