mongoid 7.2.4 → 7.3.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 (173) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/README.md +1 -1
  5. data/Rakefile +16 -0
  6. data/lib/config/locales/en.yml +2 -2
  7. data/lib/mongoid/association/accessors.rb +1 -1
  8. data/lib/mongoid/association/constrainable.rb +1 -1
  9. data/lib/mongoid/association/depending.rb +4 -4
  10. data/lib/mongoid/association/embedded/batchable.rb +1 -1
  11. data/lib/mongoid/association/embedded/embedded_in.rb +1 -1
  12. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +10 -3
  13. data/lib/mongoid/association/nested/many.rb +1 -1
  14. data/lib/mongoid/association/nested/one.rb +4 -2
  15. data/lib/mongoid/association/proxy.rb +6 -1
  16. data/lib/mongoid/association/referenced/auto_save.rb +2 -2
  17. data/lib/mongoid/association/referenced/has_many/enumerable.rb +493 -495
  18. data/lib/mongoid/association/referenced/has_many/proxy.rb +2 -2
  19. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +2 -2
  20. data/lib/mongoid/attributes.rb +24 -13
  21. data/lib/mongoid/attributes/projector.rb +120 -0
  22. data/lib/mongoid/cacheable.rb +2 -2
  23. data/lib/mongoid/clients.rb +1 -1
  24. data/lib/mongoid/clients/factory.rb +22 -8
  25. data/lib/mongoid/config.rb +19 -2
  26. data/lib/mongoid/contextual/aggregable/mongo.rb +10 -8
  27. data/lib/mongoid/copyable.rb +1 -1
  28. data/lib/mongoid/criteria.rb +4 -5
  29. data/lib/mongoid/criteria/findable.rb +1 -1
  30. data/lib/mongoid/criteria/queryable/expandable.rb +0 -24
  31. data/lib/mongoid/criteria/queryable/extensions.rb +0 -4
  32. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
  33. data/lib/mongoid/criteria/queryable/mergeable.rb +46 -20
  34. data/lib/mongoid/criteria/queryable/selectable.rb +8 -8
  35. data/lib/mongoid/document.rb +1 -15
  36. data/lib/mongoid/errors/delete_restriction.rb +8 -9
  37. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  38. data/lib/mongoid/evolvable.rb +1 -1
  39. data/lib/mongoid/extensions/boolean.rb +1 -2
  40. data/lib/mongoid/extensions/false_class.rb +1 -1
  41. data/lib/mongoid/extensions/hash.rb +2 -2
  42. data/lib/mongoid/extensions/true_class.rb +1 -1
  43. data/lib/mongoid/fields.rb +43 -5
  44. data/lib/mongoid/inspectable.rb +1 -1
  45. data/lib/mongoid/matcher.rb +7 -0
  46. data/lib/mongoid/matcher/bits.rb +41 -0
  47. data/lib/mongoid/matcher/bits_all_clear.rb +20 -0
  48. data/lib/mongoid/matcher/bits_all_set.rb +20 -0
  49. data/lib/mongoid/matcher/bits_any_clear.rb +20 -0
  50. data/lib/mongoid/matcher/bits_any_set.rb +20 -0
  51. data/lib/mongoid/matcher/expression.rb +4 -0
  52. data/lib/mongoid/matcher/field_operator.rb +6 -0
  53. data/lib/mongoid/matcher/mod.rb +17 -0
  54. data/lib/mongoid/matcher/type.rb +99 -0
  55. data/lib/mongoid/persistable/deletable.rb +1 -2
  56. data/lib/mongoid/persistable/destroyable.rb +8 -2
  57. data/lib/mongoid/persistable/updatable.rb +27 -2
  58. data/lib/mongoid/query_cache.rb +35 -29
  59. data/lib/mongoid/selectable.rb +5 -7
  60. data/lib/mongoid/shardable.rb +21 -5
  61. data/lib/mongoid/touchable.rb +23 -4
  62. data/lib/mongoid/validatable/associated.rb +1 -1
  63. data/lib/mongoid/validatable/presence.rb +3 -3
  64. data/lib/mongoid/validatable/uniqueness.rb +1 -1
  65. data/lib/mongoid/version.rb +1 -1
  66. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +1 -1
  67. data/spec/integration/app_spec.rb +0 -3
  68. data/spec/integration/associations/embeds_many_spec.rb +44 -0
  69. data/spec/integration/associations/has_one_spec.rb +48 -0
  70. data/spec/integration/criteria/date_field_spec.rb +1 -1
  71. data/spec/integration/document_spec.rb +9 -0
  72. data/spec/integration/matcher_operator_data/bits_all_clear.yml +159 -0
  73. data/spec/integration/matcher_operator_data/bits_all_set.yml +159 -0
  74. data/spec/integration/matcher_operator_data/bits_any_clear.yml +159 -0
  75. data/spec/integration/matcher_operator_data/bits_any_set.yml +159 -0
  76. data/spec/integration/matcher_operator_data/comment.yml +22 -0
  77. data/spec/integration/matcher_operator_data/in.yml +16 -0
  78. data/spec/integration/matcher_operator_data/mod.yml +55 -0
  79. data/spec/integration/matcher_operator_data/type.yml +70 -0
  80. data/spec/integration/matcher_operator_data/type_array.yml +16 -0
  81. data/spec/integration/matcher_operator_data/type_binary.yml +18 -0
  82. data/spec/integration/matcher_operator_data/type_boolean.yml +39 -0
  83. data/spec/integration/matcher_operator_data/type_code.yml +26 -0
  84. data/spec/integration/matcher_operator_data/type_code_with_scope.yml +26 -0
  85. data/spec/integration/matcher_operator_data/type_date.yml +39 -0
  86. data/spec/integration/matcher_operator_data/type_db_pointer.yml +19 -0
  87. data/spec/integration/matcher_operator_data/type_decimal.yml +40 -0
  88. data/spec/integration/matcher_operator_data/type_double.yml +15 -0
  89. data/spec/integration/matcher_operator_data/type_int32.yml +33 -0
  90. data/spec/integration/matcher_operator_data/type_int64.yml +33 -0
  91. data/spec/integration/matcher_operator_data/type_max_key.yml +17 -0
  92. data/spec/integration/matcher_operator_data/type_min_key.yml +17 -0
  93. data/spec/integration/matcher_operator_data/type_null.yml +23 -0
  94. data/spec/integration/matcher_operator_data/type_object.yml +23 -0
  95. data/spec/integration/matcher_operator_data/type_object_id.yml +25 -0
  96. data/spec/integration/matcher_operator_data/type_regex.yml +44 -0
  97. data/spec/integration/matcher_operator_data/type_string.yml +15 -0
  98. data/spec/integration/matcher_operator_data/type_symbol.yml +32 -0
  99. data/spec/integration/matcher_operator_data/type_timestamp.yml +25 -0
  100. data/spec/integration/matcher_operator_data/type_undefined.yml +17 -0
  101. data/spec/lite_spec_helper.rb +2 -0
  102. data/spec/mongoid/association/depending_spec.rb +391 -352
  103. data/spec/mongoid/association/nested/one_spec.rb +18 -14
  104. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +25 -8
  105. data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +1 -1
  106. data/spec/mongoid/association/referenced/has_many/binding_spec.rb +1 -1
  107. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +1 -1
  108. data/spec/mongoid/association/referenced/has_one_models.rb +8 -0
  109. data/spec/mongoid/atomic/paths_spec.rb +64 -12
  110. data/spec/mongoid/attributes/projector_data/embedded.yml +105 -0
  111. data/spec/mongoid/attributes/projector_data/fields.yml +93 -0
  112. data/spec/mongoid/attributes/projector_spec.rb +41 -0
  113. data/spec/mongoid/attributes_spec.rb +98 -6
  114. data/spec/mongoid/clients/factory_spec.rb +48 -0
  115. data/spec/mongoid/config_spec.rb +32 -0
  116. data/spec/mongoid/contextual/mongo_spec.rb +2 -2
  117. data/spec/mongoid/criteria/modifiable_spec.rb +1 -1
  118. data/spec/mongoid/criteria/queryable/expandable_spec.rb +0 -73
  119. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +1 -1
  120. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +105 -7
  121. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +229 -24
  122. data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +39 -0
  123. data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -565
  124. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +590 -0
  125. data/spec/mongoid/criteria_projection_spec.rb +411 -0
  126. data/spec/mongoid/criteria_spec.rb +0 -275
  127. data/spec/mongoid/document_query_spec.rb +0 -51
  128. data/spec/mongoid/document_spec.rb +13 -13
  129. data/spec/mongoid/errors/delete_restriction_spec.rb +1 -1
  130. data/spec/mongoid/errors/mongoid_error_spec.rb +8 -20
  131. data/spec/mongoid/extensions/false_class_spec.rb +1 -1
  132. data/spec/mongoid/extensions/string_spec.rb +5 -5
  133. data/spec/mongoid/extensions/true_class_spec.rb +1 -1
  134. data/spec/mongoid/fields/localized_spec.rb +4 -4
  135. data/spec/mongoid/fields_spec.rb +4 -4
  136. data/spec/mongoid/inspectable_spec.rb +12 -4
  137. data/spec/mongoid/persistable/deletable_spec.rb +175 -1
  138. data/spec/mongoid/persistable/destroyable_spec.rb +191 -3
  139. data/spec/mongoid/persistable/savable_spec.rb +3 -5
  140. data/spec/mongoid/persistable/upsertable_spec.rb +1 -1
  141. data/spec/mongoid/persistable_spec.rb +2 -2
  142. data/spec/mongoid/query_cache_middleware_spec.rb +8 -0
  143. data/spec/mongoid/reloadable_spec.rb +18 -1
  144. data/spec/mongoid/shardable_spec.rb +44 -0
  145. data/spec/mongoid/touchable_spec.rb +104 -16
  146. data/spec/mongoid/touchable_spec_models.rb +52 -0
  147. data/spec/mongoid/validatable_spec.rb +1 -1
  148. data/spec/shared/lib/mrss/cluster_config.rb +3 -8
  149. data/spec/shared/lib/mrss/constraints.rb +6 -20
  150. data/spec/shared/lib/mrss/docker_runner.rb +1 -7
  151. data/spec/shared/lib/mrss/spec_organizer.rb +1 -18
  152. data/spec/shared/share/Dockerfile.erb +30 -121
  153. data/spec/shared/shlib/server.sh +4 -31
  154. data/spec/shared/shlib/set_env.sh +1 -4
  155. data/spec/spec_helper.rb +7 -3
  156. data/spec/support/client_registry.rb +9 -0
  157. data/spec/support/models/bolt.rb +8 -0
  158. data/spec/support/models/hole.rb +13 -0
  159. data/spec/support/models/mop.rb +0 -1
  160. data/spec/support/models/nut.rb +8 -0
  161. data/spec/support/models/person.rb +6 -0
  162. data/spec/support/models/sealer.rb +8 -0
  163. data/spec/support/models/shirt.rb +12 -0
  164. data/spec/support/models/spacer.rb +8 -0
  165. data/spec/support/models/threadlocker.rb +8 -0
  166. data/spec/support/models/washer.rb +8 -0
  167. metadata +620 -534
  168. metadata.gz.sig +5 -3
  169. data/spec/shared/bin/s3-copy +0 -45
  170. data/spec/shared/bin/s3-upload +0 -69
  171. data/spec/shared/share/haproxy-1.conf +0 -16
  172. data/spec/shared/share/haproxy-2.conf +0 -17
  173. data/spec/support/cluster_config.rb +0 -158
