mongoid 8.0.10 → 8.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +3 -3
  4. data/README.md +3 -3
  5. data/Rakefile +18 -67
  6. data/lib/config/locales/en.yml +46 -14
  7. data/lib/mongoid/association/accessors.rb +3 -7
  8. data/lib/mongoid/association/builders.rb +1 -1
  9. data/lib/mongoid/association/eager_loadable.rb +0 -3
  10. data/lib/mongoid/association/embedded/batchable.rb +2 -2
  11. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +2 -2
  12. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +2 -1
  13. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +3 -2
  14. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +6 -6
  15. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +1 -1
  16. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +1 -1
  17. data/lib/mongoid/association/macros.rb +0 -6
  18. data/lib/mongoid/association/nested/one.rb +40 -2
  19. data/lib/mongoid/association/proxy.rb +1 -1
  20. data/lib/mongoid/association/referenced/counter_cache.rb +2 -2
  21. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +1 -1
  22. data/lib/mongoid/association/referenced/has_many/enumerable.rb +6 -23
  23. data/lib/mongoid/association/referenced/has_many/proxy.rb +3 -3
  24. data/lib/mongoid/association/reflections.rb +2 -2
  25. data/lib/mongoid/atomic.rb +7 -16
  26. data/lib/mongoid/attributes/dynamic.rb +1 -1
  27. data/lib/mongoid/attributes/nested.rb +2 -2
  28. data/lib/mongoid/attributes/processing.rb +5 -29
  29. data/lib/mongoid/attributes/projector.rb +1 -1
  30. data/lib/mongoid/attributes/readonly.rb +1 -1
  31. data/lib/mongoid/attributes.rb +8 -2
  32. data/lib/mongoid/changeable.rb +107 -5
  33. data/lib/mongoid/clients/storage_options.rb +2 -5
  34. data/lib/mongoid/clients/validators/storage.rb +1 -13
  35. data/lib/mongoid/collection_configurable.rb +58 -0
  36. data/lib/mongoid/composable.rb +2 -0
  37. data/lib/mongoid/config/defaults.rb +60 -0
  38. data/lib/mongoid/config/options.rb +0 -3
  39. data/lib/mongoid/config/validators/async_query_executor.rb +24 -0
  40. data/lib/mongoid/config/validators.rb +1 -0
  41. data/lib/mongoid/config.rb +88 -27
  42. data/lib/mongoid/contextual/atomic.rb +1 -1
  43. data/lib/mongoid/contextual/memory.rb +233 -33
  44. data/lib/mongoid/contextual/mongo/documents_loader.rb +177 -0
  45. data/lib/mongoid/contextual/mongo.rb +370 -133
  46. data/lib/mongoid/contextual/none.rb +162 -7
  47. data/lib/mongoid/contextual.rb +12 -0
  48. data/lib/mongoid/criteria/findable.rb +2 -2
  49. data/lib/mongoid/criteria/includable.rb +4 -3
  50. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -15
  51. data/lib/mongoid/criteria/queryable/key.rb +1 -1
  52. data/lib/mongoid/criteria/queryable/mergeable.rb +1 -1
  53. data/lib/mongoid/criteria/queryable/optional.rb +8 -8
  54. data/lib/mongoid/criteria/queryable/selectable.rb +43 -12
  55. data/lib/mongoid/criteria/queryable/selector.rb +1 -1
  56. data/lib/mongoid/criteria/queryable/storable.rb +1 -1
  57. data/lib/mongoid/criteria.rb +6 -5
  58. data/lib/mongoid/deprecable.rb +1 -2
  59. data/lib/mongoid/deprecation.rb +3 -3
  60. data/lib/mongoid/document.rb +1 -8
  61. data/lib/mongoid/errors/create_collection_failure.rb +33 -0
  62. data/lib/mongoid/errors/drop_collection_failure.rb +27 -0
  63. data/lib/mongoid/errors/immutable_attribute.rb +26 -0
  64. data/lib/mongoid/errors/invalid_async_query_executor.rb +25 -0
  65. data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +22 -0
  66. data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
  67. data/lib/mongoid/errors.rb +4 -1
  68. data/lib/mongoid/extensions/hash.rb +2 -24
  69. data/lib/mongoid/extensions/object.rb +2 -2
  70. data/lib/mongoid/extensions/time.rb +2 -0
  71. data/lib/mongoid/fields/localized.rb +10 -0
  72. data/lib/mongoid/fields/standard.rb +10 -0
  73. data/lib/mongoid/fields.rb +59 -35
  74. data/lib/mongoid/findable.rb +27 -3
  75. data/lib/mongoid/interceptable.rb +6 -116
  76. data/lib/mongoid/matcher/eq_impl.rb +1 -1
  77. data/lib/mongoid/matcher/type.rb +1 -1
  78. data/lib/mongoid/persistable/creatable.rb +1 -0
  79. data/lib/mongoid/persistable/deletable.rb +1 -1
  80. data/lib/mongoid/persistable/savable.rb +13 -1
  81. data/lib/mongoid/persistable/unsettable.rb +2 -2
  82. data/lib/mongoid/persistable/updatable.rb +51 -1
  83. data/lib/mongoid/persistable/upsertable.rb +20 -1
  84. data/lib/mongoid/persistable.rb +3 -0
  85. data/lib/mongoid/query_cache.rb +5 -1
  86. data/lib/mongoid/railties/database.rake +7 -2
  87. data/lib/mongoid/reloadable.rb +5 -3
  88. data/lib/mongoid/stateful.rb +22 -1
  89. data/lib/mongoid/tasks/database.rake +12 -0
  90. data/lib/mongoid/tasks/database.rb +20 -0
  91. data/lib/mongoid/timestamps/created.rb +1 -8
  92. data/lib/mongoid/traversable.rb +0 -12
  93. data/lib/mongoid/utils.rb +22 -0
  94. data/lib/mongoid/validatable/associated.rb +17 -98
  95. data/lib/mongoid/validatable/macros.rb +5 -5
  96. data/lib/mongoid/validatable.rb +4 -9
  97. data/lib/mongoid/version.rb +1 -1
  98. data/lib/mongoid/warnings.rb +17 -1
  99. data/lib/mongoid.rb +16 -3
  100. data/spec/integration/app_spec.rb +2 -6
  101. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +0 -40
  102. data/spec/integration/callbacks_spec.rb +99 -12
  103. data/spec/integration/discriminator_key_spec.rb +4 -5
  104. data/spec/integration/i18n_fallbacks_spec.rb +3 -2
  105. data/spec/mongoid/association/eager_spec.rb +2 -24
  106. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +27 -0
  107. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +20 -25
  108. data/spec/mongoid/association/embedded/embeds_many_models.rb +1 -0
  109. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +0 -4
  110. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +15 -2
  111. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -18
  112. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +42 -55
  113. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +9 -50
  114. data/spec/mongoid/association/syncable_spec.rb +1 -1
  115. data/spec/mongoid/association_spec.rb +0 -60
  116. data/spec/mongoid/attributes_spec.rb +3 -33
  117. data/spec/mongoid/changeable_spec.rb +299 -24
  118. data/spec/mongoid/clients_spec.rb +122 -13
  119. data/spec/mongoid/collection_configurable_spec.rb +158 -0
  120. data/spec/mongoid/config/defaults_spec.rb +160 -0
  121. data/spec/mongoid/config_spec.rb +154 -27
  122. data/spec/mongoid/contextual/memory_spec.rb +332 -76
  123. data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +187 -0
  124. data/spec/mongoid/contextual/mongo_spec.rb +1009 -125
  125. data/spec/mongoid/contextual/none_spec.rb +49 -2
  126. data/spec/mongoid/copyable_spec.rb +2 -10
  127. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +4 -10
  128. data/spec/mongoid/criteria/queryable/options_spec.rb +1 -1
  129. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +419 -0
  130. data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -1
  131. data/spec/mongoid/criteria/queryable/selector_spec.rb +3 -76
  132. data/spec/mongoid/criteria/queryable/storable_spec.rb +0 -72
  133. data/spec/mongoid/criteria_projection_spec.rb +1 -4
  134. data/spec/mongoid/criteria_spec.rb +5 -9
  135. data/spec/mongoid/document_spec.rb +0 -27
  136. data/spec/mongoid/errors/readonly_document_spec.rb +2 -2
  137. data/spec/mongoid/extensions/hash_spec.rb +3 -3
  138. data/spec/mongoid/extensions/time_spec.rb +8 -43
  139. data/spec/mongoid/extensions/time_with_zone_spec.rb +7 -52
  140. data/spec/mongoid/fields/localized_spec.rb +46 -28
  141. data/spec/mongoid/fields_spec.rb +136 -77
  142. data/spec/mongoid/findable_spec.rb +391 -34
  143. data/spec/mongoid/indexable_spec.rb +16 -10
  144. data/spec/mongoid/interceptable_spec.rb +153 -442
  145. data/spec/mongoid/interceptable_spec_models.rb +111 -51
  146. data/spec/mongoid/persistable/deletable_spec.rb +26 -6
  147. data/spec/mongoid/persistable/destroyable_spec.rb +26 -6
  148. data/spec/mongoid/persistable/incrementable_spec.rb +37 -0
  149. data/spec/mongoid/persistable/logical_spec.rb +37 -0
  150. data/spec/mongoid/persistable/poppable_spec.rb +36 -0
  151. data/spec/mongoid/persistable/pullable_spec.rb +72 -0
  152. data/spec/mongoid/persistable/pushable_spec.rb +72 -0
  153. data/spec/mongoid/persistable/renamable_spec.rb +36 -0
  154. data/spec/mongoid/persistable/savable_spec.rb +96 -0
  155. data/spec/mongoid/persistable/settable_spec.rb +37 -0
  156. data/spec/mongoid/persistable/unsettable_spec.rb +36 -0
  157. data/spec/mongoid/persistable/updatable_spec.rb +20 -28
  158. data/spec/mongoid/persistable/upsertable_spec.rb +80 -6
  159. data/spec/mongoid/persistence_context_spec.rb +7 -57
  160. data/spec/mongoid/query_cache_spec.rb +56 -61
  161. data/spec/mongoid/reloadable_spec.rb +24 -28
  162. data/spec/mongoid/scopable_spec.rb +70 -0
  163. data/spec/mongoid/serializable_spec.rb +23 -44
  164. data/spec/mongoid/stateful_spec.rb +122 -8
  165. data/spec/mongoid/tasks/database_rake_spec.rb +74 -0
  166. data/spec/mongoid/tasks/database_spec.rb +127 -0
  167. data/spec/mongoid/timestamps/created_spec.rb +0 -23
  168. data/spec/mongoid/timestamps_spec.rb +9 -11
  169. data/spec/mongoid/touchable_spec.rb +277 -5
  170. data/spec/mongoid/touchable_spec_models.rb +3 -1
  171. data/spec/mongoid/traversable_spec.rb +9 -24
  172. data/spec/mongoid/validatable/associated_spec.rb +34 -27
  173. data/spec/mongoid/validatable/uniqueness_spec.rb +2 -3
  174. data/spec/mongoid_spec.rb +36 -10
  175. data/spec/shared/LICENSE +20 -0
  176. data/spec/shared/bin/get-mongodb-download-url +17 -0
  177. data/spec/shared/bin/s3-copy +45 -0
  178. data/spec/shared/bin/s3-upload +69 -0
  179. data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
  180. data/spec/shared/lib/mrss/cluster_config.rb +231 -0
  181. data/spec/shared/lib/mrss/constraints.rb +378 -0
  182. data/spec/shared/lib/mrss/docker_runner.rb +298 -0
  183. data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
  184. data/spec/shared/lib/mrss/event_subscriber.rb +210 -0
  185. data/spec/shared/lib/mrss/lite_constraints.rb +238 -0
  186. data/spec/shared/lib/mrss/server_version_registry.rb +113 -0
  187. data/spec/shared/lib/mrss/session_registry.rb +69 -0
  188. data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
  189. data/spec/shared/lib/mrss/spec_organizer.rb +179 -0
  190. data/spec/shared/lib/mrss/utils.rb +37 -0
  191. data/spec/shared/share/Dockerfile.erb +321 -0
  192. data/spec/shared/share/haproxy-1.conf +16 -0
  193. data/spec/shared/share/haproxy-2.conf +17 -0
  194. data/spec/shared/shlib/config.sh +27 -0
  195. data/spec/shared/shlib/distro.sh +74 -0
  196. data/spec/shared/shlib/server.sh +416 -0
  197. data/spec/shared/shlib/set_env.sh +169 -0
  198. data/spec/spec_helper.rb +5 -0
  199. data/spec/support/immutable_ids.rb +118 -0
  200. data/spec/support/macros.rb +47 -15
  201. data/spec/support/models/artist.rb +0 -1
  202. data/spec/support/models/band.rb +1 -0
  203. data/spec/support/models/building.rb +2 -0
  204. data/spec/support/models/name.rb +0 -10
  205. data/spec/support/models/person.rb +0 -1
  206. data/spec/support/models/product.rb +1 -0
  207. data.tar.gz.sig +0 -0
  208. metadata +745 -637
  209. metadata.gz.sig +2 -0
  210. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -60
  211. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -60
  212. data/spec/support/models/purse.rb +0 -9
