mongoid 7.0.2 → 8.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (1104) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +33 -33
  4. data/LICENSE +1 -0
  5. data/README.md +34 -20
  6. data/Rakefile +100 -5
  7. data/lib/config/locales/en.yml +220 -105
  8. data/lib/mongoid/association/accessors.rb +176 -84
  9. data/lib/mongoid/association/bindable.rb +57 -28
  10. data/lib/mongoid/association/builders.rb +9 -15
  11. data/lib/mongoid/association/constrainable.rb +5 -7
  12. data/lib/mongoid/association/depending.rb +9 -18
  13. data/lib/mongoid/association/eager_loadable.rb +31 -10
  14. data/lib/mongoid/association/embedded/batchable.rb +68 -54
  15. data/lib/mongoid/association/embedded/cyclic.rb +10 -17
  16. data/lib/mongoid/association/embedded/embedded_in/binding.rb +27 -9
  17. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +9 -6
  18. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +16 -25
  19. data/lib/mongoid/association/embedded/embedded_in.rb +9 -28
  20. data/lib/mongoid/association/embedded/embeds_many/binding.rb +5 -8
  21. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +10 -6
  22. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +156 -135
  23. data/lib/mongoid/association/embedded/embeds_many.rb +10 -37
  24. data/lib/mongoid/association/embedded/embeds_one/binding.rb +4 -8
  25. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +27 -10
  26. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +64 -30
  27. data/lib/mongoid/association/embedded/embeds_one.rb +11 -34
  28. data/lib/mongoid/association/embedded.rb +2 -0
  29. data/lib/mongoid/association/macros.rb +65 -41
  30. data/lib/mongoid/association/many.rb +25 -35
  31. data/lib/mongoid/association/marshalable.rb +3 -6
  32. data/lib/mongoid/association/nested/many.rb +22 -30
  33. data/lib/mongoid/association/nested/nested_buildable.rb +9 -15
  34. data/lib/mongoid/association/nested/one.rb +57 -30
  35. data/lib/mongoid/association/nested.rb +3 -3
  36. data/lib/mongoid/association/one.rb +5 -12
  37. data/lib/mongoid/association/options.rb +16 -46
  38. data/lib/mongoid/association/proxy.rb +52 -40
  39. data/lib/mongoid/association/referenced/auto_save.rb +9 -14
  40. data/lib/mongoid/association/referenced/belongs_to/binding.rb +5 -9
  41. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +11 -9
  42. data/lib/mongoid/association/referenced/belongs_to/eager.rb +40 -3
  43. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +19 -31
  44. data/lib/mongoid/association/referenced/belongs_to.rb +16 -38
  45. data/lib/mongoid/association/referenced/counter_cache.rb +14 -25
  46. data/lib/mongoid/association/referenced/eager.rb +42 -38
  47. data/lib/mongoid/association/referenced/has_and_belongs_to_many/binding.rb +12 -11
  48. data/lib/mongoid/association/referenced/has_and_belongs_to_many/buildable.rb +5 -5
  49. data/lib/mongoid/association/referenced/has_and_belongs_to_many/eager.rb +2 -1
  50. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +106 -67
  51. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +29 -46
  52. data/lib/mongoid/association/referenced/has_many/binding.rb +3 -6
  53. data/lib/mongoid/association/referenced/has_many/buildable.rb +5 -5
  54. data/lib/mongoid/association/referenced/has_many/eager.rb +2 -1
  55. data/lib/mongoid/association/referenced/has_many/enumerable.rb +440 -456
  56. data/lib/mongoid/association/referenced/has_many/proxy.rb +104 -127
  57. data/lib/mongoid/association/referenced/has_many.rb +21 -45
  58. data/lib/mongoid/association/referenced/has_one/binding.rb +4 -9
  59. data/lib/mongoid/association/referenced/has_one/buildable.rb +20 -6
  60. data/lib/mongoid/association/referenced/has_one/eager.rb +2 -1
  61. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +16 -29
  62. data/lib/mongoid/association/referenced/has_one/proxy.rb +25 -30
  63. data/lib/mongoid/association/referenced/has_one.rb +16 -36
  64. data/lib/mongoid/association/referenced/syncable.rb +11 -26
  65. data/lib/mongoid/association/referenced.rb +2 -0
  66. data/lib/mongoid/association/reflections.rb +7 -6
  67. data/lib/mongoid/association/relatable.rb +149 -89
  68. data/lib/mongoid/association.rb +13 -27
  69. data/lib/mongoid/atomic/modifiers.rb +29 -53
  70. data/lib/mongoid/atomic/paths/embedded/many.rb +23 -7
  71. data/lib/mongoid/atomic/paths/embedded/one.rb +4 -7
  72. data/lib/mongoid/atomic/paths/embedded.rb +3 -4
  73. data/lib/mongoid/atomic/paths/root.rb +4 -7
  74. data/lib/mongoid/atomic/paths.rb +2 -1
  75. data/lib/mongoid/atomic.rb +49 -47
  76. data/lib/mongoid/attributes/dynamic.rb +22 -36
  77. data/lib/mongoid/attributes/nested.rb +12 -15
  78. data/lib/mongoid/attributes/processing.rb +19 -27
  79. data/lib/mongoid/attributes/projector.rb +119 -0
  80. data/lib/mongoid/attributes/readonly.rb +6 -9
  81. data/lib/mongoid/attributes.rb +103 -100
  82. data/lib/mongoid/cacheable.rb +7 -10
  83. data/lib/mongoid/changeable.rb +152 -73
  84. data/lib/mongoid/clients/factory.rb +42 -17
  85. data/lib/mongoid/clients/options.rb +21 -18
  86. data/lib/mongoid/clients/sessions.rb +10 -10
  87. data/lib/mongoid/clients/storage_options.rb +9 -17
  88. data/lib/mongoid/clients/validators/storage.rb +5 -24
  89. data/lib/mongoid/clients/validators.rb +2 -1
  90. data/lib/mongoid/clients.rb +3 -10
  91. data/lib/mongoid/collection_configurable.rb +58 -0
  92. data/lib/mongoid/composable.rb +7 -9
  93. data/lib/mongoid/config/defaults.rb +60 -0
  94. data/lib/mongoid/config/environment.rb +51 -13
  95. data/lib/mongoid/config/options.rb +20 -23
  96. data/lib/mongoid/config/validators/async_query_executor.rb +24 -0
  97. data/lib/mongoid/config/validators/client.rb +8 -23
  98. data/lib/mongoid/config/validators/option.rb +2 -3
  99. data/lib/mongoid/config/validators.rb +3 -1
  100. data/lib/mongoid/config.rb +235 -48
  101. data/lib/mongoid/contextual/aggregable/memory.rb +40 -27
  102. data/lib/mongoid/contextual/aggregable/mongo.rb +32 -33
  103. data/lib/mongoid/contextual/aggregable/none.rb +65 -0
  104. data/lib/mongoid/contextual/aggregable.rb +17 -0
  105. data/lib/mongoid/contextual/atomic.rb +29 -31
  106. data/lib/mongoid/contextual/command.rb +2 -5
  107. data/lib/mongoid/contextual/geo_near.rb +13 -44
  108. data/lib/mongoid/contextual/map_reduce.rb +7 -35
  109. data/lib/mongoid/contextual/memory.rb +387 -81
  110. data/lib/mongoid/contextual/mongo/documents_loader.rb +177 -0
  111. data/lib/mongoid/contextual/mongo.rb +641 -283
  112. data/lib/mongoid/contextual/none.rb +264 -31
  113. data/lib/mongoid/contextual/queryable.rb +3 -4
  114. data/lib/mongoid/contextual.rb +21 -11
  115. data/lib/mongoid/copyable.rb +46 -17
  116. data/lib/mongoid/criteria/findable.rb +20 -20
  117. data/lib/mongoid/criteria/includable.rb +32 -34
  118. data/lib/mongoid/criteria/inspectable.rb +2 -3
  119. data/lib/mongoid/criteria/marshalable.rb +12 -7
  120. data/lib/mongoid/criteria/modifiable.rb +15 -21
  121. data/lib/mongoid/criteria/options.rb +4 -5
  122. data/lib/mongoid/criteria/permission.rb +3 -2
  123. data/lib/mongoid/criteria/queryable/aggregable.rb +4 -15
  124. data/lib/mongoid/criteria/queryable/expandable.rb +68 -0
  125. data/lib/mongoid/criteria/queryable/extensions/array.rb +7 -41
  126. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +28 -8
  127. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +5 -6
  128. data/lib/mongoid/criteria/queryable/extensions/date.rb +9 -9
  129. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +11 -12
  130. data/lib/mongoid/criteria/queryable/extensions/hash.rb +4 -41
  131. data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +3 -14
  132. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +4 -21
  133. data/lib/mongoid/criteria/queryable/extensions/object.rb +6 -30
  134. data/lib/mongoid/criteria/queryable/extensions/range.rb +49 -17
  135. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +12 -19
  136. data/lib/mongoid/criteria/queryable/extensions/set.rb +4 -5
  137. data/lib/mongoid/criteria/queryable/extensions/string.rb +7 -32
  138. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +7 -22
  139. data/lib/mongoid/criteria/queryable/extensions/time.rb +10 -10
  140. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +19 -7
  141. data/lib/mongoid/criteria/queryable/extensions.rb +1 -4
  142. data/lib/mongoid/criteria/queryable/key.rb +105 -31
  143. data/lib/mongoid/criteria/queryable/macroable.rb +3 -4
  144. data/lib/mongoid/criteria/queryable/mergeable.rb +205 -44
  145. data/lib/mongoid/criteria/queryable/optional.rb +16 -65
  146. data/lib/mongoid/criteria/queryable/options.rb +4 -21
  147. data/lib/mongoid/criteria/queryable/pipeline.rb +5 -15
  148. data/lib/mongoid/criteria/queryable/selectable.rb +471 -168
  149. data/lib/mongoid/criteria/queryable/selector.rb +133 -58
  150. data/lib/mongoid/criteria/queryable/smash.rb +42 -18
  151. data/lib/mongoid/criteria/queryable/storable.rb +237 -0
  152. data/lib/mongoid/criteria/queryable.rb +18 -15
  153. data/lib/mongoid/criteria/scopable.rb +29 -21
  154. data/lib/mongoid/criteria/translator.rb +45 -0
  155. data/lib/mongoid/criteria.rb +106 -111
  156. data/lib/mongoid/deprecable.rb +36 -0
  157. data/lib/mongoid/deprecation.rb +25 -0
  158. data/lib/mongoid/document.rb +162 -103
  159. data/lib/mongoid/equality.rb +35 -18
  160. data/lib/mongoid/errors/ambiguous_relationship.rb +4 -5
  161. data/lib/mongoid/errors/callback.rb +2 -3
  162. data/lib/mongoid/errors/create_collection_failure.rb +33 -0
  163. data/lib/mongoid/errors/criteria_argument_required.rb +18 -0
  164. data/lib/mongoid/errors/delete_restriction.rb +10 -13
  165. data/lib/mongoid/errors/document_not_destroyed.rb +4 -7
  166. data/lib/mongoid/errors/document_not_found.rb +35 -21
  167. data/lib/mongoid/errors/drop_collection_failure.rb +27 -0
  168. data/lib/mongoid/errors/empty_config_file.rb +25 -0
  169. data/lib/mongoid/errors/immutable_attribute.rb +26 -0
  170. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +2 -3
  171. data/lib/mongoid/errors/invalid_async_query_executor.rb +25 -0
  172. data/lib/mongoid/errors/invalid_collection.rb +2 -1
  173. data/lib/mongoid/errors/invalid_config_file.rb +25 -0
  174. data/lib/mongoid/errors/invalid_config_option.rb +3 -4
  175. data/lib/mongoid/errors/invalid_dependent_strategy.rb +3 -4
  176. data/lib/mongoid/errors/invalid_discriminator_key_target.rb +24 -0
  177. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
  178. data/lib/mongoid/errors/invalid_elem_match_operator.rb +32 -0
  179. data/lib/mongoid/errors/invalid_estimated_count_criteria.rb +25 -0
  180. data/lib/mongoid/errors/invalid_expression_operator.rb +27 -0
  181. data/lib/mongoid/errors/invalid_field.rb +8 -7
  182. data/lib/mongoid/errors/invalid_field_operator.rb +32 -0
  183. data/lib/mongoid/errors/invalid_field_option.rb +2 -3
  184. data/lib/mongoid/errors/invalid_field_type.rb +26 -0
  185. data/lib/mongoid/errors/invalid_find.rb +2 -3
  186. data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +22 -0
  187. data/lib/mongoid/errors/invalid_includes.rb +2 -3
  188. data/lib/mongoid/errors/invalid_index.rb +2 -3
  189. data/lib/mongoid/errors/invalid_options.rb +4 -5
  190. data/lib/mongoid/errors/invalid_path.rb +2 -3
  191. data/lib/mongoid/errors/invalid_persistence_option.rb +2 -5
  192. data/lib/mongoid/errors/invalid_query.rb +40 -0
  193. data/lib/mongoid/errors/invalid_relation.rb +5 -10
  194. data/lib/mongoid/errors/invalid_relation_option.rb +4 -5
  195. data/lib/mongoid/errors/invalid_scope.rb +2 -3
  196. data/lib/mongoid/errors/invalid_session_use.rb +3 -6
  197. data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +6 -5
  198. data/lib/mongoid/errors/invalid_storage_options.rb +3 -4
  199. data/lib/mongoid/errors/invalid_storage_parent.rb +4 -3
  200. data/lib/mongoid/errors/invalid_time.rb +2 -3
  201. data/lib/mongoid/errors/inverse_not_found.rb +3 -4
  202. data/lib/mongoid/errors/mixed_client_configuration.rb +2 -3
  203. data/lib/mongoid/errors/mixed_relations.rb +2 -3
  204. data/lib/mongoid/errors/mongoid_error.rb +6 -13
  205. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +3 -4
  206. data/lib/mongoid/errors/no_client_config.rb +4 -5
  207. data/lib/mongoid/errors/no_client_database.rb +3 -4
  208. data/lib/mongoid/errors/no_client_hosts.rb +3 -4
  209. data/lib/mongoid/errors/no_clients_config.rb +2 -3
  210. data/lib/mongoid/errors/no_default_client.rb +3 -4
  211. data/lib/mongoid/errors/no_environment.rb +2 -3
  212. data/lib/mongoid/errors/no_map_reduce_output.rb +2 -3
  213. data/lib/mongoid/errors/no_metadata.rb +2 -3
  214. data/lib/mongoid/errors/no_parent.rb +2 -3
  215. data/lib/mongoid/errors/readonly_attribute.rb +3 -4
  216. data/lib/mongoid/errors/readonly_document.rb +3 -6
  217. data/lib/mongoid/errors/scope_overwrite.rb +2 -1
  218. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +3 -1
  219. data/lib/mongoid/errors/unknown_attribute.rb +3 -4
  220. data/lib/mongoid/errors/unknown_model.rb +2 -3
  221. data/lib/mongoid/errors/unsaved_document.rb +3 -2
  222. data/lib/mongoid/errors/unsupported_javascript.rb +2 -3
  223. data/lib/mongoid/errors/validations.rb +2 -1
  224. data/lib/mongoid/errors.rb +18 -4
  225. data/lib/mongoid/evolvable.rb +4 -5
  226. data/lib/mongoid/extensions/array.rb +37 -44
  227. data/lib/mongoid/extensions/big_decimal.rb +35 -21
  228. data/lib/mongoid/extensions/binary.rb +42 -0
  229. data/lib/mongoid/extensions/boolean.rb +10 -6
  230. data/lib/mongoid/extensions/date.rb +32 -25
  231. data/lib/mongoid/extensions/date_time.rb +5 -13
  232. data/lib/mongoid/extensions/decimal128.rb +2 -5
  233. data/lib/mongoid/extensions/false_class.rb +5 -8
  234. data/lib/mongoid/extensions/float.rb +12 -14
  235. data/lib/mongoid/extensions/hash.rb +64 -42
  236. data/lib/mongoid/extensions/integer.rb +12 -16
  237. data/lib/mongoid/extensions/module.rb +3 -4
  238. data/lib/mongoid/extensions/nil_class.rb +2 -5
  239. data/lib/mongoid/extensions/object.rb +27 -52
  240. data/lib/mongoid/extensions/object_id.rb +2 -7
  241. data/lib/mongoid/extensions/range.rb +42 -20
  242. data/lib/mongoid/extensions/regexp.rb +14 -7
  243. data/lib/mongoid/extensions/set.rb +13 -11
  244. data/lib/mongoid/extensions/string.rb +35 -64
  245. data/lib/mongoid/extensions/symbol.rb +6 -22
  246. data/lib/mongoid/extensions/time.rb +38 -22
  247. data/lib/mongoid/extensions/time_with_zone.rb +26 -9
  248. data/lib/mongoid/extensions/true_class.rb +5 -8
  249. data/lib/mongoid/extensions.rb +19 -3
  250. data/lib/mongoid/factory.rb +104 -17
  251. data/lib/mongoid/fields/foreign_key.rb +14 -26
  252. data/lib/mongoid/fields/localized.rb +21 -15
  253. data/lib/mongoid/fields/standard.rb +23 -43
  254. data/lib/mongoid/fields/validators/macro.rb +32 -20
  255. data/lib/mongoid/fields/validators.rb +2 -1
  256. data/lib/mongoid/fields.rb +349 -76
  257. data/lib/mongoid/findable.rb +115 -34
  258. data/lib/mongoid/indexable/specification.rb +5 -18
  259. data/lib/mongoid/indexable/validators/options.rb +8 -9
  260. data/lib/mongoid/indexable.rb +6 -21
  261. data/lib/mongoid/inspectable.rb +4 -11
  262. data/lib/mongoid/interceptable.rb +85 -41
  263. data/lib/mongoid/loggable.rb +13 -16
  264. data/lib/mongoid/matchable.rb +4 -154
  265. data/lib/mongoid/matcher/all.rb +22 -0
  266. data/lib/mongoid/matcher/and.rb +21 -0
  267. data/lib/mongoid/matcher/bits.rb +41 -0
  268. data/lib/mongoid/matcher/bits_all_clear.rb +20 -0
  269. data/lib/mongoid/matcher/bits_all_set.rb +20 -0
  270. data/lib/mongoid/matcher/bits_any_clear.rb +20 -0
  271. data/lib/mongoid/matcher/bits_any_set.rb +20 -0
  272. data/lib/mongoid/matcher/elem_match.rb +36 -0
  273. data/lib/mongoid/matcher/elem_match_expression.rb +20 -0
  274. data/lib/mongoid/matcher/eq.rb +11 -0
  275. data/lib/mongoid/matcher/eq_impl.rb +67 -0
  276. data/lib/mongoid/matcher/eq_impl_with_regexp.rb +26 -0
  277. data/lib/mongoid/matcher/exists.rb +15 -0
  278. data/lib/mongoid/matcher/expression.rb +35 -0
  279. data/lib/mongoid/matcher/expression_operator.rb +19 -0
  280. data/lib/mongoid/matcher/field_expression.rb +62 -0
  281. data/lib/mongoid/matcher/field_operator.rb +54 -0
  282. data/lib/mongoid/matcher/gt.rb +17 -0
  283. data/lib/mongoid/matcher/gte.rb +17 -0
  284. data/lib/mongoid/matcher/in.rb +25 -0
  285. data/lib/mongoid/matcher/lt.rb +17 -0
  286. data/lib/mongoid/matcher/lte.rb +17 -0
  287. data/lib/mongoid/matcher/mod.rb +17 -0
  288. data/lib/mongoid/matcher/ne.rb +16 -0
  289. data/lib/mongoid/matcher/nin.rb +11 -0
  290. data/lib/mongoid/matcher/nor.rb +25 -0
  291. data/lib/mongoid/matcher/not.rb +29 -0
  292. data/lib/mongoid/matcher/or.rb +21 -0
  293. data/lib/mongoid/matcher/regex.rb +41 -0
  294. data/lib/mongoid/matcher/size.rb +26 -0
  295. data/lib/mongoid/matcher/type.rb +99 -0
  296. data/lib/mongoid/matcher.rb +130 -0
  297. data/lib/mongoid/persistable/creatable.rb +23 -30
  298. data/lib/mongoid/persistable/deletable.rb +7 -23
  299. data/lib/mongoid/persistable/destroyable.rb +12 -11
  300. data/lib/mongoid/persistable/incrementable.rb +6 -7
  301. data/lib/mongoid/persistable/logical.rb +4 -6
  302. data/lib/mongoid/persistable/poppable.rb +3 -6
  303. data/lib/mongoid/persistable/pullable.rb +3 -8
  304. data/lib/mongoid/persistable/pushable.rb +14 -10
  305. data/lib/mongoid/persistable/renamable.rb +10 -8
  306. data/lib/mongoid/persistable/savable.rb +16 -9
  307. data/lib/mongoid/persistable/settable.rb +3 -6
  308. data/lib/mongoid/persistable/unsettable.rb +10 -10
  309. data/lib/mongoid/persistable/updatable.rb +99 -30
  310. data/lib/mongoid/persistable/upsertable.rb +23 -9
  311. data/lib/mongoid/persistable.rb +138 -40
  312. data/lib/mongoid/persistence_context.rb +107 -52
  313. data/lib/mongoid/positional.rb +3 -6
  314. data/lib/mongoid/query_cache.rb +18 -234
  315. data/lib/mongoid/railtie.rb +20 -16
  316. data/lib/mongoid/railties/controller_runtime.rb +88 -0
  317. data/lib/mongoid/railties/database.rake +16 -2
  318. data/lib/mongoid/reloadable.rb +19 -22
  319. data/lib/mongoid/scopable.rb +37 -60
  320. data/lib/mongoid/selectable.rb +8 -18
  321. data/lib/mongoid/serializable.rb +33 -34
  322. data/lib/mongoid/shardable.rb +108 -21
  323. data/lib/mongoid/stateful.rb +60 -20
  324. data/lib/mongoid/stringified_symbol.rb +52 -0
  325. data/lib/mongoid/tasks/database.rake +24 -5
  326. data/lib/mongoid/tasks/database.rb +105 -7
  327. data/lib/mongoid/threaded/lifecycle.rb +7 -26
  328. data/lib/mongoid/threaded.rb +80 -67
  329. data/lib/mongoid/timestamps/created/short.rb +2 -1
  330. data/lib/mongoid/timestamps/created.rb +4 -3
  331. data/lib/mongoid/timestamps/short.rb +2 -1
  332. data/lib/mongoid/timestamps/timeless.rb +6 -9
  333. data/lib/mongoid/timestamps/updated/short.rb +2 -1
  334. data/lib/mongoid/timestamps/updated.rb +5 -6
  335. data/lib/mongoid/timestamps.rb +3 -2
  336. data/lib/mongoid/touchable.rb +54 -25
  337. data/lib/mongoid/traversable.rb +185 -61
  338. data/lib/mongoid/utils.rb +22 -0
  339. data/lib/mongoid/validatable/associated.rb +5 -6
  340. data/lib/mongoid/validatable/format.rb +2 -1
  341. data/lib/mongoid/validatable/length.rb +2 -1
  342. data/lib/mongoid/validatable/localizable.rb +3 -4
  343. data/lib/mongoid/validatable/macros.rb +8 -15
  344. data/lib/mongoid/validatable/presence.rb +10 -15
  345. data/lib/mongoid/validatable/queryable.rb +2 -3
  346. data/lib/mongoid/validatable/uniqueness.rb +30 -42
  347. data/lib/mongoid/validatable.rb +16 -32
  348. data/lib/mongoid/version.rb +3 -2
  349. data/lib/mongoid/warnings.rb +44 -0
  350. data/lib/mongoid.rb +50 -17
  351. data/lib/rails/generators/mongoid/config/config_generator.rb +10 -2
  352. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +53 -32
  353. data/lib/rails/generators/mongoid/model/model_generator.rb +3 -2
  354. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +1 -1
  355. data/lib/rails/generators/mongoid_generator.rb +2 -1
  356. data/lib/rails/mongoid.rb +4 -5
  357. data/spec/README.md +33 -0
  358. data/spec/config/mongoid.yml +29 -3
  359. data/spec/config/mongoid_with_schema_map_uuid.yml +27 -0
  360. data/spec/integration/app_spec.rb +345 -0
  361. data/spec/integration/associations/belongs_to_spec.rb +33 -0
  362. data/spec/integration/associations/embedded_dirty_spec.rb +57 -0
  363. data/spec/integration/associations/embedded_spec.rb +283 -0
  364. data/spec/integration/associations/embeds_many_spec.rb +219 -0
  365. data/spec/integration/associations/embeds_one_spec.rb +41 -0
  366. data/spec/integration/associations/foreign_key_spec.rb +107 -0
  367. data/spec/integration/associations/foreign_key_spec_models.rb +64 -0
  368. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
  369. data/spec/integration/associations/has_many_spec.rb +128 -0
  370. data/spec/integration/associations/has_one_spec.rb +272 -0
  371. data/spec/integration/associations/nested_attributes_assignment_spec.rb +115 -0
  372. data/spec/integration/associations/reverse_population_spec.rb +34 -0
  373. data/spec/integration/associations/reverse_population_spec_models.rb +36 -0
  374. data/spec/integration/associations/scope_option_spec.rb +101 -0
  375. data/spec/integration/atomic/modifiers_spec.rb +116 -0
  376. data/spec/integration/bson_regexp_raw_spec.rb +19 -0
  377. data/spec/integration/callbacks_models.rb +192 -0
  378. data/spec/integration/callbacks_spec.rb +584 -0
  379. data/spec/integration/contextual/empty_spec.rb +141 -0
  380. data/spec/integration/criteria/alias_query_spec.rb +161 -0
  381. data/spec/integration/criteria/date_field_spec.rb +40 -0
  382. data/spec/integration/criteria/default_scope_spec.rb +72 -0
  383. data/spec/integration/criteria/logical_spec.rb +124 -0
  384. data/spec/integration/criteria/range_spec.rb +359 -0
  385. data/spec/integration/criteria/time_with_zone_spec.rb +142 -0
  386. data/spec/integration/discriminator_key_spec.rb +391 -0
  387. data/spec/integration/discriminator_value_spec.rb +206 -0
  388. data/spec/integration/document_spec.rb +51 -0
  389. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  390. data/spec/integration/i18n_fallbacks_spec.rb +74 -0
  391. data/spec/integration/matcher_examples_spec.rb +765 -0
  392. data/spec/integration/matcher_operator_data/all.yml +140 -0
  393. data/spec/integration/matcher_operator_data/and.yml +93 -0
  394. data/spec/integration/matcher_operator_data/bits_all_clear.yml +159 -0
  395. data/spec/integration/matcher_operator_data/bits_all_set.yml +159 -0
  396. data/spec/integration/matcher_operator_data/bits_any_clear.yml +159 -0
  397. data/spec/integration/matcher_operator_data/bits_any_set.yml +159 -0
  398. data/spec/integration/matcher_operator_data/comment.yml +22 -0
  399. data/spec/integration/matcher_operator_data/elem_match.yml +409 -0
  400. data/spec/integration/matcher_operator_data/elem_match_expr.yml +213 -0
  401. data/spec/integration/matcher_operator_data/eq.yml +191 -0
  402. data/spec/integration/matcher_operator_data/exists.yml +213 -0
  403. data/spec/integration/matcher_operator_data/generic_op.yml +17 -0
  404. data/spec/integration/matcher_operator_data/gt.yml +132 -0
  405. data/spec/integration/matcher_operator_data/gt_types.yml +63 -0
  406. data/spec/integration/matcher_operator_data/gte.yml +132 -0
  407. data/spec/integration/matcher_operator_data/gte_types.yml +15 -0
  408. data/spec/integration/matcher_operator_data/implicit.yml +331 -0
  409. data/spec/integration/matcher_operator_data/implicit_traversal.yml +112 -0
  410. data/spec/integration/matcher_operator_data/in.yml +210 -0
  411. data/spec/integration/matcher_operator_data/invalid_op.yml +59 -0
  412. data/spec/integration/matcher_operator_data/invalid_syntax.yml +39 -0
  413. data/spec/integration/matcher_operator_data/lt.yml +132 -0
  414. data/spec/integration/matcher_operator_data/lt_types.yml +15 -0
  415. data/spec/integration/matcher_operator_data/lte.yml +132 -0
  416. data/spec/integration/matcher_operator_data/lte_types.yml +15 -0
  417. data/spec/integration/matcher_operator_data/mod.yml +55 -0
  418. data/spec/integration/matcher_operator_data/multiple.yml +29 -0
  419. data/spec/integration/matcher_operator_data/ne.yml +150 -0
  420. data/spec/integration/matcher_operator_data/ne_types.yml +15 -0
  421. data/spec/integration/matcher_operator_data/nin.yml +114 -0
  422. data/spec/integration/matcher_operator_data/nor.yml +126 -0
  423. data/spec/integration/matcher_operator_data/not.yml +196 -0
  424. data/spec/integration/matcher_operator_data/or.yml +137 -0
  425. data/spec/integration/matcher_operator_data/regex.yml +174 -0
  426. data/spec/integration/matcher_operator_data/regex_options.yml +72 -0
  427. data/spec/integration/matcher_operator_data/size.yml +174 -0
  428. data/spec/integration/matcher_operator_data/type.yml +70 -0
  429. data/spec/integration/matcher_operator_data/type_array.yml +16 -0
  430. data/spec/integration/matcher_operator_data/type_binary.yml +18 -0
  431. data/spec/integration/matcher_operator_data/type_boolean.yml +39 -0
  432. data/spec/integration/matcher_operator_data/type_code.yml +26 -0
  433. data/spec/integration/matcher_operator_data/type_code_with_scope.yml +26 -0
  434. data/spec/integration/matcher_operator_data/type_date.yml +39 -0
  435. data/spec/integration/matcher_operator_data/type_db_pointer.yml +19 -0
  436. data/spec/integration/matcher_operator_data/type_decimal.yml +41 -0
  437. data/spec/integration/matcher_operator_data/type_double.yml +15 -0
  438. data/spec/integration/matcher_operator_data/type_int32.yml +33 -0
  439. data/spec/integration/matcher_operator_data/type_int64.yml +33 -0
  440. data/spec/integration/matcher_operator_data/type_max_key.yml +17 -0
  441. data/spec/integration/matcher_operator_data/type_min_key.yml +17 -0
  442. data/spec/integration/matcher_operator_data/type_null.yml +23 -0
  443. data/spec/integration/matcher_operator_data/type_object.yml +23 -0
  444. data/spec/integration/matcher_operator_data/type_object_id.yml +25 -0
  445. data/spec/integration/matcher_operator_data/type_regex.yml +44 -0
  446. data/spec/integration/matcher_operator_data/type_string.yml +15 -0
  447. data/spec/integration/matcher_operator_data/type_symbol.yml +32 -0
  448. data/spec/integration/matcher_operator_data/type_timestamp.yml +25 -0
  449. data/spec/integration/matcher_operator_data/type_undefined.yml +17 -0
  450. data/spec/integration/matcher_operator_spec.rb +122 -0
  451. data/spec/integration/matcher_spec.rb +283 -0
  452. data/spec/integration/persistence/range_field_spec.rb +350 -0
  453. data/spec/integration/server_query_spec.rb +141 -0
  454. data/spec/integration/shardable_spec.rb +148 -0
  455. data/spec/integration/stringified_symbol_field_spec.rb +203 -0
  456. data/spec/lite_spec_helper.rb +83 -0
  457. data/spec/mongoid/association/accessors_spec.rb +284 -77
  458. data/spec/mongoid/association/auto_save_spec.rb +74 -33
  459. data/spec/mongoid/association/builders_spec.rb +3 -1
  460. data/spec/mongoid/association/constrainable_spec.rb +2 -0
  461. data/spec/mongoid/association/counter_cache_spec.rb +35 -33
  462. data/spec/mongoid/association/depending_spec.rb +431 -338
  463. data/spec/mongoid/association/eager_spec.rb +8 -5
  464. data/spec/mongoid/association/embedded/cyclic_spec.rb +4 -2
  465. data/spec/mongoid/association/embedded/dirty_spec.rb +4 -2
  466. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +4 -1
  467. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +56 -0
  468. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +152 -13
  469. data/spec/mongoid/association/embedded/embedded_in_spec.rb +61 -1
  470. data/spec/mongoid/association/embedded/embeds_many/binding_spec.rb +2 -0
  471. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +114 -0
  472. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +706 -197
  473. data/spec/mongoid/association/embedded/embeds_many_models.rb +227 -0
  474. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +63 -0
  475. data/spec/mongoid/association/embedded/embeds_many_spec.rb +81 -1
  476. data/spec/mongoid/association/embedded/embeds_one/binding_spec.rb +2 -0
  477. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +27 -0
  478. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +38 -23
  479. data/spec/mongoid/association/embedded/embeds_one_dnl_models.rb +8 -0
  480. data/spec/mongoid/association/embedded/embeds_one_models.rb +73 -0
  481. data/spec/mongoid/association/embedded/embeds_one_query_spec.rb +28 -0
  482. data/spec/mongoid/association/embedded/embeds_one_spec.rb +77 -1
  483. data/spec/mongoid/association/macros_spec.rb +11 -9
  484. data/spec/mongoid/association/nested/many_spec.rb +2 -0
  485. data/spec/mongoid/association/nested/one_spec.rb +18 -12
  486. data/spec/mongoid/association/options_spec.rb +2 -0
  487. data/spec/mongoid/association/polymorphic_spec.rb +2 -0
  488. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +4 -1
  489. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +111 -16
  490. data/spec/mongoid/association/referenced/belongs_to/eager_spec.rb +266 -17
  491. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +114 -58
  492. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  493. data/spec/mongoid/association/referenced/belongs_to_query_spec.rb +57 -0
  494. data/spec/mongoid/association/referenced/belongs_to_spec.rb +96 -29
  495. data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +3 -1
  496. data/spec/mongoid/association/referenced/has_and_belongs_to_many/buildable_spec.rb +28 -1
  497. data/spec/mongoid/association/referenced/has_and_belongs_to_many/eager_spec.rb +67 -4
  498. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_persistence_spec.rb +76 -0
  499. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +559 -385
  500. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +92 -0
  501. data/spec/mongoid/association/referenced/has_and_belongs_to_many_query_spec.rb +39 -0
  502. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +84 -7
  503. data/spec/mongoid/association/referenced/has_many/binding_spec.rb +3 -1
  504. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +132 -0
  505. data/spec/mongoid/association/referenced/has_many/eager_spec.rb +40 -9
  506. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +415 -129
  507. data/spec/mongoid/association/referenced/has_many/proxy_query_spec.rb +23 -0
  508. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +859 -502
  509. data/spec/mongoid/association/referenced/has_many_models.rb +97 -0
  510. data/spec/mongoid/association/referenced/has_many_query_spec.rb +37 -0
  511. data/spec/mongoid/association/referenced/has_many_spec.rb +51 -3
  512. data/spec/mongoid/association/referenced/has_one/binding_spec.rb +2 -0
  513. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +55 -9
  514. data/spec/mongoid/association/referenced/has_one/eager_spec.rb +34 -4
  515. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +135 -27
  516. data/spec/mongoid/association/referenced/has_one_models.rb +113 -0
  517. data/spec/mongoid/association/referenced/has_one_query_spec.rb +37 -0
  518. data/spec/mongoid/association/referenced/has_one_spec.rb +87 -7
  519. data/spec/mongoid/association/reflections_spec.rb +2 -0
  520. data/spec/mongoid/association/syncable_spec.rb +48 -32
  521. data/spec/mongoid/association_spec.rb +2 -0
  522. data/spec/mongoid/atomic/modifiers_spec.rb +49 -0
  523. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +2 -0
  524. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +2 -0
  525. data/spec/mongoid/atomic/paths/root_spec.rb +2 -0
  526. data/spec/mongoid/atomic/paths_spec.rb +93 -12
  527. data/spec/mongoid/atomic_spec.rb +53 -6
  528. data/spec/mongoid/attributes/dynamic_spec.rb +152 -0
  529. data/spec/mongoid/attributes/nested_spec.rb +149 -78
  530. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  531. data/spec/mongoid/attributes/projector_data/embedded.yml +105 -0
  532. data/spec/mongoid/attributes/projector_data/fields.yml +93 -0
  533. data/spec/mongoid/attributes/projector_spec.rb +40 -0
  534. data/spec/mongoid/attributes/readonly_spec.rb +24 -22
  535. data/spec/mongoid/attributes_spec.rb +895 -54
  536. data/spec/mongoid/cacheable_spec.rb +6 -4
  537. data/spec/mongoid/changeable_spec.rb +484 -67
  538. data/spec/mongoid/clients/factory_spec.rb +139 -33
  539. data/spec/mongoid/clients/options_spec.rb +76 -54
  540. data/spec/mongoid/clients/sessions_spec.rb +35 -63
  541. data/spec/mongoid/clients/transactions_spec.rb +87 -41
  542. data/spec/mongoid/clients_spec.rb +257 -31
  543. data/spec/mongoid/collection_configurable_spec.rb +158 -0
  544. data/spec/mongoid/composable_spec.rb +2 -0
  545. data/spec/mongoid/config/defaults_spec.rb +160 -0
  546. data/spec/mongoid/config/environment_spec.rb +126 -8
  547. data/spec/mongoid/config/options_spec.rb +22 -3
  548. data/spec/mongoid/config_spec.rb +507 -2
  549. data/spec/mongoid/contextual/aggregable/memory_spec.rb +433 -153
  550. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  551. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  552. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +122 -20
  553. data/spec/mongoid/contextual/aggregable/none_spec.rb +60 -0
  554. data/spec/mongoid/contextual/atomic_spec.rb +242 -81
  555. data/spec/mongoid/contextual/geo_near_spec.rb +31 -19
  556. data/spec/mongoid/contextual/map_reduce_spec.rb +22 -19
  557. data/spec/mongoid/contextual/memory_spec.rb +1828 -303
  558. data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +187 -0
  559. data/spec/mongoid/contextual/mongo_spec.rb +3505 -1268
  560. data/spec/mongoid/contextual/none_spec.rb +80 -67
  561. data/spec/mongoid/copyable_spec.rb +697 -40
  562. data/spec/mongoid/copyable_spec_models.rb +47 -0
  563. data/spec/mongoid/criteria/findable_spec.rb +161 -228
  564. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  565. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  566. data/spec/mongoid/criteria/inspectable_spec.rb +2 -0
  567. data/spec/mongoid/criteria/marshalable_spec.rb +20 -1
  568. data/spec/mongoid/criteria/modifiable_spec.rb +100 -48
  569. data/spec/mongoid/criteria/options_spec.rb +2 -0
  570. data/spec/mongoid/criteria/queryable/aggregable_spec.rb +3 -1
  571. data/spec/mongoid/criteria/queryable/expandable_spec.rb +61 -0
  572. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +9 -19
  573. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +136 -26
  574. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +3 -1
  575. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +13 -0
  576. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +46 -17
  577. data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +2 -0
  578. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +2 -15
  579. data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +2 -0
  580. data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +2 -0
  581. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +119 -0
  582. data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +2 -0
  583. data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +239 -178
  584. data/spec/mongoid/criteria/queryable/extensions/regexp_raw_spec.rb +3 -1
  585. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +9 -7
  586. data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +2 -0
  587. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +7 -70
  588. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +2 -59
  589. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +53 -23
  590. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +41 -1
  591. data/spec/mongoid/criteria/queryable/key_spec.rb +50 -6
  592. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +145 -12
  593. data/spec/mongoid/criteria/queryable/optional_spec.rb +18 -485
  594. data/spec/mongoid/criteria/queryable/options_spec.rb +3 -1
  595. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +2 -0
  596. data/spec/mongoid/criteria/queryable/queryable_spec.rb +3 -1
  597. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +2538 -0
  598. data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +38 -0
  599. data/spec/mongoid/criteria/queryable/selectable_spec.rb +1193 -2934
  600. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +589 -0
  601. data/spec/mongoid/criteria/queryable/selector_spec.rb +56 -5
  602. data/spec/mongoid/criteria/queryable/smash_spec.rb +2 -0
  603. data/spec/mongoid/criteria/queryable/storable_spec.rb +226 -0
  604. data/spec/mongoid/criteria/scopable_spec.rb +210 -0
  605. data/spec/mongoid/criteria/translator_spec.rb +132 -0
  606. data/spec/mongoid/criteria_projection_spec.rb +406 -0
  607. data/spec/mongoid/criteria_spec.rb +1334 -1719
  608. data/spec/mongoid/document_fields_spec.rb +262 -0
  609. data/spec/mongoid/document_persistence_context_spec.rb +32 -0
  610. data/spec/mongoid/document_query_spec.rb +89 -0
  611. data/spec/mongoid/document_spec.rb +212 -67
  612. data/spec/mongoid/equality_spec.rb +144 -41
  613. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +5 -3
  614. data/spec/mongoid/errors/callback_spec.rb +2 -0
  615. data/spec/mongoid/errors/delete_restriction_spec.rb +4 -2
  616. data/spec/mongoid/errors/document_not_destroyed_spec.rb +2 -0
  617. data/spec/mongoid/errors/document_not_found_spec.rb +78 -0
  618. data/spec/mongoid/errors/invalid_collection_spec.rb +2 -0
  619. data/spec/mongoid/errors/{eager_load_spec.rb → invalid_config_file_spec.rb} +7 -5
  620. data/spec/mongoid/errors/invalid_config_option_spec.rb +2 -0
  621. data/spec/mongoid/errors/invalid_field_option_spec.rb +2 -0
  622. data/spec/mongoid/errors/invalid_field_spec.rb +3 -1
  623. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  624. data/spec/mongoid/errors/invalid_find_spec.rb +2 -0
  625. data/spec/mongoid/errors/invalid_includes_spec.rb +2 -0
  626. data/spec/mongoid/errors/invalid_index_spec.rb +2 -0
  627. data/spec/mongoid/errors/invalid_options_spec.rb +4 -2
  628. data/spec/mongoid/errors/invalid_path_spec.rb +2 -0
  629. data/spec/mongoid/errors/invalid_relation_spec.rb +4 -2
  630. data/spec/mongoid/errors/invalid_scope_spec.rb +3 -1
  631. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +2 -0
  632. data/spec/mongoid/errors/invalid_storage_options_spec.rb +2 -0
  633. data/spec/mongoid/errors/invalid_time_spec.rb +2 -0
  634. data/spec/mongoid/errors/inverse_not_found_spec.rb +3 -1
  635. data/spec/mongoid/errors/mixed_client_configuration_spec.rb +2 -0
  636. data/spec/mongoid/errors/mixed_relations_spec.rb +2 -0
  637. data/spec/mongoid/errors/mongoid_error_spec.rb +24 -8
  638. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +5 -3
  639. data/spec/mongoid/errors/no_client_config_spec.rb +4 -2
  640. data/spec/mongoid/errors/no_client_database_spec.rb +5 -3
  641. data/spec/mongoid/errors/no_client_hosts_spec.rb +5 -3
  642. data/spec/mongoid/errors/no_clients_config_spec.rb +2 -0
  643. data/spec/mongoid/errors/no_environment_spec.rb +5 -3
  644. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +2 -0
  645. data/spec/mongoid/errors/no_metadata_spec.rb +4 -2
  646. data/spec/mongoid/errors/no_parent_spec.rb +3 -1
  647. data/spec/mongoid/errors/readonly_attribute_spec.rb +2 -0
  648. data/spec/mongoid/errors/readonly_document_spec.rb +4 -2
  649. data/spec/mongoid/errors/scope_overwrite_spec.rb +2 -0
  650. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +3 -1
  651. data/spec/mongoid/errors/unknown_attribute_spec.rb +4 -2
  652. data/spec/mongoid/errors/unsaved_document_spec.rb +3 -1
  653. data/spec/mongoid/errors/unsupported_javascript_spec.rb +2 -0
  654. data/spec/mongoid/errors/validations_spec.rb +2 -0
  655. data/spec/mongoid/extensions/array_spec.rb +41 -45
  656. data/spec/mongoid/extensions/big_decimal_spec.rb +715 -213
  657. data/spec/mongoid/extensions/binary_spec.rb +46 -9
  658. data/spec/mongoid/extensions/boolean_spec.rb +70 -82
  659. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +339 -0
  660. data/spec/mongoid/extensions/date_spec.rb +58 -140
  661. data/spec/mongoid/extensions/date_time_spec.rb +32 -69
  662. data/spec/mongoid/extensions/decimal128_spec.rb +2 -0
  663. data/spec/mongoid/extensions/false_class_spec.rb +3 -1
  664. data/spec/mongoid/extensions/float_spec.rb +66 -73
  665. data/spec/mongoid/extensions/hash_spec.rb +135 -0
  666. data/spec/mongoid/extensions/integer_spec.rb +61 -63
  667. data/spec/mongoid/extensions/module_spec.rb +2 -0
  668. data/spec/mongoid/extensions/nil_class_spec.rb +2 -0
  669. data/spec/mongoid/extensions/object_id_spec.rb +2 -0
  670. data/spec/mongoid/extensions/object_spec.rb +13 -24
  671. data/spec/mongoid/extensions/range_spec.rb +257 -54
  672. data/spec/mongoid/extensions/regexp_spec.rb +70 -20
  673. data/spec/mongoid/extensions/set_spec.rb +108 -0
  674. data/spec/mongoid/extensions/string_spec.rb +146 -57
  675. data/spec/mongoid/extensions/stringified_symbol_spec.rb +84 -0
  676. data/spec/mongoid/extensions/symbol_spec.rb +20 -25
  677. data/spec/mongoid/extensions/time_spec.rb +668 -106
  678. data/spec/mongoid/extensions/time_with_zone_spec.rb +57 -83
  679. data/spec/mongoid/extensions/true_class_spec.rb +3 -1
  680. data/spec/mongoid/extensions_spec.rb +16 -2
  681. data/spec/mongoid/factory_spec.rb +347 -27
  682. data/spec/mongoid/fields/foreign_key_spec.rb +2 -0
  683. data/spec/mongoid/fields/localized_spec.rb +86 -41
  684. data/spec/mongoid/fields/standard_spec.rb +2 -0
  685. data/spec/mongoid/fields_spec.rb +869 -114
  686. data/spec/mongoid/findable_spec.rb +521 -65
  687. data/spec/mongoid/indexable/specification_spec.rb +4 -2
  688. data/spec/mongoid/indexable_spec.rb +87 -32
  689. data/spec/mongoid/inspectable_spec.rb +39 -2
  690. data/spec/mongoid/interceptable_spec.rb +761 -98
  691. data/spec/mongoid/interceptable_spec_models.rb +307 -0
  692. data/spec/mongoid/loggable_spec.rb +2 -0
  693. data/spec/mongoid/matcher/extract_attribute_data/numeric_keys.yml +104 -0
  694. data/spec/mongoid/matcher/extract_attribute_data/traversal.yml +239 -0
  695. data/spec/mongoid/matcher/extract_attribute_spec.rb +36 -0
  696. data/spec/mongoid/mongoizable_spec.rb +285 -0
  697. data/spec/mongoid/persistable/creatable_spec.rb +114 -29
  698. data/spec/mongoid/persistable/deletable_spec.rb +300 -18
  699. data/spec/mongoid/persistable/destroyable_spec.rb +228 -18
  700. data/spec/mongoid/persistable/incrementable_spec.rb +66 -13
  701. data/spec/mongoid/persistable/logical_spec.rb +56 -3
  702. data/spec/mongoid/persistable/poppable_spec.rb +55 -3
  703. data/spec/mongoid/persistable/pullable_spec.rb +108 -6
  704. data/spec/mongoid/persistable/pushable_spec.rb +163 -7
  705. data/spec/mongoid/persistable/renamable_spec.rb +54 -2
  706. data/spec/mongoid/persistable/savable_spec.rb +284 -25
  707. data/spec/mongoid/persistable/settable_spec.rb +91 -8
  708. data/spec/mongoid/persistable/unsettable_spec.rb +55 -3
  709. data/spec/mongoid/persistable/updatable_spec.rb +63 -49
  710. data/spec/mongoid/persistable/upsertable_spec.rb +93 -3
  711. data/spec/mongoid/persistable_spec.rb +85 -9
  712. data/spec/mongoid/persistence_context_spec.rb +60 -59
  713. data/spec/mongoid/positional_spec.rb +2 -0
  714. data/spec/mongoid/query_cache_middleware_spec.rb +50 -0
  715. data/spec/mongoid/query_cache_spec.rb +446 -78
  716. data/spec/mongoid/relations/proxy_spec.rb +9 -7
  717. data/spec/mongoid/reloadable_spec.rb +381 -26
  718. data/spec/mongoid/scopable_spec.rb +206 -38
  719. data/spec/mongoid/selectable_spec.rb +8 -6
  720. data/spec/mongoid/serializable_spec.rb +148 -38
  721. data/spec/mongoid/shardable_models.rb +75 -0
  722. data/spec/mongoid/shardable_spec.rb +239 -34
  723. data/spec/mongoid/stateful_spec.rb +153 -9
  724. data/spec/mongoid/tasks/database_rake_spec.rb +89 -13
  725. data/spec/mongoid/tasks/database_spec.rb +130 -1
  726. data/spec/mongoid/threaded_spec.rb +72 -2
  727. data/spec/mongoid/timestamps/created/short_spec.rb +3 -1
  728. data/spec/mongoid/timestamps/created_spec.rb +3 -1
  729. data/spec/mongoid/timestamps/timeless_spec.rb +4 -2
  730. data/spec/mongoid/timestamps/updated/short_spec.rb +5 -3
  731. data/spec/mongoid/timestamps/updated_spec.rb +5 -3
  732. data/spec/mongoid/timestamps_spec.rb +400 -10
  733. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  734. data/spec/mongoid/touchable_spec.rb +568 -33
  735. data/spec/mongoid/touchable_spec_models.rb +59 -0
  736. data/spec/mongoid/traversable_spec.rb +1145 -1
  737. data/spec/mongoid/validatable/associated_spec.rb +2 -0
  738. data/spec/mongoid/validatable/format_spec.rb +2 -0
  739. data/spec/mongoid/validatable/length_spec.rb +2 -0
  740. data/spec/mongoid/validatable/numericality_spec.rb +2 -0
  741. data/spec/mongoid/validatable/presence_spec.rb +28 -22
  742. data/spec/mongoid/validatable/uniqueness_spec.rb +159 -103
  743. data/spec/mongoid/validatable_spec.rb +5 -3
  744. data/spec/mongoid/warnings_spec.rb +35 -0
  745. data/spec/mongoid_spec.rb +36 -10
  746. data/spec/rails/controller_extension/controller_runtime_spec.rb +112 -0
  747. data/spec/rails/mongoid_spec.rb +8 -18
  748. data/spec/shared/LICENSE +20 -0
  749. data/spec/shared/bin/get-mongodb-download-url +17 -0
  750. data/spec/shared/bin/s3-copy +45 -0
  751. data/spec/shared/bin/s3-upload +69 -0
  752. data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
  753. data/spec/shared/lib/mrss/cluster_config.rb +231 -0
  754. data/spec/shared/lib/mrss/constraints.rb +378 -0
  755. data/spec/shared/lib/mrss/docker_runner.rb +298 -0
  756. data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
  757. data/spec/shared/lib/mrss/event_subscriber.rb +210 -0
  758. data/spec/shared/lib/mrss/lite_constraints.rb +238 -0
  759. data/spec/shared/lib/mrss/server_version_registry.rb +113 -0
  760. data/spec/shared/lib/mrss/session_registry.rb +69 -0
  761. data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
  762. data/spec/shared/lib/mrss/spec_organizer.rb +179 -0
  763. data/spec/shared/lib/mrss/utils.rb +37 -0
  764. data/spec/shared/share/Dockerfile.erb +321 -0
  765. data/spec/shared/share/haproxy-1.conf +16 -0
  766. data/spec/shared/share/haproxy-2.conf +17 -0
  767. data/spec/shared/shlib/config.sh +27 -0
  768. data/spec/shared/shlib/distro.sh +74 -0
  769. data/spec/shared/shlib/server.sh +416 -0
  770. data/spec/shared/shlib/set_env.sh +169 -0
  771. data/spec/spec_helper.rb +74 -88
  772. data/spec/support/authorization.rb +2 -0
  773. data/spec/support/client_registry.rb +9 -0
  774. data/spec/support/constraints.rb +77 -0
  775. data/spec/support/expectations.rb +21 -3
  776. data/spec/support/helpers.rb +11 -0
  777. data/spec/support/immutable_ids.rb +118 -0
  778. data/spec/support/macros.rb +129 -0
  779. data/spec/{app → support}/models/account.rb +3 -1
  780. data/spec/{app → support}/models/acolyte.rb +2 -0
  781. data/spec/{app → support}/models/actor.rb +3 -1
  782. data/spec/support/models/actress.rb +4 -0
  783. data/spec/{app → support}/models/address.rb +6 -0
  784. data/spec/{app → support}/models/address_component.rb +2 -0
  785. data/spec/{app → support}/models/address_number.rb +2 -0
  786. data/spec/{app → support}/models/agency.rb +2 -0
  787. data/spec/{app → support}/models/agent.rb +2 -0
  788. data/spec/{app → support}/models/album.rb +2 -0
  789. data/spec/{app → support}/models/alert.rb +2 -0
  790. data/spec/{app → support}/models/animal.rb +2 -0
  791. data/spec/{app → support}/models/answer.rb +2 -0
  792. data/spec/{app → support}/models/appointment.rb +2 -0
  793. data/spec/support/models/armrest.rb +9 -0
  794. data/spec/{app → support}/models/article.rb +2 -0
  795. data/spec/{app → support}/models/artist.rb +4 -1
  796. data/spec/{app → support}/models/artwork.rb +2 -0
  797. data/spec/support/models/audible_sound.rb +3 -0
  798. data/spec/{app → support}/models/audio.rb +2 -0
  799. data/spec/support/models/augmentation.rb +25 -0
  800. data/spec/{app → support}/models/author.rb +2 -0
  801. data/spec/{app → support}/models/baby.rb +2 -0
  802. data/spec/{app → support}/models/band.rb +10 -0
  803. data/spec/{app → support}/models/bar.rb +2 -0
  804. data/spec/{app → support}/models/basic.rb +2 -0
  805. data/spec/support/models/bed.rb +3 -0
  806. data/spec/{app → support}/models/big_palette.rb +2 -0
  807. data/spec/{app → support}/models/birthday.rb +2 -0
  808. data/spec/support/models/bolt.rb +7 -0
  809. data/spec/{app → support}/models/bomb.rb +2 -0
  810. data/spec/{app → support}/models/book.rb +3 -0
  811. data/spec/{app → support}/models/breed.rb +2 -0
  812. data/spec/{app → support}/models/browser.rb +3 -1
  813. data/spec/{app → support}/models/building.rb +4 -0
  814. data/spec/{app → support}/models/building_address.rb +2 -0
  815. data/spec/{app → support}/models/bus.rb +2 -0
  816. data/spec/{app → support}/models/business.rb +2 -0
  817. data/spec/{app → support}/models/callback_test.rb +2 -0
  818. data/spec/{app → support}/models/canvas.rb +3 -1
  819. data/spec/support/models/car.rb +3 -0
  820. data/spec/{app → support}/models/cat.rb +2 -0
  821. data/spec/support/models/catalog.rb +24 -0
  822. data/spec/{app → support}/models/category.rb +2 -0
  823. data/spec/{app → support}/models/child.rb +2 -0
  824. data/spec/{app → support}/models/child_doc.rb +5 -3
  825. data/spec/{app → support}/models/church.rb +2 -0
  826. data/spec/{app → support}/models/circle.rb +2 -0
  827. data/spec/{app → support}/models/circuit.rb +2 -0
  828. data/spec/support/models/circus.rb +12 -0
  829. data/spec/{app → support}/models/code.rb +4 -0
  830. data/spec/support/models/coding/pull_request.rb +11 -0
  831. data/spec/support/models/coding.rb +3 -0
  832. data/spec/{app → support}/models/comment.rb +2 -0
  833. data/spec/{app → support}/models/company.rb +2 -0
  834. data/spec/{app → support}/models/consumption_period.rb +2 -0
  835. data/spec/{app → support}/models/contextable_item.rb +2 -0
  836. data/spec/{app → support}/models/contractor.rb +2 -0
  837. data/spec/{app → support}/models/cookie.rb +2 -0
  838. data/spec/{app → support}/models/country_code.rb +4 -0
  839. data/spec/{app → support}/models/courier_job.rb +2 -0
  840. data/spec/support/models/cover.rb +10 -0
  841. data/spec/support/models/crate.rb +12 -0
  842. data/spec/support/models/customer.rb +10 -0
  843. data/spec/support/models/customer_address.rb +11 -0
  844. data/spec/support/models/deed.rb +7 -0
  845. data/spec/{app → support}/models/definition.rb +2 -0
  846. data/spec/support/models/delegating_patient.rb +15 -0
  847. data/spec/{app → support}/models/description.rb +2 -0
  848. data/spec/{app → support}/models/dictionary.rb +8 -0
  849. data/spec/{app → support}/models/division.rb +2 -0
  850. data/spec/{app → support}/models/doctor.rb +2 -0
  851. data/spec/{app → support}/models/dog.rb +2 -0
  852. data/spec/{app → support}/models/dokument.rb +2 -0
  853. data/spec/{app → support}/models/draft.rb +2 -0
  854. data/spec/{app → support}/models/dragon.rb +2 -0
  855. data/spec/{app → support}/models/driver.rb +3 -1
  856. data/spec/{app → support}/models/drug.rb +2 -0
  857. data/spec/{app → support}/models/dungeon.rb +2 -0
  858. data/spec/{app → support}/models/edit.rb +2 -0
  859. data/spec/{app → support}/models/email.rb +2 -0
  860. data/spec/{app → support}/models/employer.rb +2 -0
  861. data/spec/{app → support}/models/entry.rb +2 -0
  862. data/spec/support/models/eraser.rb +3 -0
  863. data/spec/{app → support}/models/even.rb +2 -0
  864. data/spec/{app → support}/models/event.rb +2 -0
  865. data/spec/{app → support}/models/exhibition.rb +2 -0
  866. data/spec/{app → support}/models/exhibitor.rb +2 -0
  867. data/spec/{app → support}/models/explosion.rb +2 -0
  868. data/spec/{app → support}/models/eye.rb +2 -0
  869. data/spec/{app → support}/models/eye_bowl.rb +2 -0
  870. data/spec/{app → support}/models/face.rb +2 -0
  871. data/spec/support/models/fanatic.rb +8 -0
  872. data/spec/{app → support}/models/favorite.rb +2 -0
  873. data/spec/{app → support}/models/filesystem.rb +2 -0
  874. data/spec/{app → support}/models/fire_hydrant.rb +2 -0
  875. data/spec/{app → support}/models/firefox.rb +2 -0
  876. data/spec/{app → support}/models/fish.rb +2 -0
  877. data/spec/{app → support}/models/folder.rb +2 -0
  878. data/spec/{app → support}/models/folder_item.rb +2 -0
  879. data/spec/{app → support}/models/fruits.rb +2 -0
  880. data/spec/{app → support}/models/game.rb +2 -0
  881. data/spec/{app → support}/models/ghost.rb +2 -0
  882. data/spec/support/models/guitar.rb +4 -0
  883. data/spec/support/models/hole.rb +12 -0
  884. data/spec/{app → support}/models/home.rb +2 -0
  885. data/spec/{app → support}/models/house.rb +2 -0
  886. data/spec/{app → support}/models/html_writer.rb +2 -0
  887. data/spec/{app → support}/models/id_key.rb +2 -0
  888. data/spec/support/models/idnodef.rb +7 -0
  889. data/spec/{app → support}/models/image.rb +2 -0
  890. data/spec/{app → support}/models/implant.rb +11 -0
  891. data/spec/support/models/instrument.rb +8 -0
  892. data/spec/{app → support}/models/item.rb +3 -1
  893. data/spec/{app → support}/models/jar.rb +2 -0
  894. data/spec/{app → support}/models/kaleidoscope.rb +2 -0
  895. data/spec/{app → support}/models/kangaroo.rb +3 -1
  896. data/spec/{app → support}/models/label.rb +6 -1
  897. data/spec/{app → support}/models/language.rb +2 -0
  898. data/spec/{app → support}/models/lat_lng.rb +2 -0
  899. data/spec/{app → support}/models/league.rb +2 -0
  900. data/spec/support/models/learner.rb +4 -0
  901. data/spec/{app → support}/models/line_item.rb +2 -0
  902. data/spec/{app → support}/models/location.rb +2 -0
  903. data/spec/{app → support}/models/login.rb +2 -0
  904. data/spec/{app → support}/models/manufacturer.rb +2 -0
  905. data/spec/{app → support}/models/meat.rb +2 -0
  906. data/spec/{app → support}/models/membership.rb +3 -0
  907. data/spec/{app → support}/models/message.rb +2 -0
  908. data/spec/support/models/minim.rb +6 -0
  909. data/spec/{app → support}/models/mixed_drink.rb +2 -0
  910. data/spec/support/models/mop.rb +24 -0
  911. data/spec/{app → support}/models/movie.rb +2 -0
  912. data/spec/support/models/my_hash.rb +4 -0
  913. data/spec/{app → support}/models/name.rb +2 -0
  914. data/spec/support/models/name_only.rb +8 -0
  915. data/spec/{app → support}/models/node.rb +2 -0
  916. data/spec/{app → support}/models/note.rb +2 -0
  917. data/spec/support/models/nut.rb +7 -0
  918. data/spec/{app → support}/models/odd.rb +2 -0
  919. data/spec/support/models/order.rb +12 -0
  920. data/spec/{app → support}/models/ordered_post.rb +3 -1
  921. data/spec/{app → support}/models/ordered_preference.rb +2 -0
  922. data/spec/{app → support}/models/oscar.rb +2 -0
  923. data/spec/support/models/other_owner_object.rb +4 -0
  924. data/spec/{app → support}/models/override.rb +2 -0
  925. data/spec/{app → support}/models/ownable.rb +2 -0
  926. data/spec/{app → support}/models/owner.rb +4 -0
  927. data/spec/{app → support}/models/pack.rb +2 -0
  928. data/spec/{app → support}/models/page.rb +2 -0
  929. data/spec/{app → support}/models/page_question.rb +2 -0
  930. data/spec/{app → support}/models/palette.rb +3 -1
  931. data/spec/{app → support}/models/parent.rb +2 -0
  932. data/spec/{app → support}/models/parent_doc.rb +2 -0
  933. data/spec/support/models/passport.rb +22 -0
  934. data/spec/{app → support}/models/patient.rb +2 -0
  935. data/spec/{app → support}/models/pdf_writer.rb +2 -0
  936. data/spec/support/models/pencil.rb +3 -0
  937. data/spec/{app → support}/models/person.rb +22 -1
  938. data/spec/{app → support}/models/pet.rb +2 -0
  939. data/spec/{app → support}/models/pet_owner.rb +2 -0
  940. data/spec/{app → support}/models/phone.rb +5 -1
  941. data/spec/support/models/piano.rb +4 -0
  942. data/spec/{app → support}/models/pizza.rb +2 -0
  943. data/spec/{app → support}/models/player.rb +4 -0
  944. data/spec/{app → support}/models/post.rb +2 -0
  945. data/spec/{app → support}/models/post_genre.rb +2 -0
  946. data/spec/support/models/powerup.rb +25 -0
  947. data/spec/{app → support}/models/preference.rb +2 -0
  948. data/spec/{app → support}/models/princess.rb +2 -0
  949. data/spec/{app → support}/models/product.rb +3 -0
  950. data/spec/support/models/profile.rb +17 -0
  951. data/spec/{app → support}/models/pronunciation.rb +2 -0
  952. data/spec/{app → support}/models/pub.rb +2 -0
  953. data/spec/support/models/publication/encyclopedia.rb +11 -0
  954. data/spec/support/models/publication/review.rb +13 -0
  955. data/spec/support/models/publication.rb +4 -0
  956. data/spec/{app → support}/models/purchase.rb +2 -0
  957. data/spec/support/models/purchased_item.rb +10 -0
  958. data/spec/{app → support}/models/question.rb +2 -0
  959. data/spec/{app → support}/models/quiz.rb +2 -0
  960. data/spec/{app → support}/models/rating.rb +2 -0
  961. data/spec/{app → support}/models/record.rb +2 -0
  962. data/spec/{app → support}/models/registry.rb +3 -0
  963. data/spec/{app → support}/models/role.rb +2 -0
  964. data/spec/{app → support}/models/root_category.rb +2 -0
  965. data/spec/{app → support}/models/sandwich.rb +2 -0
  966. data/spec/{app → support}/models/scheduler.rb +2 -0
  967. data/spec/support/models/school.rb +14 -0
  968. data/spec/support/models/scribe.rb +7 -0
  969. data/spec/support/models/sealer.rb +7 -0
  970. data/spec/support/models/seat.rb +24 -0
  971. data/spec/{app → support}/models/seo.rb +2 -0
  972. data/spec/support/models/series.rb +7 -0
  973. data/spec/{app → support}/models/server.rb +2 -0
  974. data/spec/{app → support}/models/service.rb +2 -0
  975. data/spec/{app → support}/models/shape.rb +4 -2
  976. data/spec/{app → support}/models/shelf.rb +2 -0
  977. data/spec/support/models/shield.rb +18 -0
  978. data/spec/{app → support}/models/shipment_address.rb +2 -0
  979. data/spec/{app → support}/models/shipping_container.rb +2 -0
  980. data/spec/{app → support}/models/shipping_pack.rb +2 -0
  981. data/spec/support/models/shirt.rb +11 -0
  982. data/spec/{app → support}/models/shop.rb +2 -0
  983. data/spec/{app → support}/models/short_agent.rb +2 -0
  984. data/spec/{app → support}/models/short_quiz.rb +2 -0
  985. data/spec/{app → support}/models/simple.rb +2 -0
  986. data/spec/{app → support}/models/slave.rb +2 -0
  987. data/spec/{app → support}/models/song.rb +2 -0
  988. data/spec/{app → support}/models/sound.rb +2 -0
  989. data/spec/support/models/spacer.rb +7 -0
  990. data/spec/{app → support}/models/square.rb +2 -0
  991. data/spec/{app → support}/models/staff.rb +2 -0
  992. data/spec/{app → support}/models/store_as_dup_test1.rb +2 -0
  993. data/spec/{app → support}/models/store_as_dup_test2.rb +2 -0
  994. data/spec/support/models/store_as_dup_test3.rb +7 -0
  995. data/spec/support/models/store_as_dup_test4.rb +7 -0
  996. data/spec/{app → support}/models/strategy.rb +2 -0
  997. data/spec/support/models/student.rb +14 -0
  998. data/spec/{app → support}/models/sub_item.rb +2 -0
  999. data/spec/{app → support}/models/subscription.rb +2 -0
  1000. data/spec/{app → support}/models/survey.rb +2 -0
  1001. data/spec/{app → support}/models/symptom.rb +2 -0
  1002. data/spec/support/models/system_role.rb +7 -0
  1003. data/spec/{app → support}/models/tag.rb +2 -0
  1004. data/spec/{app → support}/models/target.rb +2 -0
  1005. data/spec/{app → support}/models/template.rb +2 -0
  1006. data/spec/{app → support}/models/thing.rb +2 -0
  1007. data/spec/support/models/threadlocker.rb +7 -0
  1008. data/spec/{app → support}/models/title.rb +2 -0
  1009. data/spec/{app → support}/models/tool.rb +4 -2
  1010. data/spec/{app → support}/models/topping.rb +2 -0
  1011. data/spec/support/models/toy.rb +9 -0
  1012. data/spec/{app → support}/models/track.rb +2 -0
  1013. data/spec/{app → support}/models/translation.rb +2 -0
  1014. data/spec/{app → support}/models/tree.rb +2 -0
  1015. data/spec/support/models/truck.rb +7 -0
  1016. data/spec/{app → support}/models/user.rb +2 -0
  1017. data/spec/{app → support}/models/user_account.rb +2 -0
  1018. data/spec/{app → support}/models/validation_callback.rb +2 -0
  1019. data/spec/support/models/vehicle.rb +18 -0
  1020. data/spec/{app → support}/models/version.rb +2 -0
  1021. data/spec/{app → support}/models/vertex.rb +3 -1
  1022. data/spec/{app → support}/models/vet_visit.rb +2 -0
  1023. data/spec/{app → support}/models/video.rb +2 -0
  1024. data/spec/support/models/video_game.rb +3 -0
  1025. data/spec/support/models/washer.rb +7 -0
  1026. data/spec/support/models/weapon.rb +25 -0
  1027. data/spec/{app → support}/models/wiki_page.rb +3 -0
  1028. data/spec/{app → support}/models/word.rb +2 -0
  1029. data/spec/{app → support}/models/word_origin.rb +2 -0
  1030. data/spec/{app → support}/models/writer.rb +4 -2
  1031. data/spec/support/schema_maps/schema_map_aws.json +17 -0
  1032. data/spec/support/schema_maps/schema_map_aws_key_alt_names.json +12 -0
  1033. data/spec/support/schema_maps/schema_map_azure.json +17 -0
  1034. data/spec/support/schema_maps/schema_map_azure_key_alt_names.json +12 -0
  1035. data/spec/support/schema_maps/schema_map_gcp.json +17 -0
  1036. data/spec/support/schema_maps/schema_map_gcp_key_alt_names.json +12 -0
  1037. data/spec/support/schema_maps/schema_map_kmip.json +17 -0
  1038. data/spec/support/schema_maps/schema_map_kmip_key_alt_names.json +12 -0
  1039. data/spec/support/schema_maps/schema_map_local.json +18 -0
  1040. data/spec/support/schema_maps/schema_map_local_key_alt_names.json +12 -0
  1041. data/spec/support/shared/time.rb +53 -0
  1042. data/spec/support/spec_config.rb +64 -0
  1043. data.tar.gz.sig +1 -2
  1044. metadata +1158 -615
  1045. metadata.gz.sig +0 -0
  1046. data/lib/mongoid/criteria/queryable/forwardable.rb +0 -65
  1047. data/lib/mongoid/errors/eager_load.rb +0 -22
  1048. data/lib/mongoid/errors/invalid_value.rb +0 -16
  1049. data/lib/mongoid/matchable/all.rb +0 -27
  1050. data/lib/mongoid/matchable/and.rb +0 -30
  1051. data/lib/mongoid/matchable/default.rb +0 -72
  1052. data/lib/mongoid/matchable/elem_match.rb +0 -34
  1053. data/lib/mongoid/matchable/exists.rb +0 -23
  1054. data/lib/mongoid/matchable/gt.rb +0 -23
  1055. data/lib/mongoid/matchable/gte.rb +0 -23
  1056. data/lib/mongoid/matchable/in.rb +0 -24
  1057. data/lib/mongoid/matchable/lt.rb +0 -23
  1058. data/lib/mongoid/matchable/lte.rb +0 -23
  1059. data/lib/mongoid/matchable/ne.rb +0 -21
  1060. data/lib/mongoid/matchable/nin.rb +0 -22
  1061. data/lib/mongoid/matchable/nor.rb +0 -37
  1062. data/lib/mongoid/matchable/or.rb +0 -33
  1063. data/lib/mongoid/matchable/regexp.rb +0 -27
  1064. data/lib/mongoid/matchable/size.rb +0 -21
  1065. data/lib/support/ruby_version.rb +0 -26
  1066. data/spec/app/models/actress.rb +0 -2
  1067. data/spec/app/models/augmentation.rb +0 -11
  1068. data/spec/app/models/bed.rb +0 -1
  1069. data/spec/app/models/car.rb +0 -1
  1070. data/spec/app/models/circus.rb +0 -7
  1071. data/spec/app/models/eraser.rb +0 -1
  1072. data/spec/app/models/learner.rb +0 -2
  1073. data/spec/app/models/my_hash.rb +0 -2
  1074. data/spec/app/models/passport.rb +0 -5
  1075. data/spec/app/models/pencil.rb +0 -1
  1076. data/spec/app/models/powerup.rb +0 -11
  1077. data/spec/app/models/profile.rb +0 -5
  1078. data/spec/app/models/series.rb +0 -4
  1079. data/spec/app/models/truck.rb +0 -3
  1080. data/spec/app/models/vehicle.rb +0 -11
  1081. data/spec/app/models/video_game.rb +0 -1
  1082. data/spec/app/models/weapon.rb +0 -11
  1083. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -58
  1084. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -58
  1085. data/spec/mongoid/criteria/queryable/forwardable_spec.rb +0 -87
  1086. data/spec/mongoid/matchable/all_spec.rb +0 -31
  1087. data/spec/mongoid/matchable/and_spec.rb +0 -187
  1088. data/spec/mongoid/matchable/default_spec.rb +0 -130
  1089. data/spec/mongoid/matchable/elem_match_spec.rb +0 -106
  1090. data/spec/mongoid/matchable/exists_spec.rb +0 -57
  1091. data/spec/mongoid/matchable/gt_spec.rb +0 -86
  1092. data/spec/mongoid/matchable/gte_spec.rb +0 -84
  1093. data/spec/mongoid/matchable/in_spec.rb +0 -49
  1094. data/spec/mongoid/matchable/lt_spec.rb +0 -85
  1095. data/spec/mongoid/matchable/lte_spec.rb +0 -85
  1096. data/spec/mongoid/matchable/ne_spec.rb +0 -46
  1097. data/spec/mongoid/matchable/nin_spec.rb +0 -48
  1098. data/spec/mongoid/matchable/nor_spec.rb +0 -209
  1099. data/spec/mongoid/matchable/or_spec.rb +0 -131
  1100. data/spec/mongoid/matchable/regexp_spec.rb +0 -59
  1101. data/spec/mongoid/matchable/size_spec.rb +0 -25
  1102. data/spec/mongoid/matchable_spec.rb +0 -853
  1103. /data/spec/{app → support}/models/array_field.rb +0 -0
  1104. /data/spec/{app → support}/models/updatable.rb +0 -0