@@ -220,7 +220,7 @@ module Mongoid
220
220
  #
221
221
  # @since 2.0.0.beta.1
222
222
  def initialize(base, target, association)
223
- enum = HasMany::Targets::Enumerable.new(target, base, association)
223
+ enum = HasMany::Enumerable.new(target, base, association)
224
224
  init(base, enum, association) do
225
225
  raise_mixed if klass.embedded? && !klass.cyclic?
226
226
  end
@@ -367,7 +367,7 @@ module Mongoid
367
367
  document.persisted? &&
368
368
  document._association &&
369
369
  document.respond_to?(document._association.foreign_key) &&
370
- document.__send__(document._association.foreign_key) == _base.id
370
+ document.__send__(document._association.foreign_key) == _base._id
371
371
  end
372
372
 
373
373
  # Instantiate the binding associated with this association.
@@ -69,7 +69,7 @@ module Mongoid
69
69
  #
70
70
  # @since 2.0.0
71
71
  def acceptable_id?
72
- id = convert_id(existing.class, attributes[:id])
72
+ id = convert_id(existing.class, attributes[:_id])
73
73
  existing._id == id || id.nil? || (existing._id != id && update_only?)
74
74
  end
75
75
 
@@ -82,7 +82,7 @@ module Mongoid
82
82
  #
