mongoid 7.0.5 → 8.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1107) 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 +63 -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 +41 -40
  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 +105 -68
  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 +102 -125
  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 +62 -84
  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 +2 -3
  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 +42 -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 +151 -70
  84. data/lib/mongoid/clients/factory.rb +42 -17
  85. data/lib/mongoid/clients/options.rb +15 -14
  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 +42 -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 +4 -20
  121. data/lib/mongoid/criteria/options.rb +2 -3
  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 +40 -25
  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 +453 -177
  149. data/lib/mongoid/criteria/queryable/selector.rb +126 -29
  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 +151 -99
  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 -8
  243. data/lib/mongoid/extensions/set.rb +13 -11
  244. data/lib/mongoid/extensions/string.rb +30 -61
  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 -156
  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 +91 -51
  313. data/lib/mongoid/positional.rb +2 -5
  314. data/lib/mongoid/query_cache.rb +18 -238
  315. data/lib/mongoid/railtie.rb +3 -16
  316. data/lib/mongoid/railties/controller_runtime.rb +4 -2
  317. data/lib/mongoid/railties/database.rake +16 -2
  318. data/lib/mongoid/reloadable.rb +21 -22
  319. data/lib/mongoid/scopable.rb +34 -57
  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 +44 -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 +7 -14
  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 +19 -4
  358. data/spec/config/mongoid.yml +17 -0
  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 +20 -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 +35 -8
  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 +3 -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 +2 -0
  480. data/spec/mongoid/association/embedded/embeds_one_models.rb +22 -0
  481. data/spec/mongoid/association/embedded/embeds_one_query_spec.rb +28 -0
  482. data/spec/mongoid/association/embedded/embeds_one_spec.rb +31 -3
  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 +242 -12
  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 +28 -21
  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 +46 -2
  498. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_persistence_spec.rb +25 -5
  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 +68 -2
  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 +81 -4
  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_spec.rb +859 -502
  508. data/spec/mongoid/association/referenced/has_many_models.rb +61 -1
  509. data/spec/mongoid/association/referenced/has_many_query_spec.rb +37 -0
  510. data/spec/mongoid/association/referenced/has_many_spec.rb +48 -0
  511. data/spec/mongoid/association/referenced/has_one/binding_spec.rb +2 -0
  512. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +55 -9
  513. data/spec/mongoid/association/referenced/has_one/eager_spec.rb +34 -4
  514. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +135 -27
  515. data/spec/mongoid/association/referenced/has_one_models.rb +65 -0
  516. data/spec/mongoid/association/referenced/has_one_query_spec.rb +37 -0
  517. data/spec/mongoid/association/referenced/has_one_spec.rb +24 -1
  518. data/spec/mongoid/association/reflections_spec.rb +2 -0
  519. data/spec/mongoid/association/syncable_spec.rb +48 -32
  520. data/spec/mongoid/association_spec.rb +2 -0
  521. data/spec/mongoid/atomic/modifiers_spec.rb +49 -0
  522. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +2 -0
  523. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +2 -0
  524. data/spec/mongoid/atomic/paths/root_spec.rb +2 -0
  525. data/spec/mongoid/atomic/paths_spec.rb +93 -12
  526. data/spec/mongoid/atomic_spec.rb +53 -6
  527. data/spec/mongoid/attributes/dynamic_spec.rb +152 -0
  528. data/spec/mongoid/attributes/nested_spec.rb +149 -78
  529. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  530. data/spec/mongoid/attributes/projector_data/embedded.yml +105 -0
  531. data/spec/mongoid/attributes/projector_data/fields.yml +93 -0
  532. data/spec/mongoid/attributes/projector_spec.rb +40 -0
  533. data/spec/mongoid/attributes/readonly_spec.rb +24 -22
  534. data/spec/mongoid/attributes_spec.rb +895 -54
  535. data/spec/mongoid/cacheable_spec.rb +6 -4
  536. data/spec/mongoid/changeable_spec.rb +484 -67
  537. data/spec/mongoid/clients/factory_spec.rb +128 -28
  538. data/spec/mongoid/clients/options_spec.rb +49 -30
  539. data/spec/mongoid/clients/sessions_spec.rb +29 -66
  540. data/spec/mongoid/clients/transactions_spec.rb +74 -37
  541. data/spec/mongoid/clients_spec.rb +189 -23
  542. data/spec/mongoid/collection_configurable_spec.rb +158 -0
  543. data/spec/mongoid/composable_spec.rb +2 -0
  544. data/spec/mongoid/config/defaults_spec.rb +160 -0
  545. data/spec/mongoid/config/environment_spec.rb +126 -8
  546. data/spec/mongoid/config/options_spec.rb +22 -3
  547. data/spec/mongoid/config_spec.rb +504 -1
  548. data/spec/mongoid/contextual/aggregable/memory_spec.rb +433 -153
  549. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  550. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  551. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +122 -20
  552. data/spec/mongoid/contextual/aggregable/none_spec.rb +60 -0
  553. data/spec/mongoid/contextual/atomic_spec.rb +242 -81
  554. data/spec/mongoid/contextual/geo_near_spec.rb +30 -19
  555. data/spec/mongoid/contextual/map_reduce_spec.rb +22 -19
  556. data/spec/mongoid/contextual/memory_spec.rb +1828 -303
  557. data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +187 -0
  558. data/spec/mongoid/contextual/mongo_spec.rb +3504 -1270
  559. data/spec/mongoid/contextual/none_spec.rb +80 -67
  560. data/spec/mongoid/copyable_spec.rb +659 -36
  561. data/spec/mongoid/copyable_spec_models.rb +30 -0
  562. data/spec/mongoid/criteria/findable_spec.rb +161 -228
  563. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  564. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  565. data/spec/mongoid/criteria/inspectable_spec.rb +2 -0
  566. data/spec/mongoid/criteria/marshalable_spec.rb +20 -1
  567. data/spec/mongoid/criteria/modifiable_spec.rb +43 -40
  568. data/spec/mongoid/criteria/options_spec.rb +2 -0
  569. data/spec/mongoid/criteria/queryable/aggregable_spec.rb +3 -1
  570. data/spec/mongoid/criteria/queryable/expandable_spec.rb +61 -0
  571. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +9 -19
  572. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +136 -26
  573. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +3 -1
  574. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +13 -0
  575. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +46 -17
  576. data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +2 -0
  577. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +2 -15
  578. data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +2 -0
  579. data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +2 -0
  580. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -8
  581. data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +2 -0
  582. data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +239 -178
  583. data/spec/mongoid/criteria/queryable/extensions/regexp_raw_spec.rb +3 -1
  584. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +9 -7
  585. data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +2 -0
  586. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +7 -70
  587. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +2 -59
  588. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +53 -23
  589. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +41 -1
  590. data/spec/mongoid/criteria/queryable/key_spec.rb +2 -0
  591. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +145 -12
  592. data/spec/mongoid/criteria/queryable/optional_spec.rb +18 -485
  593. data/spec/mongoid/criteria/queryable/options_spec.rb +3 -1
  594. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +2 -0
  595. data/spec/mongoid/criteria/queryable/queryable_spec.rb +3 -1
  596. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +2538 -0
  597. data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +38 -0
  598. data/spec/mongoid/criteria/queryable/selectable_spec.rb +1100 -2880
  599. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +589 -0
  600. data/spec/mongoid/criteria/queryable/selector_spec.rb +17 -3
  601. data/spec/mongoid/criteria/queryable/smash_spec.rb +2 -0
  602. data/spec/mongoid/criteria/queryable/storable_spec.rb +226 -0
  603. data/spec/mongoid/criteria/scopable_spec.rb +129 -0
  604. data/spec/mongoid/criteria/translator_spec.rb +132 -0
  605. data/spec/mongoid/criteria_projection_spec.rb +406 -0
  606. data/spec/mongoid/criteria_spec.rb +1320 -1723
  607. data/spec/mongoid/document_fields_spec.rb +262 -0
  608. data/spec/mongoid/document_persistence_context_spec.rb +32 -0
  609. data/spec/mongoid/document_query_spec.rb +89 -0
  610. data/spec/mongoid/document_spec.rb +153 -87
  611. data/spec/mongoid/equality_spec.rb +144 -41
  612. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +5 -3
  613. data/spec/mongoid/errors/callback_spec.rb +2 -0
  614. data/spec/mongoid/errors/delete_restriction_spec.rb +4 -2
  615. data/spec/mongoid/errors/document_not_destroyed_spec.rb +2 -0
  616. data/spec/mongoid/errors/document_not_found_spec.rb +78 -0
  617. data/spec/mongoid/errors/invalid_collection_spec.rb +2 -0
  618. data/spec/mongoid/errors/{eager_load_spec.rb → invalid_config_file_spec.rb} +7 -5
  619. data/spec/mongoid/errors/invalid_config_option_spec.rb +2 -0
  620. data/spec/mongoid/errors/invalid_field_option_spec.rb +2 -0
  621. data/spec/mongoid/errors/invalid_field_spec.rb +3 -1
  622. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  623. data/spec/mongoid/errors/invalid_find_spec.rb +2 -0
  624. data/spec/mongoid/errors/invalid_includes_spec.rb +2 -0
  625. data/spec/mongoid/errors/invalid_index_spec.rb +2 -0
  626. data/spec/mongoid/errors/invalid_options_spec.rb +4 -2
  627. data/spec/mongoid/errors/invalid_path_spec.rb +2 -0
  628. data/spec/mongoid/errors/invalid_relation_spec.rb +4 -2
  629. data/spec/mongoid/errors/invalid_scope_spec.rb +3 -1
  630. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +2 -0
  631. data/spec/mongoid/errors/invalid_storage_options_spec.rb +2 -0
  632. data/spec/mongoid/errors/invalid_time_spec.rb +2 -0
  633. data/spec/mongoid/errors/inverse_not_found_spec.rb +3 -1
  634. data/spec/mongoid/errors/mixed_client_configuration_spec.rb +2 -0
  635. data/spec/mongoid/errors/mixed_relations_spec.rb +2 -0
  636. data/spec/mongoid/errors/mongoid_error_spec.rb +24 -8
  637. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +5 -3
  638. data/spec/mongoid/errors/no_client_config_spec.rb +4 -2
  639. data/spec/mongoid/errors/no_client_database_spec.rb +5 -3
  640. data/spec/mongoid/errors/no_client_hosts_spec.rb +5 -3
  641. data/spec/mongoid/errors/no_clients_config_spec.rb +2 -0
  642. data/spec/mongoid/errors/no_environment_spec.rb +5 -3
  643. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +2 -0
  644. data/spec/mongoid/errors/no_metadata_spec.rb +4 -2
  645. data/spec/mongoid/errors/no_parent_spec.rb +3 -1
  646. data/spec/mongoid/errors/readonly_attribute_spec.rb +2 -0
  647. data/spec/mongoid/errors/readonly_document_spec.rb +4 -2
  648. data/spec/mongoid/errors/scope_overwrite_spec.rb +2 -0
  649. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +3 -1
  650. data/spec/mongoid/errors/unknown_attribute_spec.rb +4 -2
  651. data/spec/mongoid/errors/unsaved_document_spec.rb +3 -1
  652. data/spec/mongoid/errors/unsupported_javascript_spec.rb +2 -0
  653. data/spec/mongoid/errors/validations_spec.rb +2 -0
  654. data/spec/mongoid/extensions/array_spec.rb +41 -45
  655. data/spec/mongoid/extensions/big_decimal_spec.rb +714 -212
  656. data/spec/mongoid/extensions/binary_spec.rb +46 -9
  657. data/spec/mongoid/extensions/boolean_spec.rb +70 -82
  658. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +339 -0
  659. data/spec/mongoid/extensions/date_spec.rb +58 -140
  660. data/spec/mongoid/extensions/date_time_spec.rb +32 -69
  661. data/spec/mongoid/extensions/decimal128_spec.rb +2 -0
  662. data/spec/mongoid/extensions/false_class_spec.rb +3 -1
  663. data/spec/mongoid/extensions/float_spec.rb +66 -73
  664. data/spec/mongoid/extensions/hash_spec.rb +135 -0
  665. data/spec/mongoid/extensions/integer_spec.rb +61 -63
  666. data/spec/mongoid/extensions/module_spec.rb +2 -0
  667. data/spec/mongoid/extensions/nil_class_spec.rb +2 -0
  668. data/spec/mongoid/extensions/object_id_spec.rb +2 -0
  669. data/spec/mongoid/extensions/object_spec.rb +13 -24
  670. data/spec/mongoid/extensions/range_spec.rb +257 -54
  671. data/spec/mongoid/extensions/regexp_spec.rb +60 -33
  672. data/spec/mongoid/extensions/set_spec.rb +108 -0
  673. data/spec/mongoid/extensions/string_spec.rb +111 -50
  674. data/spec/mongoid/extensions/stringified_symbol_spec.rb +84 -0
  675. data/spec/mongoid/extensions/symbol_spec.rb +20 -25
  676. data/spec/mongoid/extensions/time_spec.rb +668 -106
  677. data/spec/mongoid/extensions/time_with_zone_spec.rb +57 -83
  678. data/spec/mongoid/extensions/true_class_spec.rb +3 -1
  679. data/spec/mongoid/extensions_spec.rb +16 -2
  680. data/spec/mongoid/factory_spec.rb +347 -27
  681. data/spec/mongoid/fields/foreign_key_spec.rb +2 -0
  682. data/spec/mongoid/fields/localized_spec.rb +86 -41
  683. data/spec/mongoid/fields/standard_spec.rb +2 -0
  684. data/spec/mongoid/fields_spec.rb +869 -114
  685. data/spec/mongoid/findable_spec.rb +520 -64
  686. data/spec/mongoid/indexable/specification_spec.rb +4 -2
  687. data/spec/mongoid/indexable_spec.rb +87 -32
  688. data/spec/mongoid/inspectable_spec.rb +39 -2
  689. data/spec/mongoid/interceptable_spec.rb +761 -98
  690. data/spec/mongoid/interceptable_spec_models.rb +307 -0
  691. data/spec/mongoid/loggable_spec.rb +2 -0
  692. data/spec/mongoid/matcher/extract_attribute_data/numeric_keys.yml +104 -0
  693. data/spec/mongoid/matcher/extract_attribute_data/traversal.yml +239 -0
  694. data/spec/mongoid/matcher/extract_attribute_spec.rb +36 -0
  695. data/spec/mongoid/mongoizable_spec.rb +285 -0
  696. data/spec/mongoid/persistable/creatable_spec.rb +114 -29
  697. data/spec/mongoid/persistable/deletable_spec.rb +300 -18
  698. data/spec/mongoid/persistable/destroyable_spec.rb +228 -18
  699. data/spec/mongoid/persistable/incrementable_spec.rb +60 -7
  700. data/spec/mongoid/persistable/logical_spec.rb +56 -3
  701. data/spec/mongoid/persistable/poppable_spec.rb +55 -3
  702. data/spec/mongoid/persistable/pullable_spec.rb +108 -6
  703. data/spec/mongoid/persistable/pushable_spec.rb +163 -7
  704. data/spec/mongoid/persistable/renamable_spec.rb +54 -2
  705. data/spec/mongoid/persistable/savable_spec.rb +284 -25
  706. data/spec/mongoid/persistable/settable_spec.rb +91 -8
  707. data/spec/mongoid/persistable/unsettable_spec.rb +55 -3
  708. data/spec/mongoid/persistable/updatable_spec.rb +63 -49
  709. data/spec/mongoid/persistable/upsertable_spec.rb +93 -3
  710. data/spec/mongoid/persistable_spec.rb +85 -9
  711. data/spec/mongoid/persistence_context_spec.rb +59 -58
  712. data/spec/mongoid/positional_spec.rb +2 -0
  713. data/spec/mongoid/query_cache_middleware_spec.rb +50 -0
  714. data/spec/mongoid/query_cache_spec.rb +410 -95
  715. data/spec/mongoid/relations/proxy_spec.rb +9 -7
  716. data/spec/mongoid/reloadable_spec.rb +357 -26
  717. data/spec/mongoid/scopable_spec.rb +193 -38
  718. data/spec/mongoid/selectable_spec.rb +8 -6
  719. data/spec/mongoid/serializable_spec.rb +148 -38
  720. data/spec/mongoid/shardable_models.rb +75 -0
  721. data/spec/mongoid/shardable_spec.rb +239 -34
  722. data/spec/mongoid/stateful_spec.rb +153 -9
  723. data/spec/mongoid/tasks/database_rake_spec.rb +89 -13
  724. data/spec/mongoid/tasks/database_spec.rb +130 -1
  725. data/spec/mongoid/threaded_spec.rb +4 -2
  726. data/spec/mongoid/timestamps/created/short_spec.rb +3 -1
  727. data/spec/mongoid/timestamps/created_spec.rb +3 -1
  728. data/spec/mongoid/timestamps/timeless_spec.rb +4 -2
  729. data/spec/mongoid/timestamps/updated/short_spec.rb +5 -3
  730. data/spec/mongoid/timestamps/updated_spec.rb +5 -3
  731. data/spec/mongoid/timestamps_spec.rb +400 -10
  732. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  733. data/spec/mongoid/touchable_spec.rb +568 -33
  734. data/spec/mongoid/touchable_spec_models.rb +59 -0
  735. data/spec/mongoid/traversable_spec.rb +1145 -1
  736. data/spec/mongoid/validatable/associated_spec.rb +2 -0
  737. data/spec/mongoid/validatable/format_spec.rb +2 -0
  738. data/spec/mongoid/validatable/length_spec.rb +2 -0
  739. data/spec/mongoid/validatable/numericality_spec.rb +2 -0
  740. data/spec/mongoid/validatable/presence_spec.rb +28 -22
  741. data/spec/mongoid/validatable/uniqueness_spec.rb +159 -103
  742. data/spec/mongoid/validatable_spec.rb +5 -3
  743. data/spec/mongoid/warnings_spec.rb +35 -0
  744. data/spec/mongoid_spec.rb +37 -9
  745. data/spec/rails/controller_extension/controller_runtime_spec.rb +5 -3
  746. data/spec/rails/mongoid_spec.rb +8 -18
  747. data/spec/shared/LICENSE +20 -0
  748. data/spec/shared/bin/get-mongodb-download-url +17 -0
  749. data/spec/shared/bin/s3-copy +45 -0
  750. data/spec/shared/bin/s3-upload +69 -0
  751. data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
  752. data/spec/shared/lib/mrss/cluster_config.rb +231 -0
  753. data/spec/shared/lib/mrss/constraints.rb +378 -0
  754. data/spec/shared/lib/mrss/docker_runner.rb +298 -0
  755. data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
  756. data/spec/shared/lib/mrss/event_subscriber.rb +210 -0
  757. data/spec/shared/lib/mrss/lite_constraints.rb +238 -0
  758. data/spec/shared/lib/mrss/server_version_registry.rb +113 -0
  759. data/spec/shared/lib/mrss/session_registry.rb +69 -0
  760. data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
  761. data/spec/shared/lib/mrss/spec_organizer.rb +179 -0
  762. data/spec/shared/lib/mrss/utils.rb +37 -0
  763. data/spec/shared/share/Dockerfile.erb +321 -0
  764. data/spec/shared/share/haproxy-1.conf +16 -0
  765. data/spec/shared/share/haproxy-2.conf +17 -0
  766. data/spec/shared/shlib/config.sh +27 -0
  767. data/spec/shared/shlib/distro.sh +74 -0
  768. data/spec/shared/shlib/server.sh +416 -0
  769. data/spec/shared/shlib/set_env.sh +169 -0
  770. data/spec/spec_helper.rb +44 -66
  771. data/spec/support/authorization.rb +2 -0
  772. data/spec/support/client_registry.rb +9 -0
  773. data/spec/support/constraints.rb +45 -69
  774. data/spec/support/expectations.rb +21 -3
  775. data/spec/support/helpers.rb +11 -0
  776. data/spec/support/immutable_ids.rb +118 -0
  777. data/spec/support/macros.rb +109 -0
  778. data/spec/{app → support}/models/account.rb +3 -1
  779. data/spec/{app → support}/models/acolyte.rb +2 -0
  780. data/spec/{app → support}/models/actor.rb +3 -1
  781. data/spec/support/models/actress.rb +4 -0
  782. data/spec/{app → support}/models/address.rb +6 -0
  783. data/spec/{app → support}/models/address_component.rb +2 -0
  784. data/spec/{app → support}/models/address_number.rb +2 -0
  785. data/spec/{app → support}/models/agency.rb +2 -0
  786. data/spec/{app → support}/models/agent.rb +2 -0
  787. data/spec/{app → support}/models/album.rb +2 -0
  788. data/spec/{app → support}/models/alert.rb +2 -0
  789. data/spec/{app → support}/models/animal.rb +2 -0
  790. data/spec/{app → support}/models/answer.rb +2 -0
  791. data/spec/{app → support}/models/appointment.rb +2 -0
  792. data/spec/support/models/armrest.rb +9 -0
  793. data/spec/{app → support}/models/article.rb +2 -0
  794. data/spec/{app → support}/models/artist.rb +4 -1
  795. data/spec/{app → support}/models/artwork.rb +2 -0
  796. data/spec/support/models/audible_sound.rb +3 -0
  797. data/spec/{app → support}/models/audio.rb +2 -0
  798. data/spec/support/models/augmentation.rb +25 -0
  799. data/spec/{app → support}/models/author.rb +2 -0
  800. data/spec/{app → support}/models/baby.rb +2 -0
  801. data/spec/{app → support}/models/band.rb +10 -0
  802. data/spec/{app → support}/models/bar.rb +2 -0
  803. data/spec/{app → support}/models/basic.rb +2 -0
  804. data/spec/support/models/bed.rb +3 -0
  805. data/spec/{app → support}/models/big_palette.rb +2 -0
  806. data/spec/{app → support}/models/birthday.rb +2 -0
  807. data/spec/support/models/bolt.rb +7 -0
  808. data/spec/{app → support}/models/bomb.rb +2 -0
  809. data/spec/{app → support}/models/book.rb +3 -0
  810. data/spec/{app → support}/models/breed.rb +2 -0
  811. data/spec/{app → support}/models/browser.rb +3 -1
  812. data/spec/{app → support}/models/building.rb +4 -0
  813. data/spec/{app → support}/models/building_address.rb +2 -0
  814. data/spec/{app → support}/models/bus.rb +2 -0
  815. data/spec/{app → support}/models/business.rb +2 -0
  816. data/spec/{app → support}/models/callback_test.rb +2 -0
  817. data/spec/{app → support}/models/canvas.rb +3 -1
  818. data/spec/support/models/car.rb +3 -0
  819. data/spec/{app → support}/models/cat.rb +2 -0
  820. data/spec/support/models/catalog.rb +24 -0
  821. data/spec/{app → support}/models/category.rb +2 -0
  822. data/spec/{app → support}/models/child.rb +2 -0
  823. data/spec/{app → support}/models/child_doc.rb +5 -3
  824. data/spec/{app → support}/models/church.rb +2 -0
  825. data/spec/{app → support}/models/circle.rb +2 -0
  826. data/spec/{app → support}/models/circuit.rb +2 -0
  827. data/spec/support/models/circus.rb +12 -0
  828. data/spec/{app → support}/models/code.rb +4 -0
  829. data/spec/support/models/coding/pull_request.rb +11 -0
  830. data/spec/support/models/coding.rb +3 -0
  831. data/spec/{app → support}/models/comment.rb +2 -0
  832. data/spec/{app → support}/models/company.rb +2 -0
  833. data/spec/{app → support}/models/consumption_period.rb +2 -0
  834. data/spec/{app → support}/models/contextable_item.rb +2 -0
  835. data/spec/{app → support}/models/contractor.rb +2 -0
  836. data/spec/{app → support}/models/cookie.rb +2 -0
  837. data/spec/{app → support}/models/country_code.rb +4 -0
  838. data/spec/{app → support}/models/courier_job.rb +2 -0
  839. data/spec/support/models/cover.rb +10 -0
  840. data/spec/support/models/crate.rb +12 -0
  841. data/spec/support/models/customer.rb +10 -0
  842. data/spec/support/models/customer_address.rb +11 -0
  843. data/spec/support/models/deed.rb +7 -0
  844. data/spec/{app → support}/models/definition.rb +2 -0
  845. data/spec/support/models/delegating_patient.rb +15 -0
  846. data/spec/{app → support}/models/description.rb +2 -0
  847. data/spec/{app → support}/models/dictionary.rb +8 -0
  848. data/spec/{app → support}/models/division.rb +2 -0
  849. data/spec/{app → support}/models/doctor.rb +2 -0
  850. data/spec/{app → support}/models/dog.rb +2 -0
  851. data/spec/{app → support}/models/dokument.rb +2 -0
  852. data/spec/{app → support}/models/draft.rb +2 -0
  853. data/spec/{app → support}/models/dragon.rb +2 -0
  854. data/spec/{app → support}/models/driver.rb +3 -1
  855. data/spec/{app → support}/models/drug.rb +2 -0
  856. data/spec/{app → support}/models/dungeon.rb +2 -0
  857. data/spec/{app → support}/models/edit.rb +2 -0
  858. data/spec/{app → support}/models/email.rb +2 -0
  859. data/spec/{app → support}/models/employer.rb +2 -0
  860. data/spec/{app → support}/models/entry.rb +2 -0
  861. data/spec/support/models/eraser.rb +3 -0
  862. data/spec/{app → support}/models/even.rb +2 -0
  863. data/spec/{app → support}/models/event.rb +2 -0
  864. data/spec/{app → support}/models/exhibition.rb +2 -0
  865. data/spec/{app → support}/models/exhibitor.rb +2 -0
  866. data/spec/{app → support}/models/explosion.rb +2 -0
  867. data/spec/{app → support}/models/eye.rb +2 -0
  868. data/spec/{app → support}/models/eye_bowl.rb +2 -0
  869. data/spec/{app → support}/models/face.rb +2 -0
  870. data/spec/support/models/fanatic.rb +8 -0
  871. data/spec/{app → support}/models/favorite.rb +2 -0
  872. data/spec/{app → support}/models/filesystem.rb +2 -0
  873. data/spec/{app → support}/models/fire_hydrant.rb +2 -0
  874. data/spec/{app → support}/models/firefox.rb +2 -0
  875. data/spec/{app → support}/models/fish.rb +2 -0
  876. data/spec/{app → support}/models/folder.rb +2 -0
  877. data/spec/{app → support}/models/folder_item.rb +2 -0
  878. data/spec/{app → support}/models/fruits.rb +2 -0
  879. data/spec/{app → support}/models/game.rb +2 -0
  880. data/spec/{app → support}/models/ghost.rb +2 -0
  881. data/spec/support/models/guitar.rb +4 -0
  882. data/spec/support/models/hole.rb +12 -0
  883. data/spec/{app → support}/models/home.rb +2 -0
  884. data/spec/{app → support}/models/house.rb +2 -0
  885. data/spec/{app → support}/models/html_writer.rb +2 -0
  886. data/spec/{app → support}/models/id_key.rb +2 -0
  887. data/spec/support/models/idnodef.rb +7 -0
  888. data/spec/{app → support}/models/image.rb +2 -0
  889. data/spec/{app → support}/models/implant.rb +11 -0
  890. data/spec/support/models/instrument.rb +8 -0
  891. data/spec/{app → support}/models/item.rb +3 -1
  892. data/spec/{app → support}/models/jar.rb +2 -0
  893. data/spec/{app → support}/models/kaleidoscope.rb +2 -0
  894. data/spec/{app → support}/models/kangaroo.rb +3 -1
  895. data/spec/{app → support}/models/label.rb +6 -1
  896. data/spec/{app → support}/models/language.rb +2 -0
  897. data/spec/{app → support}/models/lat_lng.rb +2 -0
  898. data/spec/{app → support}/models/league.rb +2 -0
  899. data/spec/support/models/learner.rb +4 -0
  900. data/spec/{app → support}/models/line_item.rb +2 -0
  901. data/spec/{app → support}/models/location.rb +2 -0
  902. data/spec/{app → support}/models/login.rb +2 -0
  903. data/spec/{app → support}/models/manufacturer.rb +2 -0
  904. data/spec/{app → support}/models/meat.rb +2 -0
  905. data/spec/{app → support}/models/membership.rb +3 -0
  906. data/spec/{app → support}/models/message.rb +2 -0
  907. data/spec/{app → support}/models/minim.rb +0 -1
  908. data/spec/{app → support}/models/mixed_drink.rb +2 -0
  909. data/spec/support/models/mop.rb +24 -0
  910. data/spec/{app → support}/models/movie.rb +2 -0
  911. data/spec/support/models/my_hash.rb +4 -0
  912. data/spec/{app → support}/models/name.rb +2 -0
  913. data/spec/support/models/name_only.rb +8 -0
  914. data/spec/{app → support}/models/node.rb +2 -0
  915. data/spec/{app → support}/models/note.rb +2 -0
  916. data/spec/support/models/nut.rb +7 -0
  917. data/spec/{app → support}/models/odd.rb +2 -0
  918. data/spec/support/models/order.rb +12 -0
  919. data/spec/{app → support}/models/ordered_post.rb +3 -1
  920. data/spec/{app → support}/models/ordered_preference.rb +2 -0
  921. data/spec/{app → support}/models/oscar.rb +2 -0
  922. data/spec/support/models/other_owner_object.rb +4 -0
  923. data/spec/{app → support}/models/override.rb +2 -0
  924. data/spec/{app → support}/models/ownable.rb +2 -0
  925. data/spec/{app → support}/models/owner.rb +4 -0
  926. data/spec/{app → support}/models/pack.rb +2 -0
  927. data/spec/{app → support}/models/page.rb +2 -0
  928. data/spec/{app → support}/models/page_question.rb +2 -0
  929. data/spec/{app → support}/models/palette.rb +3 -1
  930. data/spec/{app → support}/models/parent.rb +2 -0
  931. data/spec/{app → support}/models/parent_doc.rb +2 -0
  932. data/spec/support/models/passport.rb +22 -0
  933. data/spec/{app → support}/models/patient.rb +2 -0
  934. data/spec/{app → support}/models/pdf_writer.rb +2 -0
  935. data/spec/support/models/pencil.rb +3 -0
  936. data/spec/{app → support}/models/person.rb +22 -1
  937. data/spec/{app → support}/models/pet.rb +2 -0
  938. data/spec/{app → support}/models/pet_owner.rb +2 -0
  939. data/spec/{app → support}/models/phone.rb +5 -1
  940. data/spec/support/models/piano.rb +4 -0
  941. data/spec/{app → support}/models/pizza.rb +2 -0
  942. data/spec/{app → support}/models/player.rb +4 -0
  943. data/spec/{app → support}/models/post.rb +2 -0
  944. data/spec/{app → support}/models/post_genre.rb +2 -0
  945. data/spec/support/models/powerup.rb +25 -0
  946. data/spec/{app → support}/models/preference.rb +2 -0
  947. data/spec/{app → support}/models/princess.rb +2 -0
  948. data/spec/{app → support}/models/product.rb +3 -0
  949. data/spec/support/models/profile.rb +17 -0
  950. data/spec/{app → support}/models/pronunciation.rb +2 -0
  951. data/spec/{app → support}/models/pub.rb +2 -0
  952. data/spec/support/models/publication/encyclopedia.rb +11 -0
  953. data/spec/support/models/publication/review.rb +13 -0
  954. data/spec/support/models/publication.rb +4 -0
  955. data/spec/{app → support}/models/purchase.rb +2 -0
  956. data/spec/support/models/purchased_item.rb +10 -0
  957. data/spec/{app → support}/models/question.rb +2 -0
  958. data/spec/{app → support}/models/quiz.rb +2 -0
  959. data/spec/{app → support}/models/rating.rb +2 -0
  960. data/spec/{app → support}/models/record.rb +2 -0
  961. data/spec/{app → support}/models/registry.rb +3 -0
  962. data/spec/{app → support}/models/role.rb +2 -0
  963. data/spec/{app → support}/models/root_category.rb +2 -0
  964. data/spec/{app → support}/models/sandwich.rb +2 -0
  965. data/spec/{app → support}/models/scheduler.rb +2 -0
  966. data/spec/support/models/school.rb +14 -0
  967. data/spec/support/models/scribe.rb +7 -0
  968. data/spec/support/models/sealer.rb +7 -0
  969. data/spec/support/models/seat.rb +24 -0
  970. data/spec/{app → support}/models/seo.rb +2 -0
  971. data/spec/support/models/series.rb +7 -0
  972. data/spec/{app → support}/models/server.rb +2 -0
  973. data/spec/{app → support}/models/service.rb +2 -0
  974. data/spec/{app → support}/models/shape.rb +4 -2
  975. data/spec/{app → support}/models/shelf.rb +2 -0
  976. data/spec/support/models/shield.rb +18 -0
  977. data/spec/{app → support}/models/shipment_address.rb +2 -0
  978. data/spec/{app → support}/models/shipping_container.rb +2 -0
  979. data/spec/{app → support}/models/shipping_pack.rb +2 -0
  980. data/spec/support/models/shirt.rb +11 -0
  981. data/spec/{app → support}/models/shop.rb +2 -0
  982. data/spec/{app → support}/models/short_agent.rb +2 -0
  983. data/spec/{app → support}/models/short_quiz.rb +2 -0
  984. data/spec/{app → support}/models/simple.rb +2 -0
  985. data/spec/{app → support}/models/slave.rb +2 -0
  986. data/spec/{app → support}/models/song.rb +2 -0
  987. data/spec/{app → support}/models/sound.rb +2 -0
  988. data/spec/support/models/spacer.rb +7 -0
  989. data/spec/{app → support}/models/square.rb +2 -0
  990. data/spec/{app → support}/models/staff.rb +2 -0
  991. data/spec/{app → support}/models/store_as_dup_test1.rb +2 -0
  992. data/spec/{app → support}/models/store_as_dup_test2.rb +2 -0
  993. data/spec/{app → support}/models/strategy.rb +2 -0
  994. data/spec/support/models/student.rb +14 -0
  995. data/spec/{app → support}/models/sub_item.rb +2 -0
  996. data/spec/{app → support}/models/subscription.rb +2 -0
  997. data/spec/{app → support}/models/survey.rb +2 -0
  998. data/spec/{app → support}/models/symptom.rb +2 -0
  999. data/spec/support/models/system_role.rb +7 -0
  1000. data/spec/{app → support}/models/tag.rb +2 -0
  1001. data/spec/{app → support}/models/target.rb +2 -0
  1002. data/spec/{app → support}/models/template.rb +2 -0
  1003. data/spec/{app → support}/models/thing.rb +2 -0
  1004. data/spec/support/models/threadlocker.rb +7 -0
  1005. data/spec/{app → support}/models/title.rb +2 -0
  1006. data/spec/{app → support}/models/tool.rb +4 -2
  1007. data/spec/{app → support}/models/topping.rb +2 -0
  1008. data/spec/support/models/toy.rb +9 -0
  1009. data/spec/{app → support}/models/track.rb +2 -0
  1010. data/spec/{app → support}/models/translation.rb +2 -0
  1011. data/spec/{app → support}/models/tree.rb +2 -0
  1012. data/spec/support/models/truck.rb +7 -0
  1013. data/spec/{app → support}/models/user.rb +2 -0
  1014. data/spec/{app → support}/models/user_account.rb +2 -0
  1015. data/spec/{app → support}/models/validation_callback.rb +2 -0
  1016. data/spec/support/models/vehicle.rb +18 -0
  1017. data/spec/{app → support}/models/version.rb +2 -0
  1018. data/spec/{app → support}/models/vertex.rb +3 -1
  1019. data/spec/{app → support}/models/vet_visit.rb +2 -0
  1020. data/spec/{app → support}/models/video.rb +2 -0
  1021. data/spec/support/models/video_game.rb +3 -0
  1022. data/spec/support/models/washer.rb +7 -0
  1023. data/spec/support/models/weapon.rb +25 -0
  1024. data/spec/{app → support}/models/wiki_page.rb +3 -0
  1025. data/spec/{app → support}/models/word.rb +2 -0
  1026. data/spec/{app → support}/models/word_origin.rb +2 -0
  1027. data/spec/{app → support}/models/writer.rb +4 -2
  1028. data/spec/support/schema_maps/schema_map_aws.json +17 -0
  1029. data/spec/support/schema_maps/schema_map_aws_key_alt_names.json +12 -0
  1030. data/spec/support/schema_maps/schema_map_azure.json +17 -0
  1031. data/spec/support/schema_maps/schema_map_azure_key_alt_names.json +12 -0
  1032. data/spec/support/schema_maps/schema_map_gcp.json +17 -0
  1033. data/spec/support/schema_maps/schema_map_gcp_key_alt_names.json +12 -0
  1034. data/spec/support/schema_maps/schema_map_kmip.json +17 -0
  1035. data/spec/support/schema_maps/schema_map_kmip_key_alt_names.json +12 -0
  1036. data/spec/support/schema_maps/schema_map_local.json +18 -0
  1037. data/spec/support/schema_maps/schema_map_local_key_alt_names.json +12 -0
  1038. data/spec/support/shared/time.rb +53 -0
  1039. data/spec/support/spec_config.rb +30 -5
  1040. data.tar.gz.sig +0 -0
  1041. metadata +1240 -742
  1042. metadata.gz.sig +0 -0
  1043. data/lib/mongoid/criteria/queryable/forwardable.rb +0 -65
  1044. data/lib/mongoid/errors/eager_load.rb +0 -22
  1045. data/lib/mongoid/errors/invalid_value.rb +0 -16
  1046. data/lib/mongoid/matchable/all.rb +0 -27
  1047. data/lib/mongoid/matchable/and.rb +0 -30
  1048. data/lib/mongoid/matchable/default.rb +0 -72
  1049. data/lib/mongoid/matchable/elem_match.rb +0 -34
  1050. data/lib/mongoid/matchable/eq.rb +0 -22
  1051. data/lib/mongoid/matchable/exists.rb +0 -23
  1052. data/lib/mongoid/matchable/gt.rb +0 -23
  1053. data/lib/mongoid/matchable/gte.rb +0 -23
  1054. data/lib/mongoid/matchable/in.rb +0 -24
  1055. data/lib/mongoid/matchable/lt.rb +0 -23
  1056. data/lib/mongoid/matchable/lte.rb +0 -23
  1057. data/lib/mongoid/matchable/ne.rb +0 -21
  1058. data/lib/mongoid/matchable/nin.rb +0 -22
  1059. data/lib/mongoid/matchable/nor.rb +0 -37
  1060. data/lib/mongoid/matchable/or.rb +0 -33
  1061. data/lib/mongoid/matchable/regexp.rb +0 -27
  1062. data/lib/mongoid/matchable/size.rb +0 -21
  1063. data/lib/support/ruby_version.rb +0 -26
  1064. data/spec/app/models/actress.rb +0 -2
  1065. data/spec/app/models/augmentation.rb +0 -11
  1066. data/spec/app/models/bed.rb +0 -1
  1067. data/spec/app/models/car.rb +0 -1
  1068. data/spec/app/models/circus.rb +0 -7
  1069. data/spec/app/models/eraser.rb +0 -1
  1070. data/spec/app/models/learner.rb +0 -2
  1071. data/spec/app/models/my_hash.rb +0 -2
  1072. data/spec/app/models/other_owner_object.rb +0 -2
  1073. data/spec/app/models/passport.rb +0 -5
  1074. data/spec/app/models/pencil.rb +0 -1
  1075. data/spec/app/models/powerup.rb +0 -11
  1076. data/spec/app/models/profile.rb +0 -5
  1077. data/spec/app/models/series.rb +0 -4
  1078. data/spec/app/models/truck.rb +0 -3
  1079. data/spec/app/models/vehicle.rb +0 -11
  1080. data/spec/app/models/video_game.rb +0 -1
  1081. data/spec/app/models/weapon.rb +0 -11
  1082. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -58
  1083. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -58
  1084. data/spec/mongoid/criteria/queryable/forwardable_spec.rb +0 -87
  1085. data/spec/mongoid/matchable/all_spec.rb +0 -31
  1086. data/spec/mongoid/matchable/and_spec.rb +0 -187
  1087. data/spec/mongoid/matchable/default_spec.rb +0 -130
  1088. data/spec/mongoid/matchable/elem_match_spec.rb +0 -106
  1089. data/spec/mongoid/matchable/eq_spec.rb +0 -48
  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/support/cluster_config.rb +0 -158
  1104. /data/spec/{app → support}/models/array_field.rb +0 -0
  1105. /data/spec/{app → support}/models/store_as_dup_test3.rb +0 -0
  1106. /data/spec/{app → support}/models/store_as_dup_test4.rb +0 -0
  1107. /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,18 +11,12 @@ 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
