mongoid 7.4.3 → 7.5.0

Sign up to get free protection for your applications and to get access to all the features.
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