@@ -80,15 +80,24 @@ module Mongoid
80
80
  # @example Do any documents exist in the null context.
81
81
  # context.exists?
82
82
  #
83
+ # @example Do any documents exist for given _id.
84
+ # context.exists?(BSON::ObjectId(...))
85
+ #
86
+ # @example Do any documents exist for given conditions.
87
+ # context.exists?(name: "...")
88
+ #
89
+ # @param [ Hash | Object | false ] id_or_conditions an _id to
90
+ # search for, a hash of conditions, nil or false.
91
+ #
83
92
  # @return [ false ] Always false.
84
- def exists?; false; end
93
+ def exists?(id_or_conditions = :none); false; end
85
94
 
86
95
  # Pluck the field values in null context.
87
96
  #
88
97
  # @example Get the values for null context.
89
98
  # context.pluck(:name)
90
99
  #
91
- # @param [ String | Symbol ] *_fields Field(s) to pluck.
100
+ # @param [ [ String | Symbol ]... ] *_fields Field(s) to pluck.
92
101
  #
93
102
  # @return [ Array ] An empty Array.
94
103
  def pluck(*_fields)
@@ -100,9 +109,9 @@ module Mongoid
100
109
  # @example Get the value for null context.
101
110
  # context.pick(:name)
102
111
  #