22
  # @attribute [rw] negating If the next expression is negated.
@@ -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,15 +173,17 @@ 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
189
  # Add a $geoIntersects or $geoWithin selection. Symbol operators must
@@ -148,31 +200,34 @@ module Mongoid
148
200
  # the upper right (north east) as the second argument.
149
201
  # Important: When latitude and longitude are passed, longitude is
150
202
  # expected as the first element of the coordinate pair.
151
- # Source: https://docs.mongodb.com/manual/reference/operator/query/box/
203
+ # Source: https://www.mongodb.com/docs/manual/reference/operator/query/box/
152
204
  #
153
205
  # @example Add a geo intersect criterion for a line.
154
- # query.geo_spacial(:location.intersects_line => [[ 1, 10 ], [ 2, 10 ]])
206
+ # query.geo_spatial(:location.intersects_line => [[ 1, 10 ], [ 2, 10 ]])
155
207
  #
156
208
  # @example Add a geo intersect criterion for a point.
157
- # query.geo_spacial(:location.intersects_point => [[ 1, 10 ]])
209
+ # query.geo_spatial(:location.intersects_point => [[ 1, 10 ]])
158
210
  #
159
211
  # @example Add a geo intersect criterion for a polygon.
160
- # 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 ]])
161
213
  #
162
214
  # @example Add a geo within criterion for a polygon.