@@ -1,4 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  module Mongoid
3
4
  class Criteria
4
5
  module Queryable
@@ -10,21 +11,15 @@ module Mongoid
10
11
  extend Macroable
11
12
 
12
13
  # Constant for a LineString $geometry.
13
- #
14
- # @since 2.0.0
15
14
  LINE_STRING = "LineString"
16
15
 
17
16
  # Constant for a Point $geometry.
18
- #
19
- # @since 2.0.0
20
17
  POINT = "Point"
21
18
 
22
19
  # Constant for a Polygon $geometry.
23
- #
24
- # @since 2.0.0
25
20
  POLYGON = "Polygon"
26
21
 
27
- # @attribute [rw] negating If the next spression is negated.
22
+ # @attribute [rw] negating If the next expression is negated.
28
23
  # @attribute [rw] selector The query selector.
29
24
  attr_accessor :negating, :selector
30
25
 
@@ -36,13 +31,35 @@ module Mongoid
36
31
  # @example Execute an $all in a where query.
37
32
  # selectable.where(:field.all => [ 1, 2 ])
38
33
  #
39
- # @param [ Hash ] criterion The key value pairs for $all matching.
34
+ # @param [ Hash... ] *criteria The key value pair(s) for $all matching.
40
35
  #
41
36
  # @return [ Selectable ] The cloned selectable.