103
- # @param [ String | Symbol ] *_fields Field or fields to pick.
112
+ # @param [ [ String | Symbol ]... ] *_fields Field(s) to pick.
104
113
  #
105
- # @return [ nil ] Always reeturn nil.
114
+ # @return [ nil ] Always return nil.
106
115
  def pick(*_fields)
107
116
  nil
108
117
  end
@@ -136,11 +145,21 @@ module Mongoid
136
145
  #
137
146
  # @param [ Integer ] limit The number of documents to return.
138
147
  #
139
- # @return [ nil ] Always nil.
148
+ # @return [ [] | nil ] Empty array or nil.
140
149
  def first(limit = nil)
141
150
  [] unless limit.nil?
142
151
  end
143
152
 
153
+ # Always raises an error.
154
+ #
155
+ # @example Get the first document in null context.
156
+ # context.first!
157
+ #
158
+ # @raises [ Mongoid::Errors::DocumentNotFound ] always raises.
159
+ def first!
160
+ raise_document_not_found_error
161
+ end
162
+
144
163
  # Always returns nil.
145
164
  #
146
165
  # @example Get the last document in null context.
@@ -148,11 +167,21 @@ module Mongoid
148
167
  #
149
168
  # @param [ Integer ] limit The number of documents to return.
150
169
  #