163
- # 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 ]])
164
216
  #
165
217
  # @example Add a geo within criterion for a box.
166
- # query.geo_spacial(:location.within_box => [[ 1, 10 ], [ 2, 10 ])
218
+ # query.geo_spatial(:location.within_box => [[ 1, 10 ], [ 2, 10 ])
167
219
  #
168
220
  # @param [ Hash ] criterion The criterion.
169
221
  #
170
222
  # @return [ Selectable ] The cloned selectable.
171
- #
172
- # @since 2.0.0
173
- def geo_spacial(criterion = nil)
223
+ def geo_spatial(criterion)
224
+ if criterion.nil?
225
+ raise Errors::CriteriaArgumentRequired, :geo_spatial
226
+ end
227
+
174
228
  __merge__(criterion)
175
229
  end
230
+
176
231
  key :intersects_line, :override, "$geoIntersects", "$geometry" do |value|
177
232
  { "type" => LINE_STRING, "coordinates" => value }
178
233
  end
@@ -187,6 +242,26 @@ module Mongoid
187
242
  end
188
243
  key :within_box, :override, "$geoWithin", "$box"
189
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"
264
+
190
265
  # Add the $gt criterion to the selector.
191
266
  #
192
267
  # @example Add the $gt criterion.
@@ -198,10 +273,12 @@ module Mongoid
198
273
  # @param [ Hash ] criterion The field/value pairs to check.