42
- #
43
- # @since 1.0.0
44
- def all(criterion = nil)
45
- send(strategy || :__union__, with_array_values(criterion), "$all")
37
+ def all(*criteria)
38
+ if criteria.empty?
39
+ return clone.tap do |query|
40
+ query.reset_strategies!
41
+ end
42
+ end
43
+
44
+ criteria.inject(clone) do |query, condition|
45
+ if condition.nil?
46
+ raise Errors::CriteriaArgumentRequired, :all
47
+ end
48
+
49
+ condition = expand_condition_to_array_values(condition)
50
+
51
+ if strategy
52
+ send(strategy, condition, "$all")
53
+ else
54
+ condition.inject(query) do |_query, (field, value)|
55
+ v = {'$all' => value}
56
+ if negating?
57
+ v = {'$not' => v}
58
+ end
59
+ _query.add_field_expression(field.to_s, v)
60
+ end
61
+ end
62
+ end.reset_strategies!
46
63
  end
47
64
  alias :all_in :all
48
65
  key :all, :union, "$all"
@@ -52,14 +69,43 @@ module Mongoid
52
69
  # @example Add the criterion.
53
70
  # selectable.and({ field: value }, { other: value })
54
71
  #
55
- # @param [ Array<Hash> ] criterion Multiple key/value pair matches that
56
- # all must match to return results.
57
- #
58
- # @return [ Selectable ] The cloned selectable.
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.
59
75
  #