151
- # @return [ nil ] Always nil.
170
+ # @return [ [] | nil ] Empty array or nil.
152
171
  def last(limit = nil)
153
172
  [] unless limit.nil?
154
173
  end
155
174
 
175
+ # Always raises an error.
176
+ #
177
+ # @example Get the last document in null context.
178
+ # context.last!
179
+ #
180
+ # @raises [ Mongoid::Errors::DocumentNotFound ] always raises.
181
+ def last!
182
+ raise_document_not_found_error
183
+ end
184
+
156
185
  # Returns nil or empty array.
157
186
  #
158
187
  # @example Take a document in null context.
@@ -172,7 +201,127 @@ module Mongoid
172
201
  #
173
202
  # @raises [ Mongoid::Errors::DocumentNotFound ] always raises.
174
203
  def take!
175
- raise Errors::DocumentNotFound.new(klass, nil, nil)
204
+ raise_document_not_found_error
205
+ end
206
+
207
+ # Always returns nil.
208
+ #
209
+ # @example Get the second document in null context.
210
+ # context.second
211
+ #
212
+ # @return [ nil ] Always nil.
213
+ def second
214
+ nil
215
+ end
216
+
217
+ # Always raises an error.
218
+ #
219
+ # @example Get the second document in null context.
220
+ # context.second!
221
+ #
222
+ # @raises [ Mongoid::Errors::DocumentNotFound ] always raises.
223
+ def second!
224
+ raise_document_not_found_error
225
+ end
226
+
227
+ # Always returns nil.
228
+ #
229
+ # @example Get the third document in null context.
230
+ # context.third
231
+ #
232
+ # @return [ nil ] Always nil.
233
+ def third
234
+ nil
235
+ end
236
+
237
+ # Always raises an error.
238
+ #
239
+ # @example Get the third document in null context.
240
+ # context.third!
241
+ #
242
+ # @raises [ Mongoid::Errors::DocumentNotFound ] always raises.
243
+ def third!
244
+ raise_document_not_found_error
245
+ end
246
+
247
+ # Always returns nil.
248
+ #
249
+ # @example Get the fourth document in null context.
250
+ # context.fourth
251
+ #
252
+ # @return [ nil ] Always nil.
253
+ def fourth
254
+ nil
255
+ end
256
+
257
+ # Always raises an error.
258
+ #
259
+ # @example Get the fourth document in null context.
260
+ # context.fourth!
261
+ #
262
+ # @raises [ Mongoid::Errors::DocumentNotFound ] always raises.
263
+ def fourth!
264
+ raise_document_not_found_error
265
+ end
266
+
267
+ # Always returns nil.
268
+ #
269
+ # @example Get the fifth document in null context.
270
+ # context.fifth
271
+ #
272
+ # @return [ nil ] Always nil.
273
+ def fifth
274
+ nil
275
+ end
276
+
277
+ # Always raises an error.
278
+ #
279
+ # @example Get the fifth document in null context.
280
+ # context.fifth!
281
+ #
282
+ # @raises [ Mongoid::Errors::DocumentNotFound ] always raises.
283
+ def fifth!
284
+ raise_document_not_found_error
285
+ end
286
+
287
+ # Always returns nil.
288
+ #
289
+ # @example Get the second to last document in null context.
290
+ # context.second_to_last
291
+ #
292
+ # @return [ nil ] Always nil.
293
+ def second_to_last
294
+ nil
295
+ end
296
+
297
+ # Always raises an error.
298
+ #
299
+ # @example Get the second to last document in null context.
300
+ # context.second_to_last!
301
+ #
302
+ # @raises [ Mongoid::Errors::DocumentNotFound ] always raises.
303
+ def second_to_last!
304
+ raise_document_not_found_error
305
+ end
306
+
307
+ # Always returns nil.
308
+ #
309
+ # @example Get the third to last document in null context.
310
+ # context.third_to_last
311
+ #
312
+ # @return [ nil ] Always nil.
313
+ def third_to_last
314
+ nil
315
+ end
316
+
317
+ # Always raises an error.
318
+ #
319
+ # @example Get the third to last document in null context.
320
+ # context.third_to_last!
321
+ #
322
+ # @raises [ Mongoid::Errors::DocumentNotFound ] always raises.
323
+ def third_to_last!
324
+ raise_document_not_found_error
176
325
  end
177
326
 
178
327
  # Always returns zero.
@@ -188,6 +337,12 @@ module Mongoid
188
337
 
189
338
  alias :find_first :first
190
339
  alias :one :first
340
+
341
+ private
342
+
343
+ def raise_document_not_found_error
344
+ raise Errors::DocumentNotFound.new(klass, nil, nil)
345
+ end
191
346
  end
192
347
  end
193
348
  end