83
83
  # @since 2.0.0
84
84
  def delete?
85
- destroyable? && !attributes[:id].nil?
85
+ destroyable? && !attributes[:_id].nil?
86
86
  end
87
87
 
88
88
  # Can the existing association potentially be destroyed?
@@ -5,6 +5,7 @@ require "active_model/attribute_methods"
5
5
  require "mongoid/attributes/dynamic"
6
6
  require "mongoid/attributes/nested"
7
7
  require "mongoid/attributes/processing"
8
+ require "mongoid/attributes/projector"
8
9
  require "mongoid/attributes/readonly"
9
10
 
10
11
  module Mongoid
@@ -238,11 +239,7 @@ module Mongoid
238
239
  #
239
240
  # @since 4.0.0
240
241
  def attribute_missing?(name)
241
- selection = __selected_fields
242
- return false unless selection
243
- field = fields[name]
244
- (selection.values.first == 0 && selection_excluded?(name, selection, field)) ||
245
- (selection.values.first == 1 && !selection_included?(name, selection, field))
242
+ !Projector.new(__selected_fields).attribute_or_path_allowed?(name)
246
243
  end
247
244
 
248
245
  # Return type-casted attributes.
@@ -259,14 +256,6 @@ module Mongoid
259
256
 
260
257
  private