199
274
  #
200
275
  # @return [ Selectable ] The cloned selectable.
201
- #
202
- # @since 1.0.0
203
- def gt(criterion = nil)
204
- __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")
205
282
  end
206
283
  key :gt, :override, "$gt"
207
284
 
@@ -216,10 +293,12 @@ module Mongoid
216
293
  # @param [ Hash ] criterion The field/value pairs to check.
217
294
  #
218
295
  # @return [ Selectable ] The cloned selectable.
219
- #
220
- # @since 1.0.0
221
- def gte(criterion = nil)
222
- __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")
223
302
  end
224
303
  key :gte, :override, "$gte"
225
304
 
@@ -234,13 +313,27 @@ module Mongoid
234
313
  # @example Execute an $in in a where query.
235
314
  # selectable.where(:field.in => [ 1, 2, 3 ])
236
315
  #
237
- # @param [ Hash ] criterion The field/value criterion pairs.
316
+ # @param [ Hash ] condition The field/value criterion pairs.
238
317
  #
239
318
  # @return [ Selectable ] The cloned selectable.
240
- #
241
- # @since 1.0.0
242
- def in(criterion = nil)
243
- 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
244
337
  end
245
338
  alias :any_in :in
246
339
  key :in, :intersect, "$in"
@@ -256,10 +349,12 @@ module Mongoid
256
349
  # @param [ Hash ] criterion The field/value pairs to check.