@@ -35,6 +35,18 @@ module Mongoid
35
35
  @context ||= create_context
36
36
  end
37
37
 
38
+ # Instructs the context to schedule an asynchronous loading of documents
39
+ # specified by the criteria.
40
+ #
41
+ # Note that depending on the context and on the Mongoid configuration,
42
+ # documents can be loaded synchronously on the caller's thread.
43
+ #
44
+ # @return [ Criteria ] Returns self.
45
+ def load_async
46
+ context.load_async if context.respond_to?(:load_async)
47
+ self
48
+ end
49
+
38
50
  private
39
51
 
40
52
  # Create the context for the queries to execute. Will be memory for
@@ -21,7 +21,7 @@ module Mongoid
21
21
  multi ? result : result.first
22
22
  end
23
23
 
24
- # Find the matchind document(s) in the criteria for the provided ids.
24
+ # Find the matching document(s) in the criteria for the provided id(s).
25
25
  #
26
26
  # @note Each argument can be an individual id, an array of ids or
27
27
  # a nested array. Each array will be flattened.
@@ -32,7 +32,7 @@ module Mongoid
32
32
  # @example Find by multiple ids.
33
33
  # criteria.find([ BSON::ObjectId.new, BSON::ObjectId.new ])
34
34
  #
35
- # @param [ Object | Array<Object> ] *args The ids to search for.
35
+ # @param [ [ Object | Array<Object> ]... ] *args The id(s) to find.
36
36
  #
37
37
  # @return [ Document | Array<Document> ] The matching document(s).
38
38
  def find(*args)
@@ -21,8 +21,8 @@ module Mongoid
21
21
  # @example Eager load the provided associations.
22
22
  # Person.includes(:posts, :game)
23
23
  #
24
- # @param [ Array<Symbol>, Array<Hash> ] relations The names of the associations to eager
25
- # load.
24
+ # @param [ [ Symbol | Hash ]... ] *relations The names of the association(s)
25
+ # to eager load.
26
26
  #
27
27
  # @return [ Criteria ] The cloned criteria.
28
28
  def includes(*relations)
@@ -70,7 +70,8 @@ module Mongoid
70
70
  # association originates.
71
71
  # @param [ String ] parent The name of the association above this one in
72
72
  # the inclusion tree, if it is a nested inclusion.
73
- # @param relations_list The names of the associations to eager load.
73
+ # @param [ [ Symbol | Hash | Array<Symbol | Hash> ]... ] *relations_list
74
+ # The names of the association(s) to eager load.
74
75
  def extract_includes_list(_parent_class, parent, *relations_list)
75
76
  relations_list.flatten.each do |relation_object|
76
77
  if relation_object.is_a?(Hash)
@@ -43,21 +43,7 @@ module Mongoid
43
43
  #
44
44
  # @return [ Object ] The converted number.
45
45
  def __numeric__(object)
46
- str = object.to_s
47
- raise ArgumentError if str.empty?
48
-
49
- # These requirements seem a bit odd, but they're explicitly specified in the tests,
50
- # so we're obligated to keep them, for now. (This code was rewritten from a one-line
51
- # regex, due to security concerns with a polynomial regex being used on uncontrolled
52
- # data).
53
-
54
- str = str.chop if str.end_with?('.')
55
- return 0 if str.empty?
56
-
57
- result = Integer(str) rescue Float(object)
58
-
59
- integer = result.to_i
60
- integer == result ? integer : result
46
+ object.to_s.match?(/\A[-+]?[0-9]*[0-9.]0*\z/) ? object.to_i : Float(object)
61
47
  end
62
48
 
63
49
  # Evolve the object to an integer.
@@ -91,7 +91,7 @@ module Mongoid
91
91
 
92
92
  # Calculate the hash code for a key.
93
93
  #
94
- # @return [ Fixnum ] The hash code for the key.
94
+ # @return [ Integer ] The hash code for the key.
95
95
  def hash
96
96
  [name, operator, expanded].hash
97
97
  end
@@ -283,7 +283,7 @@ module Mongoid
283
283
  # The new value is a simple value.
284
284
  # Transform the implicit equality to either $eq or $regexp
285
285
  # depending on the type of the argument. See
286
- # https://docs.mongodb.com/manual/reference/operator/query/eq/#std-label-eq-usage-examples
286
+ # https://www.mongodb.com/docs/manual/reference/operator/query/eq/#std-label-eq-usage-examples
287
287
  # for the description of relevant server behavior.
288
288
  op = case v
289
289
  when Regexp, BSON::Regexp::Raw
@@ -17,7 +17,7 @@ module Mongoid
17
17
  # @example Add ascending sorting.
18
18
  # optional.ascending(:first_name, :last_name)
19
19
  #
20
- # @param [ Array<Symbol> ] fields The fields to sort.
20
+ # @param [ Symbol... ] *fields The field(s) to sort.
21
21
  #
22
22
  # @return [ Optional ] The cloned optional.
23
23
  def ascending(*fields)
@@ -45,7 +45,7 @@ module Mongoid
45
45
  # @example Add descending sorting.
46
46
  # optional.descending(:first_name, :last_name)
47
47
  #
48
- # @param [ Array<Symbol> ] fields The fields to sort.
48
+ # @param [ Symbol... ] *fields The field(s) to sort.
49
49
  #