60
- # @since 1.0.0
61
- def and(*criterion)
62
- __multi__(criterion, "$and")
76
+ # @return [ Selectable ] The new selectable.
77
+ def and(*criteria)
78
+ _mongoid_flatten_arrays(criteria).inject(self.clone) do |c, new_s|
79
+ if new_s.is_a?(Selectable)
80
+ new_s = new_s.selector
81
+ end
82
+ normalized = _mongoid_expand_keys(new_s)
83
+ normalized.each do |k, v|
84
+ k = k.to_s
85
+ if c.selector[k]
86
+ # There is already a condition on k.
87
+ # If v is an operator, and all existing conditions are
88
+ # also operators, and v isn't present in existing conditions,
89
+ # we can add to existing conditions.
90
+ # Otherwise use $and.
91
+ if v.is_a?(Hash) &&
92
+ v.length == 1 &&
93
+ (new_k = v.keys.first).start_with?('$') &&
94
+ (existing_kv = c.selector[k]).is_a?(Hash) &&
95
+ !existing_kv.key?(new_k) &&
96
+ existing_kv.keys.all? { |sub_k| sub_k.start_with?('$') }
97
+ then
98
+ merged_v = c.selector[k].merge(v)
99
+ c.selector.store(k, merged_v)
100
+ else
101
+ c = c.send(:__multi__, [k => v], '$and')
102
+ end
103
+ else
104
+ c.selector.store(k, v)
105
+ end
106
+ end
107
+ c
108
+ end
63
109
  end