257
350
  #
258
351
  # @return [ Selectable ] The cloned selectable.
259
- #
260
- # @since 1.0.0
261
- def lt(criterion = nil)
262
- __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")
263
358
  end
264
359
  key :lt, :override, "$lt"
265
360
 
@@ -274,10 +369,12 @@ module Mongoid
274
369
  # @param [ Hash ] criterion The field/value pairs to check.
275
370
  #
276
371
  # @return [ Selectable ] The cloned selectable.
277
- #
278
- # @since 1.0.0
279
- def lte(criterion = nil)
280
- __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")
281
378
  end
282
379
  key :lte, :override, "$lte"
283
380
 
@@ -289,9 +386,12 @@ module Mongoid
289
386
  # @param [ Hash ] criterion The field/distance pairs.
290
387
  #
291
388
  # @return [ Selectable ] The cloned selectable.
292
- #
293
- # @since 1.0.0
294
- 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
295
395
  __add__(criterion, "$maxDistance")
296
396
  end
297
397
 
@@ -306,10 +406,12 @@ module Mongoid
306
406
  # @param [ Hash ] criterion The field/mod selections.
307
407
  #
308
408
  # @return [ Selectable ] The cloned selectable.
309
- #
310
- # @since 1.0.0
311
- def mod(criterion = nil)
312
- __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")
313
415
  end