50
50
  # @return [ Optional ] The cloned optional.
51
51
  def descending(*fields)
@@ -123,7 +123,7 @@ module Mongoid
123
123
  # @example Limit the results to the provided fields.
124
124
  # optional.only(:name, :dob)
125
125
  #
126
- # @param [ Array<Symbol> ] args The fields to return.
126
+ # @param [ Symbol... ] *args The field(s) to return.
127
127
  #
128
128
  # @return [ Optional ] The cloned optional.
129
129
  def only(*args)
@@ -163,7 +163,7 @@ module Mongoid
163
163
  # @example Add sorting options via a string.
164
164
  # optional.order_by("name ASC, dob DESC")
165
165
  #
166
- # @param [ Array | Hash | String ] spec The sorting specification.
166
+ # @param [ [ Array | Hash | String ]... ] *spec The sorting specification.
167
167
  #
168
168
  # @return [ Optional ] The cloned optional.
169
169
  def order_by(*spec)
@@ -184,7 +184,7 @@ module Mongoid
184
184
  # @example Replace the ordering.
185
185
  # optional.reorder(name: :asc)
186
186
  #
187
- # @param [ Array | Hash | String ] spec The sorting specification.
187
+ # @param [ [ Array | Hash | String ]... ] *spec The sorting specification.
188
188
  #
189
189
  # @return [ Optional ] The cloned optional.
190
190
  def reorder(*spec)
@@ -245,7 +245,7 @@ module Mongoid
245
245
  # @example Limit the results to the fields not provided.
246
246
  # optional.without(:name, :dob)
247
247
  #
248
- # @param [ Array<Symbol> ] args The fields to ignore.
248
+ # @param [ Symbol... ] *args The field(s) to ignore.
249
249
  #
250
250
  # @return [ Optional ] The cloned optional.
251
251
  def without(*args)
@@ -331,7 +331,7 @@ module Mongoid
331
331
  # @example Store the option.
332
332
  # optional.option({ skip: 10 })
333
333
  #
334
- # @param [ Array ] args The options.
334
+ # @param [ Object... ] *args The options.
335
335
  #
336
336
  # @return [ Queryable ] The cloned queryable.
337
337
  def option(*args)
@@ -349,7 +349,7 @@ module Mongoid
349
349
  # @example Add multiple sort options.
350
350
  # optional.sort_with_list(:name, :dob, 1)
351
351
  #
352
- # @param [ Array<String> ] fields The field names.
352
+ # @param [ [ Symbol | String ]... ] *fields The field name(s).
353
353
  # @param [ Integer ] direction The sort direction.
354
354
  #
355
355
  # @return [ Optional ] The cloned optional.
@@ -31,7 +31,7 @@ module Mongoid
31
31
  # @example Execute an $all in a where query.
32
32
  # selectable.where(:field.all => [ 1, 2 ])
33
33
  #
34
- # @param [ Hash ] criterion The key value pairs for $all matching.
34
+ # @param [ Hash... ] *criteria The key value pair(s) for $all matching.
35
35
  #
36
36
  # @return [ Selectable ] The cloned selectable.
37
37
  def all(*criteria)
@@ -69,8 +69,9 @@ module Mongoid
69
69
  # @example Add the criterion.
70
70
  # selectable.and({ field: value }, { other: value })
71
71
  #
72
- # @param [ Array<Hash | Criteria> ] criteria Multiple key/value pair
73
- # matches or Criteria objects that all must match to return results.
72
+ # @param [ [ Hash | Criteria | Array<Hash | Criteria> ]... ] *criteria
73
+ # Multiple key/value pair matches or Criteria objects that all must
74
+ # match to return results.
74
75
  #
75
76
  # @return [ Selectable ] The new selectable.
76
77
  def and(*criteria)
@@ -199,7 +200,7 @@ module Mongoid
199
200
  # the upper right (north east) as the second argument.
200
201
  # Important: When latitude and longitude are passed, longitude is
201
202
  # expected as the first element of the coordinate pair.
202
- # Source: https://docs.mongodb.com/manual/reference/operator/query/box/
203
+ # Source: https://www.mongodb.com/docs/manual/reference/operator/query/box/
203
204
  #
204
205
  # @example Add a geo intersect criterion for a line.
205
206
  # query.geo_spatial(:location.intersects_line => [[ 1, 10 ], [ 2, 10 ]])
@@ -516,8 +517,8 @@ module Mongoid
516
517
  # @example Add the $nor selection.
517
518
  # selectable.nor(field: 1, field: 2)
518
519
  #
519
- # @param [ Array<Hash | Criteria> ] criteria Multiple key/value pair
520
- # matches or Criteria objects.
520
+ # @param [ [ Hash | Criteria | Array<Hash | Criteria> ]... ] *criteria
521
+ # Multiple key/value pair matches or Criteria objects.
521
522
  #
522
523
  # @return [ Selectable ] The new selectable.
523
524
  def nor(*criteria)
@@ -545,7 +546,7 @@ module Mongoid
545
546
  # @example Execute a $not in a where query.
546
547
  # selectable.where(:field.not => /Bob/)
547
548
  #
