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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/lib/config/locales/en.yml +7 -0
  4. data/lib/mongoid/association/embedded/batchable.rb +3 -20
  5. data/lib/mongoid/association/macros.rb +20 -0
  6. data/lib/mongoid/association/referenced/has_many/enumerable.rb +12 -8
  7. data/lib/mongoid/association/referenced/has_many/proxy.rb +2 -2
  8. data/lib/mongoid/atomic/paths/embedded/many.rb +0 -19
  9. data/lib/mongoid/config.rb +6 -1
  10. data/lib/mongoid/contextual/memory.rb +144 -12
  11. data/lib/mongoid/contextual/mongo.rb +118 -26
  12. data/lib/mongoid/contextual/none.rb +45 -1
  13. data/lib/mongoid/criteria/queryable/extensions/array.rb +2 -0
  14. data/lib/mongoid/criteria/queryable/extensions/hash.rb +2 -0
  15. data/lib/mongoid/criteria/queryable/mergeable.rb +21 -0
  16. data/lib/mongoid/criteria/queryable/selectable.rb +26 -10
  17. data/lib/mongoid/criteria.rb +2 -0
  18. data/lib/mongoid/document.rb +2 -0
  19. data/lib/mongoid/equality.rb +4 -4
  20. data/lib/mongoid/errors/document_not_found.rb +23 -6
  21. data/lib/mongoid/fields.rb +145 -21
  22. data/lib/mongoid/findable.rb +20 -5
  23. data/lib/mongoid/version.rb +1 -1
  24. data/lib/mongoid/warnings.rb +29 -0
  25. data/lib/mongoid.rb +1 -0
  26. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +4 -3
  27. data/spec/integration/i18n_fallbacks_spec.rb +15 -1
  28. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +0 -21
  29. data/spec/mongoid/association/embedded/embeds_many_models.rb +0 -121
  30. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +0 -8
  31. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +54 -0
  32. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +8 -24
  33. data/spec/mongoid/clients/options_spec.rb +1 -0
  34. data/spec/mongoid/config_spec.rb +10 -4
  35. data/spec/mongoid/contextual/memory_spec.rb +826 -65
  36. data/spec/mongoid/contextual/mongo_spec.rb +781 -18
  37. data/spec/mongoid/contextual/none_spec.rb +46 -0
  38. data/spec/mongoid/criteria/queryable/selectable_spec.rb +212 -39
  39. data/spec/mongoid/criteria_spec.rb +8 -0
  40. data/spec/mongoid/equality_spec.rb +12 -12
  41. data/spec/mongoid/errors/document_not_found_spec.rb +49 -0
  42. data/spec/mongoid/findable_spec.rb +30 -0
  43. data/spec/support/models/code.rb +2 -0
  44. data.tar.gz.sig +0 -0
  45. metadata +3 -2
  46. metadata.gz.sig +0 -0
@@ -142,6 +142,8 @@ module Mongoid
142
142
  # @param [ Proc ] block The block to execute on each value.
143
143
  #
144
144
  # @return [ Hash ] the hash.
145
+ #
146
+ # @deprecated
145
147
  def update_values(&block)
146
148
  each_pair do |key, value|
147
149
  store(key, block[value])
@@ -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
- __override__(criterion, "$elemMatch")
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
- __override__(criterion, "$eq")
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
- __override__(criterion, "$gt")
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
- __override__(criterion, "$gte")
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
- __override__(criterion, "$lt")
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
- __override__(criterion, "$lte")
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
- __override__(criterion, "$mod")
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
- __override__(criterion, "$ne")
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
- __override__(criterion, "$near")
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
- __override__(criterion, "$nearSphere")
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.
@@ -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
 
@@ -143,6 +143,8 @@ module Mongoid
143
143
  # document.to_a
144
144
  #
145
145
  # @return [ Array<Document> ] An array with the document as its only item.
146
+ #
147
+ # @deprecated
146
148
  def to_a
147
149
  [ self ]
148
150
  end
@@ -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
- case params
98
- when Hash then "document_with_attributes_not_found"
99
- else "document_not_found"
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
@@ -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
- # Returns an array of names for the attributes available on this object.
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
- # Provides the field names in an ORM-agnostic way. Rails v3.1+ uses this
280
- # method to automatically wrap params in JSON requests.
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
- # @example Get the field names
283
- # Model.attribute_names
282
+ # The next iteration will use klass's fields and associations to continue
283
+ # traversing the tree.
284
284
  #
285
- # @return [ Array<String> ] The field names
286
- def attribute_names
287
- fields.keys
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
- # @example Get the database field name of a field.
296
- # Model.database_field_name(:authorization)
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
- # @example Get the database field name of an embedded field.
299
- # Model.database_field_name('customers.addresses.city')
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
- def database_field_name(name)
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
- segment = aliased_fields[segment]&.dup || segment
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
- "#{segment}.#{relation.klass.database_field_name(remaining)}"
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, :type => Integer, :default => 0
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, Proc ] :default The field's default
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
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mongoid
4
- VERSION = "7.4.3"
4
+ VERSION = "7.5.0"
5
5
  end
@@ -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