261
258
 
262
- def selection_excluded?(name, selection, field)
263
- selection[name] == 0
264
- end
265
-
266
- def selection_included?(name, selection, field)
267
- selection.key?(name) || selection.keys.collect { |k| k.partition('.').first }.include?(name)
268
- end
269
-
270
259
  # Does the string contain dot syntax for accessing hashes?
271
260
  #
272
261
  # @api private
@@ -300,9 +289,11 @@ module Mongoid
300
289
 
301
290
  def read_raw_attribute(name)
302
291
  normalized = database_field_name(name.to_s)
292
+
303
293
  if attribute_missing?(normalized)
304
294
  raise ActiveModel::MissingAttributeError, "Missing attribute: '#{name}'"
305
295
  end
296
+
306
297
  if hash_dot_syntax?(normalized)
307
298
  attributes.__nested__(normalized)
308
299
  else
@@ -341,6 +332,26 @@ module Mongoid
341
332
  alias_method "#{name}_will_change!", "#{original}_will_change!"
342
333
  alias_method "#{name}_before_type_cast", "#{original}_before_type_cast"
343
334
  end
335
+
336
+ # Removes a field alias.
337
+ #
338
+ # @param [ Symbol ] name The aliased field name to remove.
339
+ def unalias_attribute(name)
340
+ unless aliased_fields.delete(name.to_s)
341
+ raise AttributeError, "Field #{name} is not an aliased field"
342
+ end
343
+
344
+ remove_method name
345
+ remove_method "#{name}="
346
+ remove_method "#{name}?"
347
+ remove_method "#{name}_change"
348
+ remove_method "#{name}_changed?"
349
+ remove_method "reset_#{name}!"
350
+ remove_method "reset_#{name}_to_default!"
351
+ remove_method "#{name}_was"
352
+ remove_method "#{name}_will_change!"
353
+ remove_method "#{name}_before_type_cast"
354
+ end
344
355
  end
345
356
 