548
- # @param [ Array<Hash | Criteria> ] criteria Multiple key/value pair
549
+ # @param [ [ Hash | Criteria ]... ] *criteria The key/value pair
549
550
  # matches or Criteria objects to negate.
550
551
  #
551
552
  # @return [ Selectable ] The new selectable.
@@ -580,6 +581,35 @@ module Mongoid
580
581
  end
581
582
  key :not, :override, "$not"
582
583
 
584
+ # Negate the arguments, constraining the query to only those documents
585
+ # that do NOT match the arguments.
586
+ #
587
+ # @example Exclude a single criterion.
588
+ # selectable.none_of(name: /Bob/)
589
+ #
590
+ # @example Exclude multiple criteria.
591
+ # selectable.none_of(name: /Bob/, country: "USA")
592
+ #
593
+ # @example Exclude multiple criteria as an array.
594
+ # selectable.none_of([{ name: /Bob/ }, { country: "USA" }])
595
+ #
596
+ # @param [ [ Hash | Criteria ]... ] *criteria The key/value pair
597
+ # matches or Criteria objects to negate.
598
+ #
599
+ # @return [ Selectable ] The new selectable.
600
+ def none_of(*criteria)
601
+ criteria = _mongoid_flatten_arrays(criteria)
602
+ return dup if criteria.empty?
603
+
604
+ exprs = criteria.map do |criterion|
605
+ _mongoid_expand_keys(
606
+ criterion.is_a?(Selectable) ?
607
+ criterion.selector : criterion)
608
+ end
609
+
610
+ self.and('$nor' => exprs)
611
+ end
612
+
583
613
  # Creates a disjunction using $or from the existing criteria in the
584
614
  # receiver and the provided arguments.
585
615
  #
@@ -605,7 +635,7 @@ module Mongoid
605
635
  # @example Same as previous example, also deprecated.
606
636
  # selectable.or([{field: 1}], [{field: 2}])
607
637
  #
608
- # @param [ Hash | Criteria | Array<Hash | Criteria>, ... ] criteria
638
+ # @param [ [ Hash | Criteria | Array<Hash | Criteria> ]... ] *criteria
609
639
  # Multiple key/value pair matches or Criteria objects, or arrays
610
640
  # thereof. Passing arrays is deprecated.
611
641
  #
@@ -635,7 +665,7 @@ module Mongoid
635
665
  # @example Same as previous example, also deprecated.
636
666
  # selectable.any_of([{field: 1}], [{field: 2}])
637
667
  #
638
- # @param [ Hash | Criteria | Array<Hash | Criteria>, ... ] criteria
668
+ # @param [ [ Hash | Criteria | Array<Hash | Criteria> ]... ] *criteria
639
669
  # Multiple key/value pair matches or Criteria objects, or arrays
640
670
  # thereof. Passing arrays is deprecated.
641
671
  #
@@ -731,7 +761,7 @@ module Mongoid
731
761
  # @example Construct a text search selector with options.
732
762
  # selectable.text_search("testing", :$language => "fr")
733
763
  #
734
- # @note Per https://docs.mongodb.com/manual/reference/operator/query/text/
764
+ # @note Per https://www.mongodb.com/docs/manual/reference/operator/query/text/
735
765
  # it is not currently possible to supply multiple text search
736
766
  # conditions in a query. Mongoid will build such a query but the
737
767
  # server will return an error when trying to execute it.
@@ -751,7 +781,7 @@ module Mongoid
751
781
  criterion = {'$text' => { '$search' => terms }}
752
782
  criterion['$text'].merge!(opts) if opts
753
783
  if query.selector['$text']
754
- # Per https://docs.mongodb.com/manual/reference/operator/query/text/
784
+ # Per https://www.mongodb.com/docs/manual/reference/operator/query/text/
755
785
  # multiple $text expressions are not currently supported by
756
786
  # MongoDB server, but build the query correctly instead of
757
787
  # overwriting previous text search condition with the currently
@@ -774,7 +804,8 @@ module Mongoid
774
804
  # @example Add a javascript selection.
775
805
  # selectable.where("this.name == 'syd'")
776
806
  #
777
- # @param [ String | Hash ] criterion The javascript or standard selection.
807
+ # @param [ [ Hash | String ]... ] *criterion The standard selection
808
+ # or javascript string.
778
809
  #
779
810
  # @return [ Selectable ] The cloned selectable.
780
811
  def where(*criteria)
@@ -20,7 +20,7 @@ module Mongoid
20
20
  other.each_pair do |key, value|
21
21
  if value.is_a?(Hash) && self[key.to_s].is_a?(Hash)
22
22
  value = self[key.to_s].merge(value) do |_key, old_val, new_val|
23
- case _key.to_s
23
+ case _key
24
24
  when '$in'
25
25
  new_val & old_val
26
26
  when '$nin'
@@ -47,7 +47,7 @@ module Mongoid
47
47
  if value.is_a?(Hash) && selector[field].is_a?(Hash) &&
48
48
  value.keys.all? { |key|
49
49
  key_s = key.to_s
50
- key_s.start_with?('$') && !selector[field].keys.map(&:to_s).include?(key_s)
50
+ key_s.start_with?('$') && !selector[field].key?(key_s)
51
51
  }