314
416
  key :mod, :override, "$mod"
315
417
 
@@ -324,10 +426,12 @@ module Mongoid
324
426
  # @param [ Hash ] criterion The field/ne selections.
325
427
  #
326
428
  # @return [ Selectable ] The cloned selectable.
327
- #
328
- # @since 1.0.0
329
- def ne(criterion = nil)
330
- __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")
331
435
  end
332
436
  alias :excludes :ne
333
437
  key :ne, :override, "$ne"
@@ -343,10 +447,12 @@ module Mongoid
343
447
  # @param [ Hash ] criterion The field/location pair.
344
448
  #
345
449
  # @return [ Selectable ] The cloned selectable.
346
- #
347
- # @since 1.0.0
348
- def near(criterion = nil)
349
- __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")
350
456
  end
351
457
  key :near, :override, "$near"
352
458
 
@@ -361,10 +467,12 @@ module Mongoid
361
467
  # @param [ Hash ] criterion The field/location pair.
362
468
  #
363
469
  # @return [ Selectable ] The cloned selectable.
364
- #
365
- # @since 1.0.0
366
- def near_sphere(criterion = nil)
367
- __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")
368
476
  end
369
477
  key :near_sphere, :override, "$nearSphere"
370
478
 
@@ -379,13 +487,27 @@ module Mongoid
379
487
  # @example Execute an $nin in a where query.