64
110
  alias :all_of :and
65
111
 
@@ -74,9 +120,11 @@ module Mongoid
74
120
  # @param [ Hash ] criterion Multiple key/range pairs.
75
121
  #
76
122
  # @return [ Selectable ] The cloned selectable.
77
- #
78
- # @since 1.0.0
79
- def between(criterion = nil)
123
+ def between(criterion)
124
+ if criterion.nil?
125
+ raise Errors::CriteriaArgumentRequired, :between
126
+ end
127
+
80
128
  selection(criterion) do |selector, field, value|
81
129
  selector.store(
82
130
  field,
@@ -102,10 +150,12 @@ module Mongoid
102
150
  # @param [ Hash ] criterion The field/match pairs.
103
151
  #
104
152
  # @return [ Selectable ] The cloned selectable.
105
- #
106
- # @since 1.0.0
107
- def elem_match(criterion = nil)
108
- __override__(criterion, "$elemMatch")
153
+ def elem_match(criterion)
154
+ if criterion.nil?
155
+ raise Errors::CriteriaArgumentRequired, :elem_match
156
+ end
157
+
158
+ and_or_override(criterion, "$elemMatch")
109
159
  end
110
160
  key :elem_match, :override, "$elemMatch"
111
161
 
@@ -123,45 +173,61 @@ module Mongoid
123
173
  # @param [ Hash ] criterion The field/boolean existence checks.
124
174
  #
125
175
  # @return [ Selectable ] The cloned selectable.
126
- #
127
- # @since 1.0.0
128
- def exists(criterion = nil)
176
+ def exists(criterion)
177
+ if criterion.nil?
178
+ raise Errors::CriteriaArgumentRequired, :exists
179
+ end
180
+
129
181
  typed_override(criterion, "$exists") do |value|
130
- ::Boolean.evolve(value)
182
+ Mongoid::Boolean.evolve(value)
131
183
  end
132
184
  end
133
185
  key :exists, :override, "$exists" do |value|
134
- ::Boolean.evolve(value)
186
+ Mongoid::Boolean.evolve(value)
135
187
  end
136
188
 
137
- # Add a $geoIntersects or $geoWithin selection. Symbol operators must be used as shown in
138
- # the examples to expand the criteria.
189
+ # Add a $geoIntersects or $geoWithin selection. Symbol operators must
190
+ # be used as shown in the examples to expand the criteria.
139
191
  #
140
192
  # @note The only valid geometry shapes for a $geoIntersects are:
141
193
  # :intersects_line, :intersects_point, and :intersects_polygon.
142
194
  #
143
- # @note The only valid geometry shape for a $geoWithin is :within_polygon
195
+ # @note The only valid options for a $geoWithin query are the geometry
196
+ # shape :within_polygon and the operator :within_box.
197
+ #
198
+ # @note The :within_box operator for the $geoWithin query expects the
199
+ # lower left (south west) coordinate pair as the first argument and
200
+ # the upper right (north east) as the second argument.
201
+ # Important: When latitude and longitude are passed, longitude is
202
+ # expected as the first element of the coordinate pair.
203
+ # Source: https://www.mongodb.com/docs/manual/reference/operator/query/box/
144
204
  #
145
205
  # @example Add a geo intersect criterion for a line.
146
- # query.geo_spacial(:location.intersects_line => [[ 1, 10 ], [ 2, 10 ]])
206
+ # query.geo_spatial(:location.intersects_line => [[ 1, 10 ], [ 2, 10 ]])
147
207
  #
148
208
  # @example Add a geo intersect criterion for a point.
149
- # query.geo_spacial(:location.intersects_point => [[ 1, 10 ]])
209
+ # query.geo_spatial(:location.intersects_point => [[ 1, 10 ]])
150
210
  #
151
211
  # @example Add a geo intersect criterion for a polygon.
152
- # query.geo_spacial(:location.intersects_polygon => [[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]])
212
+ # query.geo_spatial(:location.intersects_polygon => [[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]])
153
213
  #
154
214
  # @example Add a geo within criterion for a polygon.
155
- # query.geo_spacial(:location.within_polygon => [[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]])
215
+ # query.geo_spatial(:location.within_polygon => [[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]])
216
+ #
217
+ # @example Add a geo within criterion for a box.
218
+ # query.geo_spatial(:location.within_box => [[ 1, 10 ], [ 2, 10 ])
156
219
  #
157
220
  # @param [ Hash ] criterion The criterion.
158
221
  #
159
222
  # @return [ Selectable ] The cloned selectable.
160
- #
161
- # @since 2.0.0
162
- def geo_spacial(criterion = nil)
223
+ def geo_spatial(criterion)
224
+ if criterion.nil?
225
+ raise Errors::CriteriaArgumentRequired, :geo_spatial
226
+ end
227
+
163
228
  __merge__(criterion)
164
229
  end
230
+
165
231
  key :intersects_line, :override, "$geoIntersects", "$geometry" do |value|
166
232
  { "type" => LINE_STRING, "coordinates" => value }
167
233
  end
@@ -174,6 +240,27 @@ module Mongoid
174
240
  key :within_polygon, :override, "$geoWithin", "$geometry" do |value|
175
241
  { "type" => POLYGON, "coordinates" => value }
176
242
  end
243
+ key :within_box, :override, "$geoWithin", "$box"
244
+
245
+ # Add the $eq criterion to the selector.
246
+ #
247
+ # @example Add the $eq criterion.
248
+ # selectable.eq(age: 60)
249
+ #
250
+ # @example Execute an $eq in a where query.
251
+ # selectable.where(:field.eq => 10)
252
+ #
253
+ # @param [ Hash ] criterion The field/value pairs to check.
254
+ #
255
+ # @return [ Selectable ] The cloned selectable.
256
+ def eq(criterion)
257
+ if criterion.nil?
258
+ raise Errors::CriteriaArgumentRequired, :eq
259
+ end
260
+
261
+ and_or_override(criterion, "$eq")
262
+ end
263
+ key :eq, :override, "$eq"
177
264
 
178
265
  # Add the $gt criterion to the selector.
179
266
  #
@@ -186,10 +273,12 @@ module Mongoid
186
273
  # @param [ Hash ] criterion The field/value pairs to check.
187
274
  #
188
275
  # @return [ Selectable ] The cloned selectable.
189
- #
190
- # @since 1.0.0
191
- def gt(criterion = nil)
192
- __override__(criterion, "$gt")
276
+ def gt(criterion)
277
+ if criterion.nil?
278
+ raise Errors::CriteriaArgumentRequired, :gt
279
+ end
280
+
281
+ and_or_override(criterion, "$gt")
193
282
  end
194
283
  key :gt, :override, "$gt"
195
284
 
@@ -204,10 +293,12 @@ module Mongoid
204
293
  # @param [ Hash ] criterion The field/value pairs to check.
205
294
  #
206
295
  # @return [ Selectable ] The cloned selectable.
207
- #
208
- # @since 1.0.0
209
- def gte(criterion = nil)
210
- __override__(criterion, "$gte")
296
+ def gte(criterion)
297
+ if criterion.nil?
298
+ raise Errors::CriteriaArgumentRequired, :gte
299
+ end
300
+
301
+ and_or_override(criterion, "$gte")
211
302
  end
212
303
  key :gte, :override, "$gte"
213
304
 
@@ -222,13 +313,27 @@ module Mongoid
222
313
  # @example Execute an $in in a where query.
223
314
  # selectable.where(:field.in => [ 1, 2, 3 ])
224
315
  #
225
- # @param [ Hash ] criterion The field/value criterion pairs.
316
+ # @param [ Hash ] condition The field/value criterion pairs.
226
317
  #
227
318
  # @return [ Selectable ] The cloned selectable.
228
- #
229
- # @since 1.0.0
230
- def in(criterion = nil)
231
- send(strategy || :__intersect__, with_array_values(criterion), "$in")
319
+ def in(condition)
320
+ if condition.nil?
321
+ raise Errors::CriteriaArgumentRequired, :in
322
+ end
323
+
324
+ condition = expand_condition_to_array_values(condition)
325
+
326
+ if strategy
327
+ send(strategy, condition, "$in")
328
+ else
329
+ condition.inject(clone) do |query, (field, value)|
330
+ v = {'$in' => value}
331
+ if negating?
332
+ v = {'$not' => v}
333
+ end
334
+ query.add_field_expression(field.to_s, v)
335
+ end.reset_strategies!
336
+ end
232
337
  end
233
338
  alias :any_in :in
234
339
  key :in, :intersect, "$in"
@@ -244,10 +349,12 @@ module Mongoid
244
349
  # @param [ Hash ] criterion The field/value pairs to check.
245
350
  #
246
351
  # @return [ Selectable ] The cloned selectable.
247
- #
248
- # @since 1.0.0
249
- def lt(criterion = nil)
250
- __override__(criterion, "$lt")
352
+ def lt(criterion)
353
+ if criterion.nil?
354
+ raise Errors::CriteriaArgumentRequired, :lt
355
+ end
356
+
357
+ and_or_override(criterion, "$lt")
251
358
  end
252
359
  key :lt, :override, "$lt"
253
360
 
@@ -262,10 +369,12 @@ module Mongoid
262
369
  # @param [ Hash ] criterion The field/value pairs to check.
263
370
  #
264
371
  # @return [ Selectable ] The cloned selectable.
265
- #
266
- # @since 1.0.0
267
- def lte(criterion = nil)
268
- __override__(criterion, "$lte")
372
+ def lte(criterion)
373
+ if criterion.nil?
374
+ raise Errors::CriteriaArgumentRequired, :lte
375
+ end
376
+
377
+ and_or_override(criterion, "$lte")
269
378
  end
270
379
  key :lte, :override, "$lte"
271
380
 
@@ -277,9 +386,12 @@ module Mongoid
277
386
  # @param [ Hash ] criterion The field/distance pairs.
278
387
  #
279
388
  # @return [ Selectable ] The cloned selectable.
280
- #
281
- # @since 1.0.0
282
- def max_distance(criterion = nil)
389
+ def max_distance(criterion)
390
+ if criterion.nil?
391
+ raise Errors::CriteriaArgumentRequired, :max_distance
392
+ end
393
+
394
+ # $maxDistance must be given together with $near
283
395
  __add__(criterion, "$maxDistance")
284
396
  end
285
397
 
@@ -294,10 +406,12 @@ module Mongoid
294
406
  # @param [ Hash ] criterion The field/mod selections.
295
407
  #
296
408
  # @return [ Selectable ] The cloned selectable.
297
- #
298
- # @since 1.0.0
299
- def mod(criterion = nil)
300
- __override__(criterion, "$mod")
409
+ def mod(criterion)
410
+ if criterion.nil?
411
+ raise Errors::CriteriaArgumentRequired, :mod
412
+ end
413
+
414
+ and_or_override(criterion, "$mod")
301
415
  end
302
416
  key :mod, :override, "$mod"
303
417
 
@@ -312,10 +426,12 @@ module Mongoid
312
426
  # @param [ Hash ] criterion The field/ne selections.
313
427
  #
314
428
  # @return [ Selectable ] The cloned selectable.
315
- #
316
- # @since 1.0.0
317
- def ne(criterion = nil)
318
- __override__(criterion, "$ne")
429
+ def ne(criterion)
430
+ if criterion.nil?
431
+ raise Errors::CriteriaArgumentRequired, :ne
432
+ end
433
+
434
+ and_or_override(criterion, "$ne")
319
435
  end
320
436
  alias :excludes :ne
321
437
  key :ne, :override, "$ne"
@@ -331,10 +447,12 @@ module Mongoid
331
447
  # @param [ Hash ] criterion The field/location pair.
332
448
  #
333
449
  # @return [ Selectable ] The cloned selectable.
334
- #
335
- # @since 1.0.0
336
- def near(criterion = nil)
337
- __override__(criterion, "$near")
450
+ def near(criterion)
451
+ if criterion.nil?
452
+ raise Errors::CriteriaArgumentRequired, :near
453
+ end
454
+
455
+ and_or_override(criterion, "$near")
338
456
  end
339
457
  key :near, :override, "$near"
340
458
 
@@ -349,10 +467,12 @@ module Mongoid
349
467
  # @param [ Hash ] criterion The field/location pair.
350
468
  #
351
469
  # @return [ Selectable ] The cloned selectable.
352
- #
353
- # @since 1.0.0
354
- def near_sphere(criterion = nil)
355
- __override__(criterion, "$nearSphere")
470
+ def near_sphere(criterion)
471
+ if criterion.nil?
472
+ raise Errors::CriteriaArgumentRequired, :near_sphere
473
+ end
474
+
475
+ and_or_override(criterion, "$nearSphere")
356
476
  end
357
477
  key :near_sphere, :override, "$nearSphere"
358
478
 
@@ -367,13 +487,27 @@ module Mongoid
367
487
  # @example Execute an $nin in a where query.
368
488
  # selectable.where(:field.nin => [ 1, 2, 3 ])
369
489
  #
370
- # @param [ Hash ] criterion The field/value criterion pairs.
490
+ # @param [ Hash ] condition The field/value criterion pairs.
371
491
  #
372
492
  # @return [ Selectable ] The cloned selectable.
373
- #
374
- # @since 1.0.0
375
- def nin(criterion = nil)
376
- send(strategy || :__intersect__, with_array_values(criterion), "$nin")
493
+ def nin(condition)
494
+ if condition.nil?
495
+ raise Errors::CriteriaArgumentRequired, :nin
496
+ end
497
+
498
+ condition = expand_condition_to_array_values(condition)
499
+
500
+ if strategy
501
+ send(strategy, condition, "$nin")
502
+ else
503
+ condition.inject(clone) do |query, (field, value)|
504
+ v = {'$nin' => value}
505
+ if negating?
506
+ v = {'$not' => v}
507
+ end
508
+ query.add_field_expression(field.to_s, v)
509
+ end.reset_strategies!
510
+ end
377
511
  end
378
512
  alias :not_in :nin
379
513
  key :nin, :intersect, "$nin"
@@ -383,13 +517,12 @@ module Mongoid
383
517
  # @example Add the $nor selection.
384
518
  # selectable.nor(field: 1, field: 2)
385
519
  #
386
- # @param [ Array ] criterion An array of hash criterion.
520
+ # @param [ [ Hash | Criteria | Array<Hash | Criteria> ]... ] *criteria
521
+ # Multiple key/value pair matches or Criteria objects.
387
522
  #
388
- # @return [ Selectable ] The cloned selectable.
389
- #
390
- # @since 1.0.0
391
- def nor(*criterion)
392
- __multi__(criterion, "$nor")
523
+ # @return [ Selectable ] The new selectable.
524
+ def nor(*criteria)
525
+ _mongoid_add_top_level_operation('$nor', criteria)
393
526
  end
394
527
 
395
528
  # Is the current selectable negating the next selection?
@@ -397,16 +530,14 @@ module Mongoid
397
530
  # @example Is the selectable negating?
398
531
  # selectable.negating?
399
532
  #
400
- # @return [ true, false ] If the selectable is negating.
401
- #
402
- # @since 1.0.0
533
+ # @return [ true | false ] If the selectable is negating.
403
534
  def negating?
404
535
  !!negating
405
536
  end
406
537
 
407
- # Negate the next selection.
538
+ # Negate the arguments, or the next selection if no arguments are given.
408
539
  #
409
- # @example Negate the selection.
540
+ # @example Negate the next selection.
410
541
  # selectable.not.in(field: [ 1, 2 ])
411
542
  #
412
543
  # @example Add the $not criterion.
@@ -415,34 +546,159 @@ module Mongoid
415
546
  # @example Execute a $not in a where query.
416
547
  # selectable.where(:field.not => /Bob/)
417
548
  #
418
- # @param [ Hash ] criterion The field/value pairs to negate.
549
+ # @param [ [ Hash | Criteria ]... ] *criteria The key/value pair
550
+ # matches or Criteria objects to negate.
419
551
  #
420
- # @return [ Selectable ] The negated selectable.
421
- #
422
- # @since 1.0.0
423
- def not(*criterion)
424
- if criterion.empty?
425
- tap { |query| query.negating = true }
552
+ # @return [ Selectable ] The new selectable.
553
+ def not(*criteria)
554
+ if criteria.empty?
555
+ dup.tap { |query| query.negating = true }
426
556
  else
427
- __override__(criterion.first, "$not")
557
+ criteria.compact.inject(self.clone) do |c, new_s|
558
+ if new_s.is_a?(Selectable)
559
+ new_s = new_s.selector
560
+ end
561
+ _mongoid_expand_keys(new_s).each do |k, v|
562
+ k = k.to_s
563
+ if c.selector[k] || k.start_with?('$')
564
+ c = c.send(:__multi__, [{'$nor' => [{k => v}]}], '$and')
565
+ else
566
+ if v.is_a?(Hash)
567
+ c = c.send(:__multi__, [{'$nor' => [{k => v}]}], '$and')
568
+ else
569
+ if v.is_a?(Regexp)
570
+ negated_operator = '$not'
571
+ else
572
+ negated_operator = '$ne'
573
+ end
574
+ c = c.send(:__override__, {k => v}, negated_operator)
575
+ end
576
+ end
577
+ end
578
+ c
579
+ end
428
580
  end
429
581
  end
430
582
  key :not, :override, "$not"
431
583
 
432
- # Adds $or selection to the selectable.
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
+
613
+ # Creates a disjunction using $or from the existing criteria in the
614
+ # receiver and the provided arguments.
615
+ #
616
+ # This behavior (receiver becoming one of the disjunction operands)
617
+ # matches ActiveRecord's +or+ behavior.
433
618
  #
434
- # @example Add the $or selection.
619
+ # Use +any_of+ to add a disjunction of the arguments as an additional
620
+ # constraint to the criteria already existing in the receiver.
621
+ #
622
+ # Each argument can be a Hash, a Criteria object, an array of
623
+ # Hash or Criteria objects, or a nested array. Nested arrays will be
624
+ # flattened and can be of any depth. Passing arrays is deprecated.
625
+ #
626
+ # @example Add the $or selection where both fields must have the specified values.
435
627
  # selectable.or(field: 1, field: 2)
436
628
  #
437
- # @param [ Array ] criterion An array of hash criterion.
629
+ # @example Add the $or selection where either value match is sufficient.
630
+ # selectable.or({field: 1}, {field: 2})
438
631
  #
439
- # @return [ Selectable ] The cloned selectable.
632
+ # @example Same as previous example but using the deprecated array wrap.
633
+ # selectable.or([{field: 1}, {field: 2}])
634
+ #
635
+ # @example Same as previous example, also deprecated.
636
+ # selectable.or([{field: 1}], [{field: 2}])
637
+ #
638
+ # @param [ [ Hash | Criteria | Array<Hash | Criteria> ]... ] *criteria
639
+ # Multiple key/value pair matches or Criteria objects, or arrays
640
+ # thereof. Passing arrays is deprecated.
641
+ #
642
+ # @return [ Selectable ] The new selectable.
643
+ def or(*criteria)
644
+ _mongoid_add_top_level_operation('$or', criteria)
645
+ end
646
+
647
+ # Adds a disjunction of the arguments as an additional constraint
648
+ # to the criteria already existing in the receiver.
649
+ #
650
+ # Use +or+ to make the receiver one of the disjunction operands.
651
+ #
652
+ # Each argument can be a Hash, a Criteria object, an array of
653
+ # Hash or Criteria objects, or a nested array. Nested arrays will be
654
+ # flattened and can be of any depth. Passing arrays is deprecated.
440
655
  #
441
- # @since 1.0.0
442
- def or(*criterion)
443
- __multi__(criterion, "$or")
656
+ # @example Add the $or selection where both fields must have the specified values.
657
+ # selectable.any_of(field: 1, field: 2)
658
+ #
659
+ # @example Add the $or selection where either value match is sufficient.
660
+ # selectable.any_of({field: 1}, {field: 2})
661
+ #
662
+ # @example Same as previous example but using the deprecated array wrap.
663
+ # selectable.any_of([{field: 1}, {field: 2}])
664
+ #
665
+ # @example Same as previous example, also deprecated.
666
+ # selectable.any_of([{field: 1}], [{field: 2}])
667
+ #
668
+ # @param [ [ Hash | Criteria | Array<Hash | Criteria> ]... ] *criteria
669
+ # Multiple key/value pair matches or Criteria objects, or arrays
670
+ # thereof. Passing arrays is deprecated.
671
+ #
672
+ # @return [ Selectable ] The new selectable.
673
+ def any_of(*criteria)
674
+ criteria = _mongoid_flatten_arrays(criteria)
675
+ case criteria.length
676
+ when 0
677
+ clone
678
+ when 1
679
+ # When we have a single criteria, any_of behaves like and.
680
+ # Note: criteria can be a Query object, which #where method does
681
+ # not support.
682
+ self.and(*criteria)
683
+ else
684
+ # When we have multiple criteria, combine them all with $or
685
+ # and add the result to self.
686
+ exprs = criteria.map do |criterion|
687
+ if criterion.is_a?(Selectable)
688
+ _mongoid_expand_keys(criterion.selector)
689
+ else
690
+ Hash[criterion.map do |k, v|
691
+ if k.is_a?(Symbol)
692
+ [k.to_s, v]
693
+ else
694
+ [k, v]
695
+ end
696
+ end]
697
+ end
698
+ end
699
+ self.and('$or' => exprs)
700
+ end
444
701
  end
445
- alias :any_of :or
446
702
 
447
703
  # Add a $size selection for array fields.
448
704
  #
@@ -458,9 +714,11 @@ module Mongoid
458
714
  # @param [ Hash ] criterion The field/size pairs criterion.
459
715
  #
460
716
  # @return [ Selectable ] The cloned selectable.
461
- #
462
- # @since 1.0.0
463
- def with_size(criterion = nil)
717
+ def with_size(criterion)
718
+ if criterion.nil?
719
+ raise Errors::CriteriaArgumentRequired, :with_size
720
+ end
721
+
464
722
  typed_override(criterion, "$size") do |value|
465
723
  ::Integer.evolve(value)
466
724
  end
@@ -482,9 +740,11 @@ module Mongoid
482
740
  # @param [ Hash ] criterion The field/type pairs.
483
741
  #
484
742
  # @return [ Selectable ] The cloned selectable.
485
- #
486
- # @since 1.0.0
487
- def with_type(criterion = nil)
743
+ def with_type(criterion)
744
+ if criterion.nil?
745
+ raise Errors::CriteriaArgumentRequired, :with_type
746
+ end
747
+
488
748
  typed_override(criterion, "$type") do |value|
489
749
  ::Integer.evolve(value)
490
750
  end
@@ -501,20 +761,35 @@ module Mongoid
501
761
  # @example Construct a text search selector with options.
502
762
  # selectable.text_search("testing", :$language => "fr")
503
763
  #
504
- # @param [ String, Symbol ] terms A string of terms that MongoDB parses
764
+ # @note Per https://www.mongodb.com/docs/manual/reference/operator/query/text/
765
+ # it is not currently possible to supply multiple text search
766
+ # conditions in a query. Mongoid will build such a query but the
767
+ # server will return an error when trying to execute it.
768
+ #
769
+ # @param [ String | Symbol ] terms A string of terms that MongoDB parses
505
770
  # and uses to query the text index.
506
771
  # @param [ Hash ] opts Text search options. See MongoDB documentation
507
772
  # for options.
508
773
  #
509
774
  # @return [ Selectable ] The cloned selectable.
510
- #
511
- # @since 2.2.0
512
775
  def text_search(terms, opts = nil)
776
+ if terms.nil?
777
+ raise Errors::CriteriaArgumentRequired, :terms
778
+ end
779
+
513
780
  clone.tap do |query|
514
- if terms
515
- criterion = { :$text => { :$search => terms } }
516
- criterion[:$text].merge!(opts) if opts
517
- query.selector = criterion
781
+ criterion = {'$text' => { '$search' => terms }}
782
+ criterion['$text'].merge!(opts) if opts
783
+ if query.selector['$text']
784
+ # Per https://www.mongodb.com/docs/manual/reference/operator/query/text/
785
+ # multiple $text expressions are not currently supported by
786
+ # MongoDB server, but build the query correctly instead of
787
+ # overwriting previous text search condition with the currently
788
+ # given one.
789
+ Mongoid.logger.warn('Multiple $text expressions per query are not currently supported by the server')
790
+ query.selector = {'$and' => [query.selector]}.merge(criterion)
791
+ else
792
+ query.selector = query.selector.merge(criterion)
518
793
  end
519
794
  end
520
795
  end
@@ -529,23 +804,42 @@ module Mongoid
529
804
  # @example Add a javascript selection.
530
805
  # selectable.where("this.name == 'syd'")
531
806
  #
532
- # @param [ String, Hash ] criterion The javascript or standard selection.
807
+ # @param [ [ Hash | String ]... ] *criterion The standard selection
808
+ # or javascript string.
533
809
  #
534
810
  # @return [ Selectable ] The cloned selectable.
535
- #
536
- # @since 1.0.0
537
- def where(criterion = nil)
538
- # We need to save the criterion in an instance variable so Modifiable methods
539
- # know how to create a polymorphic object.
540
- @criterion = criterion
541
- criterion.is_a?(String) ? js_query(criterion) : expr_query(criterion)
811
+ def where(*criteria)
812
+ criteria.inject(clone) do |query, criterion|
813
+ if criterion.nil?
814
+ raise Errors::CriteriaArgumentRequired, :where
815
+ end
816
+
817
+ # We need to save the criterion in an instance variable so
818
+ # Modifiable methods know how to create a polymorphic object.
819
+ # Note that this method in principle accepts multiple criteria,
820
+ # but only the first one will be stored in @criterion. This
821
+ # works out to be fine because first_or_create etc. methods
822
+ # only ever specify one criterion to #where.
823
+ @criterion = criterion
824
+ if criterion.is_a?(String)
825
+ js_query(criterion)
826
+ else
827
+ expr_query(criterion)
828
+ end
829
+ end.reset_strategies!
542
830
  end
543
831
 
544
832
  private
545
833
 
546
- # Create the standard expression query.
834
+ # Adds the specified expression to the query.
547
835
  #
548
- # @api private
836
+ # Criterion must be a hash in one of the following forms:
837
+ # - {field_name: value}
838
+ # - {'field_name' => value}
839
+ # - {key_instance: value}
840
+ # - {'$operator' => operator_value_expression}
841
+ #
842
+ # Field name and operator may be given as either strings or symbols.
549
843
  #
550
844
  # @example Create the selection.
551
845
  # selectable.expr_query(age: 50)
@@ -553,11 +847,27 @@ module Mongoid
553
847
  # @param [ Hash ] criterion The field/value pairs.
554
848
  #
555
849
  # @return [ Selectable ] The cloned selectable.
556
- #
557
- # @since 1.0.0
850
+ # @api private
558
851
  def expr_query(criterion)
559
- selection(criterion) do |selector, field, value|
560
- selector.merge!(field.__expr_part__(value.__expand_complex__, negating?))
852
+ if criterion.nil?
853
+ raise ArgumentError, 'Criterion cannot be nil here'
854
+ end
855
+ unless Hash === criterion
856
+ raise Errors::InvalidQuery, "Expression must be a Hash: #{Errors::InvalidQuery.truncate_expr(criterion)}"
857
+ end
858
+
859
+ normalized = _mongoid_expand_keys(criterion)
860
+ clone.tap do |query|
861
+ normalized.each do |field, value|
862
+ field_s = field.to_s
863
+ if field_s.start_with?('$')
864
+ # Query expression-level operator, like $and or $where
865
+ query.add_operator_expression(field_s, value)
866
+ else
867
+ query.add_field_expression(field, value)
868
+ end
869
+ end
870
+ query.reset_strategies!
561
871
  end
562
872
  end
563
873
 
@@ -571,11 +881,9 @@ module Mongoid
571
881
  # end
572
882
  #
573
883
  # @param [ Hash ] criterion The criterion.
574
- #
575
- # @since 1.0.0
576
884
  def typed_override(criterion, operator)
577
885
  if criterion
578
- criterion.update_values do |value|
886
+ criterion.transform_values! do |value|
579
887
  yield(value)
580
888
  end
581
889
  end
@@ -592,27 +900,28 @@ module Mongoid
592
900
  # @param [ String ] criterion The javascript as a string.
593
901
  #
594
902
  # @return [ Selectable ] The cloned selectable
595
- #
596
- # @since 1.0.0
597
903
  def js_query(criterion)
598
904
  clone.tap do |query|
599
- query.selector.merge!("$where" => criterion)
905
+ if negating?
906
+ query.add_operator_expression('$and',
907
+ [{'$nor' => [{'$where' => criterion}]}])
908
+ else
909
+ query.add_operator_expression('$where', criterion)
910
+ end
911
+ query.reset_strategies!
600
912
  end
601
913
  end
602
914
 
603
915
  # Take the provided criterion and store it as a selection in the query
604
916
  # selector.
605
917
  #
606
- # @api private
607
- #
608
918
  # @example Store the selection.
609
919
  # selectable.selection({ field: "value" })
610
920
  #
611
921
  # @param [ Hash ] criterion The selection to store.
612
922
  #
613
923
  # @return [ Selectable ] The cloned selectable.
614
- #
615
- # @since 1.0.0
924
+ # @api private
616
925
  def selection(criterion = nil)
617
926
  clone.tap do |query|
618
927
  if criterion
@@ -624,23 +933,19 @@ module Mongoid
624
933
  end
625
934
  end
626
935
 
627
- # Convert the criterion values to $in friendly values. This means you,
628
- # array.
629
- #
630
- # @api private
936
+ # Combine operator expessions onto a Criteria using either
937
+ # an override or ands depending on the status of the
938
+ # Mongoid.overwrite_chained_operators feature flag.
631
939
  #
632
- # @example Convert all the values to arrays.
633
- # selectable.with_array_values({ key: 1...4 })
940
+ # @param [ Hash ] The criterion to add to the criteria.
941
+ # @param [ String ] operator The MongoDB operator.
634
942
  #
635
- # @param [ Hash ] criterion The criterion.
636
- #
637
- # @return [ Hash ] The $in friendly criterion (array values).
638
- #
639
- # @since 1.0.0
640
- def with_array_values(criterion)
641
- return nil unless criterion
642
- criterion.each_pair do |key, value|
643
- criterion[key] = value.__array__
943
+ # @return [ Criteria ] The resulting criteria.
944
+ def and_or_override(criterion, operator)
945
+ if Mongoid.overwrite_chained_operators
946
+ __override__(criterion, operator)
947
+ else
948
+ and_with_operator(criterion, operator)
644
949
  end
645
950
  end
646
951
 
@@ -652,8 +957,6 @@ module Mongoid
652
957
  # Selectable.forwardables
653
958
  #
654
959
  # @return [ Array<Symbol> ] The names of the forwardable methods.
655
- #
656
- # @since 1.0.0
657
960
  def forwardables
658
961
  public_instance_methods(false) -
659
962
  [ :negating, :negating=, :negating?, :selector, :selector= ]