52
52
  then
53
53
  # Multiple operators can be combined on the same field by
@@ -89,7 +89,7 @@ module Mongoid
89
89
  # @example Tries to find a document whose _id is the stringification of the provided Proc, typically failing.
90
90
  # enumerator = criteria.find(-> { "Default Band" })
91
91
  #
92
- # @param [ Object | Array<Object> ] *args The ids.
92
+ # @param [ [ Object | Array<Object> ]... ] *args The id(s).
93
93
  # @param [ Proc ] block Optional block to pass.
94
94
  #
95
95
  # @return [ Document | Array<Document> | nil ] A document or matching documents.
@@ -285,7 +285,7 @@ module Mongoid
285
285
  # @example Limit the fields returned from the database.
286
286
  # Band.only(:name)
287
287
  #
288
- # @param [ Array<Symbol> ] args The names of the fields.
288
+ # @param [ [ Symbol | Array<Symbol> ]... ] *args The field name(s).
289
289
  #
290
290
  # @return [ Criteria ] The cloned criteria.
291
291
  def only(*args)
@@ -319,7 +319,7 @@ module Mongoid
319
319
  # @example Exclude fields returned from the database.
320
320
  # Band.without(:name)
321
321
  #
322
- # @param [ Array<Symbol> ] args The names of the fields.
322
+ # @param [ Symbol... ] *args The field name(s).
323
323
  #
324
324
  # @return [ Criteria ] The cloned criteria.
325
325
  def without(*args)
@@ -386,7 +386,8 @@ module Mongoid
386
386
  # @example Add a javascript selection.
387
387
  # criteria.where("this.name == 'syd'")
388
388
  #
389
- # @param [ String | Hash ] expression The javascript or standard selection.
389
+ # @param [ [ Hash | String ]... ] *args The standard selection
390
+ # or javascript string.
390
391
  #
391
392
  # @raise [ UnsupportedJavascript ] If provided a string and the criteria
392
393
  # is embedded.
@@ -496,7 +497,7 @@ module Mongoid
496
497
  # criteria.method_missing(:name)
497
498
  #
498
499
  # @param [ Symbol ] name The method name.
499
- # @param [ Array ] args The arguments.
500
+ # @param [ Object... ] *args The arguments.
500
501
  #
501
502
  # @return [ Object ] The result of the method call.
502
503
  ruby2_keywords def method_missing(name, *args, &block)
@@ -27,8 +27,7 @@ module Mongoid
27
27
  # @param [ [ Symbol | Hash<Symbol, [ Symbol | String ]> ]... ] *method_descriptors
28
28
  # The methods to deprecate, with optional replacement instructions.
29
29
  def deprecate(target_module, *method_descriptors)
30
- @_deprecator ||= Mongoid::Deprecation.new
31
- @_deprecator.deprecate_methods(target_module, *method_descriptors)
30
+ Mongoid::Deprecation.deprecate_methods(target_module, *method_descriptors)
32
31
  end
33
32
  end
34
33
  end
@@ -15,10 +15,10 @@ module Mongoid
15
15
  #
16
16
  # @return Array<Proc> The deprecation behavior.
17
17
  def behavior
18
- @behavior ||= Array(->(*args) {
18
+ @behavior ||= Array(->(message, callstack, _deprecation_horizon, _gem_name) {
19
19
  logger = Mongoid.logger
20
- logger.warn(args[0])
21
- logger.debug(args[1].join("\n ")) if debug
20
+ logger.warn(message)
21
+ logger.debug(callstack.join("\n ")) if debug
22
22
  })
23
23
  end
24
24
  end
@@ -133,14 +133,7 @@ module Mongoid
133
133
  #
134
134
  # @return [ Hash ] A hash of all attributes in the hierarchy.
135
135
  def as_document
136
- attrs = as_attributes
137
-
138
- # legacy attributes have a tendency to leak internal state via
139
- # `as_document`; we have to deep_dup the attributes here to prevent
140
- # that.
141
- attrs = attrs.deep_dup if Mongoid.legacy_attributes
142
-
143
- BSON::Document.new(attrs)
136
+ BSON::Document.new(as_attributes)
144
137
  end
145
138
 
146
139
  # Calls #as_json on the document with additional, Mongoid-specific options.
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mongoid
4
+ module Errors
5
+
6
+ # Raised when an attempt to create a collection failed.
7
+ class CreateCollectionFailure < MongoidError
8
+
9
+ # Instantiate the create collection error.
10
+ #
11
+ # @param [ String ] collection_name The name of the collection that
12
+ # Mongoid failed to create.
13
+ # @param [ Hash ] collection_options The options that were used when
14
+ # tried to create the collection.
15
+ # @param [ Mongo::Error::OperationFailure ] error The error raised when
16
+ # tried to create the collection.
17
+ #
18
+ # @api private
19
+ def initialize(collection_name, collection_options, error)
20
+ super(
21
+ compose_message(
22
+ "create_collection_failure",
23
+ {
24
+ collection_name: collection_name,
25
+ collection_options: collection_options,
26
+ error: "#{error.class}: #{error.message}"
27
+ }
28
+ )
29
+ )
30
+ end
31
+ end
32
+ end
33
+ end