380
488
  # selectable.where(:field.nin => [ 1, 2, 3 ])
381
489
  #
382
- # @param [ Hash ] criterion The field/value criterion pairs.
490
+ # @param [ Hash ] condition The field/value criterion pairs.
383
491
  #
384
492
  # @return [ Selectable ] The cloned selectable.
385
- #
386
- # @since 1.0.0
387
- def nin(criterion = nil)
388
- 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
389
511
  end
390
512
  alias :not_in :nin
391
513
  key :nin, :intersect, "$nin"
@@ -395,13 +517,12 @@ module Mongoid
395
517
  # @example Add the $nor selection.
396
518
  # selectable.nor(field: 1, field: 2)
397
519
  #
398
- # @param [ Array ] criterion An array of hash criterion.
399
- #
400
- # @return [ Selectable ] The cloned selectable.
520
+ # @param [ [ Hash | Criteria | Array<Hash | Criteria> ]... ] *criteria
521
+ # Multiple key/value pair matches or Criteria objects.
401
522
  #
402
- # @since 1.0.0
403
- def nor(*criterion)
404
- __multi__(criterion, "$nor")
523
+ # @return [ Selectable ] The new selectable.
524
+ def nor(*criteria)
525
+ _mongoid_add_top_level_operation('$nor', criteria)
405
526
  end
406
527
 
407
528
  # Is the current selectable negating the next selection?
@@ -409,16 +530,14 @@ module Mongoid
409
530
  # @example Is the selectable negating?
410
531
  # selectable.negating?
411
532
  #
412
- # @return [ true, false ] If the selectable is negating.
413
- #
414
- # @since 1.0.0
533
+ # @return [ true | false ] If the selectable is negating.
415
534
  def negating?
416
535
  !!negating
417
536
  end
418
537
 
419
- # Negate the next selection.
538
+ # Negate the arguments, or the next selection if no arguments are given.
420
539
  #
421
- # @example Negate the selection.
540
+ # @example Negate the next selection.
422
541
  # selectable.not.in(field: [ 1, 2 ])
423
542
  #
424
543
  # @example Add the $not criterion.
@@ -427,34 +546,159 @@ module Mongoid
427
546
  # @example Execute a $not in a where query.
428
547
  # selectable.where(:field.not => /Bob/)
429
548
  #
430
- # @param [ Hash ] criterion The field/value pairs to negate.
431
- #
432
- # @return [ Selectable ] The negated selectable.
549
+ # @param [ [ Hash | Criteria ]... ] *criteria The key/value pair
550
+ # matches or Criteria objects to negate.
433
551
  #
434
- # @since 1.0.0
435
- def not(*criterion)
436
- if criterion.empty?
437
- 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 }
438
556
  else
439
- __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
440
580
  end
441
581
  end
442
582
  key :not, :override, "$not"
443
583
 
444
- # 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.
618
+ #
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.
445
625
  #
446
- # @example Add the $or selection.
626
+ # @example Add the $or selection where both fields must have the specified values.
447
627
  # selectable.or(field: 1, field: 2)
448
628
  #