346
357
  private
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ module Mongoid
5
+ module Attributes
6
+
7
+ # This module defines projection helpers.
8
+ #
9
+ # Projection rules are rather non-trivial. See
10
+ # https://docs.mongodb.com/manual/reference/method/db.collection.find/#find-projection
11
+ # for server documentation.
12
+ # 4.4 server (and presumably all older ones) requires that a projection
13
+ # for content fields is either exclusionary or inclusionary, i.e. one
14
+ # cannot mix exclusions and inclusions in the same query.
15
+ # However, _id can be excluded in a projection that includes content
16
+ # fields.
17
+ # Integer projection values other than 0 and 1 aren't officially
18
+ # documented as of this writing; see DOCSP-15266.
19
+ # 4.4 server also allows nested hash projection specification
20
+ # in addition to dot notation, which I assume Mongoid doesn't handle yet.
21
+ #
22
+ # @api private
23
+ class Projector
24
+ def initialize(projection)
25
+ if projection
26
+ @content_projection = projection.dup
27
+ @content_projection.delete('_id')
28
+ @id_projection_value = projection['_id']
29
+ else
30
+ @content_projection = nil
31
+ @id_projection_value = nil
32
+ end
33
+ end
34
+
35
+ attr_reader :id_projection_value
36
+ attr_reader :content_projection
37
+
38
+ # Determine if the specified attribute, or a dot notation path, is allowed
39
+ # by the configured projection, if any.
40
+ #
41
+ # If there is no configured projection, returns true.
42
+ #
43
+ # @param [ String ] name The name of the attribute or a dot notation path.
44
+ #
45
+ # @return [ true, false ] Whether the attribute is allowed by projection.
46
+ #
47
+ # @api private
48
+ def attribute_or_path_allowed?(name)
49
+ # Special handling for _id.
50
+ if name == '_id'
51
+ result = unless id_projection_value.nil?
52
+ value_inclusionary?(id_projection_value)
53
+ else
54
+ true
55
+ end
56
+ return result
57
+ end
58
+
59
+ if content_projection.nil?
60
+ # No projection (as opposed to an empty projection).
61
+ # All attributes are allowed.
62
+ return true
63
+ end
64
+
65
+ # Find an item which matches or is a parent of the requested name/path.
66
+ # This handles the case when, for example, the projection was
67
+ # {foo: true} and we want to know if foo.bar is allowed.
68
+ item, value = content_projection.detect do |path, value|
69
+ (name + '.').start_with?(path + '.')
70
+ end
71
+ if item
72
+ return value_inclusionary?(value)
73
+ end
74
+
75
+ if content_inclusionary?
76
+ # Find an item which would be a strict child of the requested name/path.
77
+ # This handles the case when, for example, the projection was
78
+ # {"foo.bar" => true} and we want to know if foo is allowed.
79
+ # (It is as a container of bars.)
80
+ item, value = content_projection.detect do |path, value|
81
+ (path + '.').start_with?(name + '.')
82
+ end
83
+ if item
84
+ return true
85
+ end
86
+ end
87
+
88
+ !content_inclusionary?
89
+ end
90
+
91
+ private
92
+
93
+ # Determines whether the projection for content fields is inclusionary.
94
+ #
95
+ # An empty projection is inclusionary.
96
+ def content_inclusionary?
97
+ if content_projection.empty?
98
+ return value_inclusionary?(id_projection_value)
99
+ end
100
+
101
+ value_inclusionary?(content_projection.values.first)
102
+ end
103
+
104
+ def value_inclusionary?(value)
105
+ case value
106
+ when Integer
107
+ value >= 1
108
+ when true
109
+ true
110
+ when false
111
+ false
112
+ else
113
+ # The various expressions that are permitted as projection arguments
114
+ # imply an inclusionary projection.
115
+ true
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
@@ -31,8 +31,8 @@ module Mongoid
31
31
  # @since 2.4.0
32
32
  def cache_key
33
33
  return "#{model_key}/new" if new_record?
34
- return "#{model_key}/#{id}-#{updated_at.utc.to_s(cache_timestamp_format)}" if do_or_do_not(:updated_at)
35
- "#{model_key}/#{id}"
34
+ return "#{model_key}/#{_id}-#{updated_at.utc.to_s(cache_timestamp_format)}" if do_or_do_not(:updated_at)
35
+ "#{model_key}/#{_id}"
36
36
  end
37
37
  end
38
38
  end
@@ -59,7 +59,7 @@ module Mongoid
59
59
  # @example Get a client with the name.
60
60
  # Mongoid::Clients.with_name(:replica)
61
61
  #
62
- # @param [ Symbol ] name The name of the client.
62
+ # @param [ String | Symbol ] name The name of the client.
63
63
  #
64
64
  # @return [ Mongo::Client ] The named client.
65
65
  #
@@ -5,6 +5,7 @@ module Mongoid
5
5
  module Clients
6
6
  module Factory
7
7
  extend self
8
+ extend Loggable
8
9
 
9
10
  # Create a new client given the named configuration. If no name is
10
11
  # provided, return a new client with the default configuration. If a
@@ -59,12 +60,20 @@ module Mongoid
59
60
  # @since 3.0.0
60
61
  def create_client(configuration)
61
62
  raise Errors::NoClientsConfig.new unless configuration
62
- if configuration[:uri]
63
- Mongo::Client.new(configuration[:uri], options(configuration))
63
+ config = configuration.dup
64
+ uri = config.delete(:uri)
65
+ database = config.delete(:database)
66
+ hosts = config.delete(:hosts)
67
+ opts = config.delete(:options) || {}
68
+ unless config.empty?
69
+ default_logger.warn("Unknown config options detected: #{config}.")
70
+ end
71
+ if uri
72
+ Mongo::Client.new(uri, options(opts))
64
73
  else
65
74
  Mongo::Client.new(
66
- configuration[:hosts],
67
- options(configuration).merge(database: configuration[:database])
75
+ hosts,
76
+ options(opts).merge(database: database)
68
77
  )
69
78
  end
70
79
  end
@@ -78,9 +87,14 @@ module Mongoid
78
87
  Mongo::VERSION.split('.')[0...2].map(&:to_i)
79
88
  end
80
89
 
81
- def options(configuration)
82
- config = configuration.dup
83
- options = config.delete(:options) || {}
90
+ # Prepare options for Mongo::Client based on Mongoid client configuration.
91
+ #
92
+ # @param [ Hash ] opts Parameters from options section of Mongoid client configuration.
93
+ # @return [ Hash ] Options that should be passed to Mongo::Client constructor.
94
+ #
95
+ # @api private
96
+ def options(opts)
97
+ options = opts.dup
84
98
  options[:platform] = PLATFORM_DETAILS
85
99
  options[:app_name] = Mongoid::Config.app_name if Mongoid::Config.app_name
86
100
  if (driver_version <=> [2, 13]) >= 0
@@ -91,7 +105,7 @@ module Mongoid
91
105
  end
92
106
  options[:wrapping_libraries] = wrap_lib
93
107
  end
94
- options.reject{ |k, v| k == :hosts }.to_hash.symbolize_keys!
108
+ options.reject{ |k, _v| k == :hosts }.to_hash.symbolize_keys!
95
109
  end
96
110
  end
97
111
  end
@@ -220,7 +220,7 @@ module Mongoid
220
220
  #
221
221
  # @since 2.0.2
222
222
  def purge!
223
- Clients.default.database.collections.each(&:drop) and true
223
+ global_client.database.collections.each(&:drop) and true
224
224
  end
225
225
 
226
226
  # Truncate all data in all collections, but not the indexes.
@@ -234,7 +234,7 @@ module Mongoid
234
234
  #
235
235
  # @since 2.0.2
236
236
  def truncate!
237
- Clients.default.database.collections.each do |collection|
237
+ global_client.database.collections.each do |collection|
238
238
  collection.find.delete_many
239
239
  end and true
240
240
  end
@@ -305,5 +305,22 @@ module Mongoid
305
305
  Validators::Client.validate(c)
306
306
  @clients = c
307
307
  end
308
+
309
+ # Get database client that respects global overrides
310
+ # Config.override_database and Config.override_client.
311
+ #
312
+ # @return [Mongo::Client] Client according to global overrides.
313
+ def global_client
314
+ client = if Threaded.client_override
315
+ Clients.with_name(Threaded.client_override)
316
+ else
317
+ Clients.default
318
+ end
319
+ if Threaded.database_override
320
+ client.use(Threaded.database_override)
321
+ else
322
+ client
323
+ end
324
+ end
308
325
  end