449
- # @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})
450
631
  #
451
- # @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.
655
+ #
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})
452
661
  #
453
- # @since 1.0.0
454
- def or(*criterion)
455
- __multi__(criterion, "$or")
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
456
701
  end
457
- alias :any_of :or
458
702
 
459
703
  # Add a $size selection for array fields.
460
704
  #
@@ -470,9 +714,11 @@ module Mongoid
470
714
  # @param [ Hash ] criterion The field/size pairs criterion.
471
715
  #
472
716
  # @return [ Selectable ] The cloned selectable.
473
- #
474
- # @since 1.0.0
475
- def with_size(criterion = nil)
717
+ def with_size(criterion)
718
+ if criterion.nil?
719
+ raise Errors::CriteriaArgumentRequired, :with_size
720
+ end
721
+
476
722
  typed_override(criterion, "$size") do |value|
477
723
  ::Integer.evolve(value)
478
724
  end
@@ -494,9 +740,11 @@ module Mongoid
494
740
  # @param [ Hash ] criterion The field/type pairs.
495
741
  #
496
742
  # @return [ Selectable ] The cloned selectable.
497
- #
498
- # @since 1.0.0
499
- def with_type(criterion = nil)
743
+ def with_type(criterion)
744
+ if criterion.nil?
745
+ raise Errors::CriteriaArgumentRequired, :with_type
746
+ end
747
+
500
748
  typed_override(criterion, "$type") do |value|
501
749
  ::Integer.evolve(value)
502
750
  end
@@ -513,35 +761,35 @@ module Mongoid
513
761
  # @example Construct a text search selector with options.
514
762
  # selectable.text_search("testing", :$language => "fr")
515
763
  #
516
- # @note Per https://docs.mongodb.com/manual/reference/operator/query/text/
764
+ # @note Per https://www.mongodb.com/docs/manual/reference/operator/query/text/
517
765
  # it is not currently possible to supply multiple text search
518
766
  # conditions in a query. Mongoid will build such a query but the
519
767
  # server will return an error when trying to execute it.
520
768
  #
521
- # @param [ String, Symbol ] terms A string of terms that MongoDB parses
769
+ # @param [ String | Symbol ] terms A string of terms that MongoDB parses
522
770
  # and uses to query the text index.
523
771
  # @param [ Hash ] opts Text search options. See MongoDB documentation
524
772
  # for options.
525
773
  #
526
774
  # @return [ Selectable ] The cloned selectable.
527
- #
528
- # @since 2.2.0
529
775
  def text_search(terms, opts = nil)
776
+ if terms.nil?
777
+ raise Errors::CriteriaArgumentRequired, :terms
778
+ end
779
+
530
780
  clone.tap do |query|
531
- if terms
532
- criterion = {'$text' => { '$search' => terms }}
533
- criterion['$text'].merge!(opts) if opts
534
- if query.selector['$text']
535
- # Per https://docs.mongodb.com/manual/reference/operator/query/text/
536
- # multiple $text expressions are not currently supported by
537
- # MongoDB server, but build the query correctly instead of
538
- # overwriting previous text search condition with the currently
539
- # given one.
540
- Mongoid.logger.warn('Multiple $text expressions per query are not currently supported by the server')
541
- query.selector = {'$and' => [query.selector]}.merge(criterion)
542
- else
543
- query.selector = query.selector.merge(criterion)
544
- end
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)
545
793
  end
546
794
  end
547
795
  end
@@ -556,23 +804,42 @@ module Mongoid
556
804
  # @example Add a javascript selection.
557
805
  # selectable.where("this.name == 'syd'")
558
806
  #
559
- # @param [ String, Hash ] criterion The javascript or standard selection.
807
+ # @param [ [ Hash | String ]... ] *criterion The standard selection
808
+ # or javascript string.
560
809
  #
561
810
  # @return [ Selectable ] The cloned selectable.
562
- #
563
- # @since 1.0.0
564
- def where(criterion = nil)
565
- # We need to save the criterion in an instance variable so Modifiable methods
566
- # know how to create a polymorphic object.
567
- @criterion = criterion
568
- 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!
569
830
  end
570
831
 
571
832
  private
572
833
 
573
- # Create the standard expression query.
834
+ # Adds the specified expression to the query.
574
835
  #
575
- # @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.
576
843
  #
577
844
  # @example Create the selection.
578
845
  # selectable.expr_query(age: 50)
@@ -580,11 +847,27 @@ module Mongoid
580
847
  # @param [ Hash ] criterion The field/value pairs.
581
848
  #
582
849
  # @return [ Selectable ] The cloned selectable.
583
- #
584
- # @since 1.0.0
850
+ # @api private
585
851
  def expr_query(criterion)
586
- selection(criterion) do |selector, field, value|
587
- 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!
588
871
  end
589
872
  end
590
873
 
@@ -598,11 +881,9 @@ module Mongoid
598
881
  # end
599
882
  #
600
883
  # @param [ Hash ] criterion The criterion.
601
- #
602
- # @since 1.0.0
603
884
  def typed_override(criterion, operator)
604
885
  if criterion
605
- criterion.update_values do |value|
886
+ criterion.transform_values! do |value|
606
887
  yield(value)
607
888
  end
608
889
  end
@@ -619,27 +900,28 @@ module Mongoid
619
900
  # @param [ String ] criterion The javascript as a string.
620
901
  #
621
902
  # @return [ Selectable ] The cloned selectable
622
- #
623
- # @since 1.0.0
624
903
  def js_query(criterion)
625
904
  clone.tap do |query|
626
- 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!
627
912
  end
628
913
  end
629
914
 
630
915
  # Take the provided criterion and store it as a selection in the query
631
916
  # selector.
632
917
  #
633
- # @api private
634
- #
635
918
  # @example Store the selection.
636
919
  # selectable.selection({ field: "value" })
637
920
  #
638
921
  # @param [ Hash ] criterion The selection to store.
639
922
  #
640
923
  # @return [ Selectable ] The cloned selectable.
641
- #
642
- # @since 1.0.0
924
+ # @api private
643
925
  def selection(criterion = nil)
644
926
  clone.tap do |query|
645
927
  if criterion
@@ -651,23 +933,19 @@ module Mongoid
651
933
  end
652
934
  end
653
935
 
654
- # Convert the criterion values to $in friendly values. This means you,
655
- # array.
656
- #
657
- # @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.
658
939
  #
659
- # @example Convert all the values to arrays.
660
- # selectable.with_array_values({ key: 1...4 })
940
+ # @param [ Hash ] The criterion to add to the criteria.
941
+ # @param [ String ] operator The MongoDB operator.
661
942
  #
662
- # @param [ Hash ] criterion The criterion.
663
- #
664
- # @return [ Hash ] The $in friendly criterion (array values).
665
- #
666
- # @since 1.0.0
667
- def with_array_values(criterion)
668
- return nil unless criterion
669
- criterion.each_pair do |key, value|
670
- 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)
671
949
  end
672
950
  end
673
951
 
@@ -679,8 +957,6 @@ module Mongoid
679
957
  # Selectable.forwardables
680
958
  #
681
959
  # @return [ Array<Symbol> ] The names of the forwardable methods.
682
- #
683
- # @since 1.0.0
684
960
  def forwardables
685
961
  public_instance_methods(false) -
686
962
  [ :negating, :negating=, :negating?, :selector, :selector= ]