309
326
  end
@@ -11,17 +11,19 @@ module Mongoid
11
11
  #
12
12
  # @example Get all the aggregate values.
13
13
  # aggregable.aggregates(:likes)
14
+ # # => {
15
+ # # "count" => 2.0,
16
+ # # "max" => 1000.0,
17
+ # # "min" => 500.0,
18
+ # # "sum" => 1500.0,
19
+ # # "avg" => 750.0
20
+ # # }
14
21
  #
15
22
  # @param [ String, Symbol ] field The field name.
16
23
  #
17
- # @return [ Hash ] count is a number of documents with the provided field. If there're none, then count is 0 and max, min, sum, avg are nil.
18
- # {
19
- # "count" => 2.0,
20
- # "max" => 1000.0,
21
- # "min" => 500.0,
22
- # "sum" => 1500.0,
23
- # "avg" => 750.0
24
- # }
24
+ # @return [ Hash ] count is a number of documents with the provided
25
+ # field. If there're none, then count is 0 and max, min, sum, avg
26
+ # are nil.
25
27
  #
26
28
  # @since 3.0.0
27
29
  def aggregates(field)
@@ -21,7 +21,7 @@ module Mongoid
21
21
  # @note This next line is here to address #2704, even though having an
22
22
  # _id and id field in the document would cause problems with Mongoid
23
23
  # elsewhere.
24
- attrs = clone_document.except("_id", "id")
24
+ attrs = clone_document.except(*self.class.id_fields)
25
25
  dynamic_attrs = {}
26
26
  _attribute_names = self.attribute_names
27
27
  attrs.reject! do |attr_name, value|
@@ -336,16 +336,15 @@ module Mongoid
336
336
  #
337
337
  # @since 1.0.0
338
338
  def only(*args)
339
- return clone if args.flatten.empty?
340
339
  args = args.flatten
340
+ return clone if args.empty?
341
341
  if (args & Fields::IDS).empty?
342
342
  args.unshift(:_id)
343
343
  end
344
344
  if klass.hereditary?
345
- super(*args.push(klass.discriminator_key.to_sym))
346
- else
347
- super(*args)
345
+ args.push(klass.discriminator_key.to_sym)
348
346
  end
347
+ super(*args)
349
348
  end
350
349
 
351
350
  # Set the read preference for the criteria.
@@ -375,7 +374,7 @@ module Mongoid
375
374
  #
376
375
  # @since 4.0.3
377
376
  def without(*args)
378
- args -= Fields::IDS
377
+ args -= id_fields
379
378
  super(*args)
380
379
  end
381
380
 
@@ -132,7 +132,7 @@ module Mongoid
132
132
  # @since 3.0.0
133
133
  def mongoize_ids(ids)
134
134
  ids.map do |id|
135
- id = id[:id] if id.respond_to?(:keys) && id[:id]
135
+ id = id[:_id] if id.respond_to?(:keys) && id[:_id]
136
136
  klass.fields["_id"].mongoize(id)
137
137
  end
138
138
  end
@@ -15,30 +15,6 @@ module Mongoid
15
15
 
16
16
  private
17
17
 
18
- # Expands the specified condition to MongoDB syntax.
19
- #
20
- # The condition must be a hash in one of the following forms:
21
- # - {field_name: value}
22
- # - {'field_name' => value}
23
- # - {key_instance: value}
24
- # - {'$operator' => operator_value_expression}
25
- #
26
- # This method expands the key instance form to the the operator form,
27
- # and also converts hash key to string.
28
- #
29
- # The hash may contain multiple items, each representing a separate
30
- # condition.
31
- #
32
- # @param [ Hash ] condition The condition to expand.
33
- #
34
- # @return [ Hash ] The expanded condition.
35
- def expand_condition(condition)
36
- mapped = condition.map do |field, value|
37
- expand_one_condition(field, value)
38
- end
39
- Hash[mapped]
40
- end
41
-
42
18
  # Expands the specified condition to MongoDB syntax.
43
19
  #
44
20
  # This method is meant to be called when processing the items of