mongoid 7.4.3 → 8.0.7

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 (383) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +3 -3
  4. data/Rakefile +25 -0
  5. data/lib/config/locales/en.yml +52 -28
  6. data/lib/mongoid/association/accessors.rb +38 -9
  7. data/lib/mongoid/association/bindable.rb +50 -2
  8. data/lib/mongoid/association/builders.rb +4 -2
  9. data/lib/mongoid/association/constrainable.rb +0 -1
  10. data/lib/mongoid/association/eager_loadable.rb +29 -7
  11. data/lib/mongoid/association/embedded/batchable.rb +33 -10
  12. data/lib/mongoid/association/embedded/cyclic.rb +1 -1
  13. data/lib/mongoid/association/embedded/embedded_in/binding.rb +24 -2
  14. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +2 -2
  15. data/lib/mongoid/association/embedded/embedded_in.rb +3 -2
  16. data/lib/mongoid/association/embedded/embeds_many/binding.rb +1 -0
  17. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +1 -1
  18. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +65 -41
  19. data/lib/mongoid/association/embedded/embeds_many.rb +2 -2
  20. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +18 -4
  21. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +23 -4
  22. data/lib/mongoid/association/embedded/embeds_one.rb +3 -3
  23. data/lib/mongoid/association/macros.rb +28 -1
  24. data/lib/mongoid/association/many.rb +11 -7
  25. data/lib/mongoid/association/nested/many.rb +5 -4
  26. data/lib/mongoid/association/nested/nested_buildable.rb +4 -4
  27. data/lib/mongoid/association/nested/one.rb +5 -5
  28. data/lib/mongoid/association/one.rb +2 -2
  29. data/lib/mongoid/association/options.rb +9 -9
  30. data/lib/mongoid/association/proxy.rb +14 -3
  31. data/lib/mongoid/association/referenced/auto_save.rb +4 -3
  32. data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
  33. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
  34. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +5 -6
  35. data/lib/mongoid/association/referenced/belongs_to.rb +2 -2
  36. data/lib/mongoid/association/referenced/counter_cache.rb +10 -10
  37. data/lib/mongoid/association/referenced/eager.rb +2 -2
  38. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +70 -13
  39. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +6 -3
  40. data/lib/mongoid/association/referenced/has_many/enumerable.rb +20 -24
  41. data/lib/mongoid/association/referenced/has_many/proxy.rb +26 -16
  42. data/lib/mongoid/association/referenced/has_many.rb +3 -3
  43. data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -1
  44. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +5 -5
  45. data/lib/mongoid/association/referenced/has_one/proxy.rb +9 -12
  46. data/lib/mongoid/association/referenced/has_one.rb +3 -3
  47. data/lib/mongoid/association/referenced/syncable.rb +4 -4
  48. data/lib/mongoid/association/reflections.rb +2 -2
  49. data/lib/mongoid/association/relatable.rb +44 -10
  50. data/lib/mongoid/association.rb +5 -5
  51. data/lib/mongoid/atomic/modifiers.rb +2 -2
  52. data/lib/mongoid/atomic.rb +7 -0
  53. data/lib/mongoid/attributes/dynamic.rb +3 -3
  54. data/lib/mongoid/attributes/nested.rb +5 -5
  55. data/lib/mongoid/attributes/processing.rb +37 -6
  56. data/lib/mongoid/attributes/projector.rb +1 -1
  57. data/lib/mongoid/attributes/readonly.rb +2 -2
  58. data/lib/mongoid/attributes.rb +43 -40
  59. data/lib/mongoid/cacheable.rb +2 -2
  60. data/lib/mongoid/changeable.rb +43 -10
  61. data/lib/mongoid/clients/options.rb +5 -1
  62. data/lib/mongoid/clients/sessions.rb +2 -14
  63. data/lib/mongoid/clients/validators/storage.rb +3 -3
  64. data/lib/mongoid/config/options.rb +3 -0
  65. data/lib/mongoid/config/validators/client.rb +6 -6
  66. data/lib/mongoid/config.rb +62 -17
  67. data/lib/mongoid/contextual/aggregable/memory.rb +24 -16
  68. data/lib/mongoid/contextual/aggregable/mongo.rb +5 -5
  69. data/lib/mongoid/contextual/aggregable/none.rb +1 -1
  70. data/lib/mongoid/contextual/atomic.rb +1 -1
  71. data/lib/mongoid/contextual/geo_near.rb +7 -7
  72. data/lib/mongoid/contextual/map_reduce.rb +2 -2
  73. data/lib/mongoid/contextual/memory.rb +180 -21
  74. data/lib/mongoid/contextual/mongo.rb +260 -217
  75. data/lib/mongoid/contextual/none.rb +67 -5
  76. data/lib/mongoid/contextual/queryable.rb +1 -1
  77. data/lib/mongoid/contextual.rb +2 -2
  78. data/lib/mongoid/copyable.rb +32 -8
  79. data/lib/mongoid/criteria/findable.rb +7 -4
  80. data/lib/mongoid/criteria/includable.rb +24 -20
  81. data/lib/mongoid/criteria/marshalable.rb +10 -2
  82. data/lib/mongoid/criteria/permission.rb +1 -1
  83. data/lib/mongoid/criteria/queryable/aggregable.rb +2 -2
  84. data/lib/mongoid/criteria/queryable/extensions/array.rb +3 -14
  85. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -4
  86. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +2 -2
  87. data/lib/mongoid/criteria/queryable/extensions/date.rb +6 -1
  88. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +6 -1
  89. data/lib/mongoid/criteria/queryable/extensions/hash.rb +1 -15
  90. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -9
  91. data/lib/mongoid/criteria/queryable/extensions/object.rb +2 -1
  92. data/lib/mongoid/criteria/queryable/extensions/range.rb +13 -5
  93. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
  94. data/lib/mongoid/criteria/queryable/extensions/set.rb +1 -1
  95. data/lib/mongoid/criteria/queryable/extensions/string.rb +4 -14
  96. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +4 -12
  97. data/lib/mongoid/criteria/queryable/extensions/time.rb +6 -1
  98. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +6 -1
  99. data/lib/mongoid/criteria/queryable/key.rb +3 -3
  100. data/lib/mongoid/criteria/queryable/mergeable.rb +21 -0
  101. data/lib/mongoid/criteria/queryable/optional.rb +5 -11
  102. data/lib/mongoid/criteria/queryable/options.rb +2 -2
  103. data/lib/mongoid/criteria/queryable/pipeline.rb +1 -1
  104. data/lib/mongoid/criteria/queryable/selectable.rb +31 -37
  105. data/lib/mongoid/criteria/queryable/selector.rb +93 -8
  106. data/lib/mongoid/criteria/queryable/smash.rb +40 -7
  107. data/lib/mongoid/criteria/queryable/storable.rb +1 -1
  108. data/lib/mongoid/criteria/queryable.rb +12 -7
  109. data/lib/mongoid/criteria/scopable.rb +2 -2
  110. data/lib/mongoid/criteria/translator.rb +45 -0
  111. data/lib/mongoid/criteria.rb +16 -35
  112. data/lib/mongoid/deprecable.rb +37 -0
  113. data/lib/mongoid/deprecation.rb +25 -0
  114. data/lib/mongoid/document.rb +135 -34
  115. data/lib/mongoid/equality.rb +8 -8
  116. data/lib/mongoid/errors/document_not_found.rb +33 -12
  117. data/lib/mongoid/errors/invalid_config_option.rb +1 -1
  118. data/lib/mongoid/errors/invalid_dependent_strategy.rb +1 -1
  119. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
  120. data/lib/mongoid/errors/invalid_field.rb +6 -2
  121. data/lib/mongoid/errors/invalid_field_type.rb +26 -0
  122. data/lib/mongoid/errors/invalid_relation.rb +1 -1
  123. data/lib/mongoid/errors/invalid_relation_option.rb +1 -1
  124. data/lib/mongoid/errors/invalid_session_use.rb +1 -1
  125. data/lib/mongoid/errors/invalid_storage_options.rb +1 -1
  126. data/lib/mongoid/errors/mongoid_error.rb +3 -3
  127. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +1 -1
  128. data/lib/mongoid/errors/no_client_database.rb +1 -1
  129. data/lib/mongoid/errors/no_client_hosts.rb +1 -1
  130. data/lib/mongoid/errors/readonly_attribute.rb +1 -1
  131. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
  132. data/lib/mongoid/errors/unknown_attribute.rb +1 -1
  133. data/lib/mongoid/errors.rb +2 -2
  134. data/lib/mongoid/extensions/array.rb +9 -7
  135. data/lib/mongoid/extensions/big_decimal.rb +33 -10
  136. data/lib/mongoid/extensions/binary.rb +42 -0
  137. data/lib/mongoid/extensions/boolean.rb +8 -2
  138. data/lib/mongoid/extensions/date.rb +26 -20
  139. data/lib/mongoid/extensions/date_time.rb +1 -1
  140. data/lib/mongoid/extensions/false_class.rb +1 -1
  141. data/lib/mongoid/extensions/float.rb +7 -4
  142. data/lib/mongoid/extensions/hash.rb +37 -8
  143. data/lib/mongoid/extensions/integer.rb +7 -4
  144. data/lib/mongoid/extensions/module.rb +1 -1
  145. data/lib/mongoid/extensions/object.rb +8 -6
  146. data/lib/mongoid/extensions/range.rb +41 -10
  147. data/lib/mongoid/extensions/regexp.rb +11 -4
  148. data/lib/mongoid/extensions/set.rb +11 -4
  149. data/lib/mongoid/extensions/string.rb +11 -22
  150. data/lib/mongoid/extensions/symbol.rb +4 -15
  151. data/lib/mongoid/extensions/time.rb +27 -16
  152. data/lib/mongoid/extensions/time_with_zone.rb +1 -2
  153. data/lib/mongoid/extensions/true_class.rb +1 -1
  154. data/lib/mongoid/extensions.rb +1 -0
  155. data/lib/mongoid/factory.rb +55 -7
  156. data/lib/mongoid/fields/foreign_key.rb +11 -4
  157. data/lib/mongoid/fields/localized.rb +9 -4
  158. data/lib/mongoid/fields/standard.rb +7 -7
  159. data/lib/mongoid/fields/validators/macro.rb +3 -9
  160. data/lib/mongoid/fields.rb +233 -40
  161. data/lib/mongoid/findable.rb +34 -13
  162. data/lib/mongoid/indexable/specification.rb +2 -2
  163. data/lib/mongoid/indexable/validators/options.rb +6 -2
  164. data/lib/mongoid/interceptable.rb +185 -16
  165. data/lib/mongoid/matchable.rb +1 -1
  166. data/lib/mongoid/matcher.rb +33 -13
  167. data/lib/mongoid/persistable/creatable.rb +18 -9
  168. data/lib/mongoid/persistable/deletable.rb +1 -1
  169. data/lib/mongoid/persistable/destroyable.rb +1 -1
  170. data/lib/mongoid/persistable/savable.rb +2 -2
  171. data/lib/mongoid/persistable/unsettable.rb +1 -1
  172. data/lib/mongoid/persistable/updatable.rb +19 -12
  173. data/lib/mongoid/persistable/upsertable.rb +1 -1
  174. data/lib/mongoid/persistable.rb +3 -3
  175. data/lib/mongoid/persistence_context.rb +63 -10
  176. data/lib/mongoid/query_cache.rb +8 -260
  177. data/lib/mongoid/railties/controller_runtime.rb +1 -1
  178. data/lib/mongoid/reloadable.rb +10 -8
  179. data/lib/mongoid/scopable.rb +26 -22
  180. data/lib/mongoid/selectable.rb +1 -2
  181. data/lib/mongoid/serializable.rb +10 -6
  182. data/lib/mongoid/shardable.rb +35 -11
  183. data/lib/mongoid/stateful.rb +35 -9
  184. data/lib/mongoid/tasks/database.rb +0 -2
  185. data/lib/mongoid/threaded/lifecycle.rb +5 -5
  186. data/lib/mongoid/threaded.rb +42 -12
  187. data/lib/mongoid/timestamps/created.rb +1 -1
  188. data/lib/mongoid/timestamps/updated.rb +2 -2
  189. data/lib/mongoid/touchable.rb +2 -3
  190. data/lib/mongoid/traversable.rb +5 -4
  191. data/lib/mongoid/validatable/localizable.rb +1 -1
  192. data/lib/mongoid/validatable/macros.rb +0 -2
  193. data/lib/mongoid/validatable/presence.rb +2 -2
  194. data/lib/mongoid/validatable/uniqueness.rb +9 -8
  195. data/lib/mongoid/validatable.rb +6 -6
  196. data/lib/mongoid/version.rb +1 -1
  197. data/lib/mongoid/warnings.rb +28 -0
  198. data/lib/mongoid.rb +2 -0
  199. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +4 -3
  200. data/spec/config/mongoid.yml +16 -0
  201. data/spec/integration/app_spec.rb +8 -12
  202. data/spec/integration/associations/belongs_to_spec.rb +18 -0
  203. data/spec/integration/associations/embedded_spec.rb +15 -0
  204. data/spec/integration/associations/embeds_many_spec.rb +15 -2
  205. data/spec/integration/associations/embeds_one_spec.rb +18 -0
  206. data/spec/integration/associations/foreign_key_spec.rb +9 -0
  207. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
  208. data/spec/integration/associations/has_one_spec.rb +97 -1
  209. data/spec/integration/associations/scope_option_spec.rb +1 -1
  210. data/spec/integration/callbacks_models.rb +95 -1
  211. data/spec/integration/callbacks_spec.rb +246 -4
  212. data/spec/integration/criteria/range_spec.rb +95 -1
  213. data/spec/integration/discriminator_key_spec.rb +115 -76
  214. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  215. data/spec/integration/i18n_fallbacks_spec.rb +1 -17
  216. data/spec/integration/matcher_examples_spec.rb +20 -13
  217. data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
  218. data/spec/integration/matcher_operator_spec.rb +3 -5
  219. data/spec/integration/persistence/range_field_spec.rb +350 -0
  220. data/spec/mongoid/association/counter_cache_spec.rb +1 -1
  221. data/spec/mongoid/association/depending_spec.rb +9 -9
  222. data/spec/mongoid/association/eager_spec.rb +2 -1
  223. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
  224. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
  225. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +69 -9
  226. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
  227. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +235 -40
  228. data/spec/mongoid/association/embedded/embeds_many_models.rb +36 -0
  229. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +12 -0
  230. data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
  231. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
  232. data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
  233. data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
  234. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
  235. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
  236. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +15 -0
  237. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  238. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -2
  239. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +202 -201
  240. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
  241. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
  242. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
  243. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +8 -8
  244. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +160 -119
  245. data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
  246. data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
  247. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
  248. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
  249. data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
  250. data/spec/mongoid/association/syncable_spec.rb +14 -0
  251. data/spec/mongoid/atomic/paths_spec.rb +0 -14
  252. data/spec/mongoid/attributes/nested_spec.rb +80 -11
  253. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  254. data/spec/mongoid/attributes/projector_spec.rb +1 -5
  255. data/spec/mongoid/attributes_spec.rb +551 -27
  256. data/spec/mongoid/cacheable_spec.rb +3 -3
  257. data/spec/mongoid/changeable_spec.rb +130 -13
  258. data/spec/mongoid/clients/factory_spec.rb +23 -30
  259. data/spec/mongoid/clients/options_spec.rb +1 -0
  260. data/spec/mongoid/clients/sessions_spec.rb +0 -38
  261. data/spec/mongoid/clients_spec.rb +57 -2
  262. data/spec/mongoid/config_spec.rb +78 -18
  263. data/spec/mongoid/contextual/aggregable/memory_spec.rb +396 -158
  264. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  265. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  266. data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
  267. data/spec/mongoid/contextual/memory_spec.rb +1336 -69
  268. data/spec/mongoid/contextual/mongo_spec.rb +1253 -247
  269. data/spec/mongoid/contextual/none_spec.rb +38 -0
  270. data/spec/mongoid/copyable_spec.rb +451 -1
  271. data/spec/mongoid/criteria/findable_spec.rb +86 -210
  272. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  273. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  274. data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
  275. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
  276. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
  277. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
  278. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
  279. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
  280. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
  281. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +0 -59
  282. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +0 -59
  283. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
  284. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
  285. data/spec/mongoid/criteria/queryable/optional_spec.rb +15 -484
  286. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +50 -0
  287. data/spec/mongoid/criteria/queryable/selectable_spec.rb +289 -124
  288. data/spec/mongoid/criteria/queryable/selector_spec.rb +89 -4
  289. data/spec/mongoid/criteria/queryable/storable_spec.rb +72 -0
  290. data/spec/mongoid/criteria/translator_spec.rb +132 -0
  291. data/spec/mongoid/criteria_projection_spec.rb +0 -1
  292. data/spec/mongoid/criteria_spec.rb +475 -1199
  293. data/spec/mongoid/document_fields_spec.rb +173 -24
  294. data/spec/mongoid/document_spec.rb +32 -41
  295. data/spec/mongoid/errors/document_not_found_spec.rb +76 -0
  296. data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
  297. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  298. data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
  299. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  300. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
  301. data/spec/mongoid/extensions/array_spec.rb +16 -2
  302. data/spec/mongoid/extensions/big_decimal_spec.rb +712 -212
  303. data/spec/mongoid/extensions/binary_spec.rb +44 -9
  304. data/spec/mongoid/extensions/boolean_spec.rb +68 -82
  305. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
  306. data/spec/mongoid/extensions/date_spec.rb +71 -1
  307. data/spec/mongoid/extensions/date_time_spec.rb +15 -9
  308. data/spec/mongoid/extensions/float_spec.rb +53 -74
  309. data/spec/mongoid/extensions/hash_spec.rb +33 -3
  310. data/spec/mongoid/extensions/integer_spec.rb +50 -64
  311. data/spec/mongoid/extensions/range_spec.rb +255 -54
  312. data/spec/mongoid/extensions/regexp_spec.rb +58 -33
  313. data/spec/mongoid/extensions/set_spec.rb +106 -0
  314. data/spec/mongoid/extensions/string_spec.rb +53 -25
  315. data/spec/mongoid/extensions/symbol_spec.rb +18 -25
  316. data/spec/mongoid/extensions/time_spec.rb +634 -66
  317. data/spec/mongoid/extensions/time_with_zone_spec.rb +17 -31
  318. data/spec/mongoid/factory_spec.rb +61 -1
  319. data/spec/mongoid/fields/localized_spec.rb +37 -12
  320. data/spec/mongoid/fields_spec.rb +364 -50
  321. data/spec/mongoid/findable_spec.rb +80 -15
  322. data/spec/mongoid/indexable/specification_spec.rb +2 -2
  323. data/spec/mongoid/indexable_spec.rb +39 -20
  324. data/spec/mongoid/interceptable_spec.rb +807 -27
  325. data/spec/mongoid/interceptable_spec_models.rb +235 -4
  326. data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
  327. data/spec/mongoid/mongoizable_spec.rb +285 -0
  328. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  329. data/spec/mongoid/persistable/deletable_spec.rb +2 -2
  330. data/spec/mongoid/persistable/destroyable_spec.rb +2 -2
  331. data/spec/mongoid/persistable/upsertable_spec.rb +14 -0
  332. data/spec/mongoid/persistence_context_spec.rb +50 -1
  333. data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
  334. data/spec/mongoid/query_cache_spec.rb +0 -154
  335. data/spec/mongoid/reloadable_spec.rb +59 -2
  336. data/spec/mongoid/scopable_spec.rb +54 -16
  337. data/spec/mongoid/shardable_models.rb +14 -0
  338. data/spec/mongoid/shardable_spec.rb +157 -51
  339. data/spec/mongoid/stateful_spec.rb +28 -0
  340. data/spec/mongoid/timestamps_spec.rb +390 -0
  341. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  342. data/spec/mongoid/touchable_spec.rb +116 -0
  343. data/spec/mongoid/touchable_spec_models.rb +12 -8
  344. data/spec/mongoid/traversable_spec.rb +4 -11
  345. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  346. data/spec/mongoid/validatable/uniqueness_spec.rb +59 -31
  347. data/spec/mongoid/warnings_spec.rb +35 -0
  348. data/spec/mongoid_spec.rb +1 -1
  349. data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
  350. data/spec/rails/mongoid_spec.rb +4 -16
  351. data/spec/shared/lib/mrss/docker_runner.rb +7 -0
  352. data/spec/shared/lib/mrss/lite_constraints.rb +10 -2
  353. data/spec/shared/lib/mrss/server_version_registry.rb +16 -23
  354. data/spec/shared/lib/mrss/utils.rb +28 -6
  355. data/spec/shared/share/Dockerfile.erb +36 -40
  356. data/spec/shared/shlib/server.sh +32 -8
  357. data/spec/shared/shlib/set_env.sh +4 -4
  358. data/spec/support/constraints.rb +24 -0
  359. data/spec/support/macros.rb +46 -0
  360. data/spec/support/models/augmentation.rb +12 -0
  361. data/spec/support/models/band.rb +3 -0
  362. data/spec/support/models/catalog.rb +24 -0
  363. data/spec/support/models/circus.rb +3 -0
  364. data/spec/support/models/code.rb +2 -0
  365. data/spec/support/models/fanatic.rb +8 -0
  366. data/spec/support/models/implant.rb +9 -0
  367. data/spec/support/models/label.rb +2 -0
  368. data/spec/support/models/passport.rb +9 -0
  369. data/spec/support/models/person.rb +2 -0
  370. data/spec/support/models/player.rb +2 -0
  371. data/spec/support/models/powerup.rb +12 -0
  372. data/spec/support/models/purse.rb +9 -0
  373. data/spec/support/models/registry.rb +1 -0
  374. data/spec/support/models/school.rb +14 -0
  375. data/spec/support/models/shield.rb +18 -0
  376. data/spec/support/models/student.rb +14 -0
  377. data/spec/support/models/weapon.rb +12 -0
  378. data.tar.gz.sig +4 -1
  379. metadata +682 -635
  380. metadata.gz.sig +0 -0
  381. data/lib/mongoid/errors/eager_load.rb +0 -23
  382. data/lib/mongoid/errors/invalid_value.rb +0 -17
  383. data/spec/mongoid/errors/eager_load_spec.rb +0 -31
@@ -383,10 +383,11 @@ describe Mongoid::Criteria do
383
383
  Person.create!
384
384
  end
385
385
 
386
- context "when no eager loading is involved" do
386
+ context "when the query cache is enabled" do
387
+ query_cache_enabled
387
388
 
388
389
  let(:criteria) do
389
- Person.all.cache
390
+ Person.all
390
391
  end
391
392
 
392
393
  before do
@@ -394,17 +395,19 @@ describe Mongoid::Criteria do
394
395
  end
395
396
 
396
397
  it "does not hit the database after first iteration" do
397
- expect(criteria.context.view).to receive(:each).never
398
- criteria.each do |doc|
399
- expect(doc).to eq(person)
398
+ expect_no_queries do
399
+ criteria.each do |doc|
400
+ expect(doc).to eq(person)
401
+ end
400
402
  end
401
403
  end
402
404
  end
403
405
 
404
406
  context "when the criteria is eager loading" do
407
+ query_cache_enabled
405
408
 
406
409
  let(:criteria) do
407
- Person.includes(:posts).cache
410
+ Person.includes(:posts)
408
411
  end
409
412
 
410
413
  before do
@@ -412,9 +415,10 @@ describe Mongoid::Criteria do
412
415
  end
413
416
 
414
417
  it "does not hit the database after first iteration" do
415
- expect(criteria.context.view).to receive(:each).never
416
- criteria.each do |doc|
417
- expect(doc).to eq(person)
418
+ expect_no_queries do
419
+ criteria.each do |doc|
420
+ expect(doc).to eq(person)
421
+ end
418
422
  end
419
423
  end
420
424
  end
@@ -491,17 +495,6 @@ describe Mongoid::Criteria do
491
495
  end
492
496
  end
493
497
 
494
- describe "#cache" do
495
-
496
- let(:criteria) do
497
- Band.where(name: "Depeche Mode")
498
- end
499
-
500
- it "sets the cache option to true" do
501
- expect(criteria.cache).to be_cached
502
- end
503
- end
504
-
505
498
  describe "#context" do
506
499
 
507
500
  context "when the model is embedded" do
@@ -837,8 +830,8 @@ describe Mongoid::Criteria do
837
830
  end
838
831
  end
839
832
 
840
- context "when given a Proc" do
841
- it "behaves as Enumerable" do
833
+ context "when given a Proc without a block" do
834
+ it "raises an error" do
842
835
  lambda do
843
836
  criteria.find(-> {"default"})
844
837
  # Proc is not serializable to a BSON type
@@ -1000,7 +993,7 @@ describe Mongoid::Criteria do
1000
993
  it "deletes the document from the database" do
1001
994
  expect {
1002
995
  depeche.reload
1003
- }.to raise_error(Mongoid::Errors::DocumentNotFound)
996
+ }.to raise_error(Mongoid::Errors::DocumentNotFound, /Document\(s\) not found for class Band with id\(s\)/)
1004
997
  end
1005
998
  end
1006
999
  end
@@ -1159,1186 +1152,78 @@ describe Mongoid::Criteria do
1159
1152
 
1160
1153
  let!(:match_one) do
1161
1154
  Person.create!(preference_ids: [ id ])
1162
- end
1163
-
1164
- context "when providing valid ids" do
1165
-
1166
- let(:criteria) do
1167
- Person.send(method, preference_ids: [ id ])
1168
- end
1169
-
1170
- it "returns the matching documents" do
1171
- expect(criteria).to eq([ match_one ])
1172
- end
1173
- end
1174
-
1175
- context "when providing empty strings" do
1176
-
1177
- let(:criteria) do
1178
- Person.send(method, preference_ids: [ id, "" ])
1179
- end
1180
-
1181
- it "returns the matching documents" do
1182
- expect(criteria).to eq([ match_one ])
1183
- end
1184
- end
1185
-
1186
- context "when providing nils" do
1187
-
1188
- context "when the relation is a many to many" do
1189
-
1190
- let(:criteria) do
1191
- Person.send(method, preference_ids: [ id, nil ])
1192
- end
1193
-
1194
- it "returns the matching documents" do
1195
- expect(criteria).to eq([ match_one ])
1196
- end
1197
- end
1198
-
1199
- context "when the relation is a one to one" do
1200
-
1201
- let!(:game) do
1202
- Game.create!
1203
- end
1204
-
1205
- let(:criteria) do
1206
- Game.send(method, person_id: [ nil ])
1207
- end
1208
-
1209
- it "returns the matching documents" do
1210
- expect(criteria).to eq([ game ])
1211
- end
1212
- end
1213
- end
1214
- end
1215
- end
1216
- end
1217
-
1218
- describe "#initialize" do
1219
-
1220
- let(:criteria) do
1221
- described_class.new(Band)
1222
- end
1223
-
1224
- it "sets the class" do
1225
- expect(criteria.klass).to eq(Band)
1226
- end
1227
-
1228
- it "sets the aliased fields" do
1229
- expect(criteria.aliased_fields).to eq(Band.aliased_fields)
1230
- end
1231
-
1232
- it "sets the serializers" do
1233
- expect(criteria.serializers).to eq(Band.fields)
1234
- end
1235
- end
1236
-
1237
- describe "#includes" do
1238
-
1239
- let!(:person) do
1240
- Person.create!(age: 1)
1241
- end
1242
-
1243
- context "when providing a name that is not a relation" do
1244
-
1245
- it "raises an error" do
1246
- expect {
1247
- Person.includes(:members)
1248
- }.to raise_error(Mongoid::Errors::InvalidIncludes)
1249
- end
1250
- end
1251
-
1252
- context "when providing one association" do
1253
-
1254
- let!(:user) do
1255
- User.create!(posts: [ post1 ])
1256
- end
1257
-
1258
- let!(:post1) do
1259
- Post.create!
1260
- end
1261
-
1262
- let(:result) do
1263
- User.includes(:posts).first
1264
- end
1265
-
1266
- it "executes the query" do
1267
- expect(result).to eq(user)
1268
- end
1269
-
1270
- it "includes the related objects" do
1271
- expect(result.posts).to eq([ post1 ])
1272
- end
1273
- end
1274
-
1275
- context "when providing a list of associations" do
1276
-
1277
- let!(:user) do
1278
- User.create!(posts: [ post1 ], descriptions: [ description1 ])
1279
- end
1280
-
1281
- let!(:post1) do
1282
- Post.create!
1283
- end
1284
-
1285
- let!(:description1) do
1286
- Description.create!(details: 1)
1287
- end
1288
-
1289
- let(:result) do
1290
- User.includes(:posts, :descriptions).first
1291
- end
1292
-
1293
- it "executes the query" do
1294
- expect(result).to eq(user)
1295
- end
1296
-
1297
- it "includes the related objects" do
1298
- expect(result.posts).to eq([ post1 ])
1299
- expect(result.descriptions).to eq([ description1 ])
1300
- end
1301
- end
1302
-
1303
- context "when providing a nested association" do
1304
-
1305
- let!(:user) do
1306
- User.create!
1307
- end
1308
-
1309
- before do
1310
- p = Post.create!(alerts: [ Alert.create! ])
1311
- user.posts = [ p ]
1312
- user.save!
1313
- end
1314
-
1315
- let(:result) do
1316
- User.includes(:posts => [:alerts]).first
1317
- end
1318
-
1319
- it "executes the query" do
1320
- expect(result).to eq(user)
1321
- end
1322
-
1323
- it "includes the related objects" do
1324
- expect(result.posts.size).to eq(1)
1325
- expect(result.posts.first.alerts.size).to eq(1)
1326
- end
1327
- end
1328
-
1329
- context "when providing a deeply nested association" do
1330
-
1331
- let!(:user) do
1332
- User.create!
1333
- end
1334
-
1335
- let(:results) do
1336
- User.includes(:posts => [{ :alerts => :items }]).to_a
1337
- end
1338
-
1339
- it "executes the query" do
1340
- expect(results.first).to eq(user)
1341
- end
1342
- end
1343
-
1344
- context "when the models are inherited" do
1345
-
1346
- before(:all) do
1347
- class A
1348
- include Mongoid::Document
1349
- end
1350
-
1351
- class B < A
1352
- belongs_to :c
1353
- end
1354
-
1355
- class C
1356
- include Mongoid::Document
1357
- has_one :b
1358
- end
1359
- end
1360
-
1361
- after(:all) do
1362
- Object.send(:remove_const, :A)
1363
- Object.send(:remove_const, :B)
1364
- Object.send(:remove_const, :C)
1365
- end
1366
-
1367
- context "when the includes is on the subclass" do
1368
-
1369
- let!(:c_one) do
1370
- C.create!
1371
- end
1372
-
1373
- let!(:c_two) do
1374
- C.create!
1375
- end
1376
-
1377
- let!(:b) do
1378
- B.create!(c: c_two)
1379
- end
1380
-
1381
- let!(:results) do
1382
- C.includes(:b).to_a.detect do |c|
1383
- c.id == c_two.id
1384
- end
1385
- end
1386
-
1387
- it "returns the correct documents" do
1388
- expect(results).to eq(c_two)
1389
- end
1390
-
1391
- it "does not query the db" do
1392
- expect_query(0) do
1393
- results.b
1394
- end
1395
- end
1396
- end
1397
- end
1398
-
1399
- context "when the models are inherited from another one model" do
1400
-
1401
- context "when the relation is a has_one" do
1402
-
1403
- before(:all) do
1404
- class A
1405
- include Mongoid::Document
1406
- end
1407
-
1408
- class B < A
1409
- belongs_to :d
1410
- end
1411
-
1412
- class C < A
1413
- belongs_to :d
1414
- end
1415
-
1416
- class D
1417
- include Mongoid::Document
1418
- has_one :b
1419
- has_one :c
1420
- end
1421
- end
1422
-
1423
- after(:all) do
1424
- Object.send(:remove_const, :A)
1425
- Object.send(:remove_const, :B)
1426
- Object.send(:remove_const, :C)
1427
- Object.send(:remove_const, :D)
1428
- end
1429
-
1430
- context "when the includes is on the several relations" do
1431
-
1432
- let!(:d_one) do
1433
- D.create!
1434
- end
1435
-
1436
- let!(:d_two) do
1437
- D.create!
1438
- end
1439
-
1440
- let!(:b) do
1441
- B.create!(d: d_two)
1442
- end
1443
-
1444
- let!(:c) do
1445
- C.create!(d: d_two)
1446
- end
1447
-
1448
- let!(:results) do
1449
- D.includes(:b, :c).entries.detect do |d|
1450
- d.id == d_two.id
1451
- end
1452
- end
1453
-
1454
- it "returns the correct documents" do
1455
- expect(results).to eq(d_two)
1456
- end
1457
-
1458
- it "does not query the db on b" do
1459
- expect_query(0) do
1460
- results.b
1461
- end
1462
- end
1463
-
1464
- it "does not query the db on c" do
1465
- expect_query(0) do
1466
- results.b
1467
- end
1468
- end
1469
- end
1470
- end
1471
-
1472
- context "when the relation is a has_many" do
1473
-
1474
- before(:all) do
1475
- class A
1476
- include Mongoid::Document
1477
- end
1478
-
1479
- class B < A
1480
- belongs_to :d
1481
- end
1482
-
1483
- class C < A
1484
- belongs_to :d
1485
- end
1486
-
1487
- class D
1488
- include Mongoid::Document
1489
- has_many :b
1490
- has_many :c
1491
- end
1492
- end
1493
-
1494
- after(:all) do
1495
- Object.send(:remove_const, :A)
1496
- Object.send(:remove_const, :B)
1497
- Object.send(:remove_const, :C)
1498
- Object.send(:remove_const, :D)
1499
- end
1500
-
1501
- context "when the includes is on the several relations" do
1502
-
1503
- let!(:d_one) do
1504
- D.create!
1505
- end
1506
-
1507
- let!(:d_two) do
1508
- D.create!
1509
- end
1510
-
1511
- let!(:bs) do
1512
- 2.times.map { B.create!(d: d_two) }
1513
- end
1514
-
1515
- let!(:cs) do
1516
- 2.times.map { C.create!(d: d_two) }
1517
- end
1518
-
1519
- let!(:results) do
1520
- D.includes(:b, :c).entries.detect do |d|
1521
- d.id == d_two.id
1522
- end
1523
- end
1524
-
1525
- it "returns the correct documents" do
1526
- expect(results).to eq(d_two)
1527
- end
1528
-
1529
- it "does not query the db on b" do
1530
- expect_query(0) do
1531
- results.b
1532
- end
1533
- end
1534
-
1535
- it "does not query the db on c" do
1536
- expect_query(0) do
1537
- results.b
1538
- end
1539
- end
1540
- end
1541
- end
1542
- end
1543
-
1544
- context "when including the same association multiple times" do
1545
-
1546
- let(:criteria) do
1547
- Person.all.includes(:posts, :posts).includes(:posts)
1548
- end
1549
-
1550
- let(:association) do
1551
- Person.reflect_on_association(:posts)
1552
- end
1553
-
1554
- it "does not duplicate the association in the inclusions" do
1555
- expect(criteria.inclusions).to eq([ association ])
1556
- end
1557
- end
1558
-
1559
- context "when mapping the results more than once" do
1560
-
1561
- let!(:post) do
1562
- person.posts.create!(title: "one")
1563
- end
1564
-
1565
- let(:criteria) do
1566
- Post.includes(:person)
1567
- end
1568
-
1569
- let!(:results) do
1570
- criteria.map { |doc| doc }
1571
- criteria.map { |doc| doc }
1572
- end
1573
-
1574
- it "returns the proper results" do
1575
- expect(results.first.title).to eq("one")
1576
- end
1577
- end
1578
-
1579
- context "when including a belongs to relation" do
1580
-
1581
- context "when the criteria is from the root" do
1582
-
1583
- let!(:person_two) do
1584
- Person.create!(age: 2)
1585
- end
1586
-
1587
- let!(:post_one) do
1588
- person.posts.create!(title: "one")
1589
- end
1590
-
1591
- let!(:post_two) do
1592
- person_two.posts.create!(title: "two")
1593
- end
1594
-
1595
- context "when calling first" do
1596
-
1597
- let(:criteria) do
1598
- Post.includes(:person)
1599
- end
1600
-
1601
- let!(:document) do
1602
- criteria.first
1603
- end
1604
-
1605
- it "eager loads the first document" do
1606
- expect_query(0) do
1607
- expect(document.person).to eq(person)
1608
- end
1609
- end
1610
-
1611
- it "returns the first document" do
1612
- expect(document).to eq(post_one)
1613
- end
1614
- end
1615
-
1616
- context "when calling last" do
1617
-
1618
- let!(:criteria) do
1619
- Post.asc(:_id).includes(:person)
1620
- end
1621
-
1622
- let!(:document) do
1623
- criteria.last
1624
- end
1625
-
1626
- it "eager loads the last document" do
1627
- expect_query(0) do
1628
- expect(document.person).to eq(person_two)
1629
- end
1630
- end
1631
-
1632
- it "returns the last document" do
1633
- expect(document).to eq(post_two)
1634
- end
1635
- end
1636
- end
1637
-
1638
- context "when the criteria is from an embedded relation" do
1639
-
1640
- let(:peep) do
1641
- Person.create!
1642
- end
1643
-
1644
- let!(:address_one) do
1645
- peep.addresses.create!(street: "rosenthaler")
1646
- end
1647
-
1648
- let!(:address_two) do
1649
- peep.addresses.create!(street: "weinmeister")
1650
- end
1651
-
1652
- let!(:depeche) do
1653
- Band.create!(name: "Depeche Mode")
1654
- end
1655
-
1656
- let!(:tool) do
1657
- Band.create!(name: "Tool")
1658
- end
1659
-
1660
- before do
1661
- address_one.band = depeche
1662
- address_two.band = tool
1663
- address_one.save!
1664
- address_two.save!
1665
- end
1666
-
1667
- context "when calling first" do
1668
-
1669
- let(:criteria) do
1670
- peep.reload.addresses.includes(:band)
1671
- end
1672
-
1673
- let(:context) do
1674
- criteria.context
1675
- end
1676
-
1677
- let!(:document) do
1678
- criteria.first
1679
- end
1680
-
1681
- it "eager loads the first document" do
1682
- expect_query(0) do
1683
- expect(document.band).to eq(depeche)
1684
- end
1685
- end
1686
-
1687
- it "returns the document" do
1688
- expect(document).to eq(address_one)
1689
- end
1690
- end
1691
-
1692
- context "when calling last" do
1693
-
1694
- let(:criteria) do
1695
- peep.reload.addresses.includes(:band)
1696
- end
1697
-
1698
- let(:context) do
1699
- criteria.context
1700
- end
1701
-
1702
- let!(:document) do
1703
- criteria.last
1704
- end
1705
-
1706
- it "eager loads the last document" do
1707
- expect_query(0) do
1708
- expect(document.band).to eq(tool)
1709
- end
1710
- end
1711
-
1712
- it "returns the document" do
1713
- expect(document).to eq(address_two)
1714
- end
1715
- end
1716
-
1717
- context "when iterating all documents" do
1718
-
1719
- let(:criteria) do
1720
- peep.reload.addresses.includes(:band)
1721
- end
1722
-
1723
- let(:context) do
1724
- criteria.context
1725
- end
1726
-
1727
- let!(:documents) do
1728
- criteria.to_a
1729
- end
1730
-
1731
- it "eager loads the first document" do
1732
- expect_query(0) do
1733
- expect(documents.first.band).to eq(depeche)
1734
- end
1735
- end
1736
-
1737
- it "eager loads the last document" do
1738
- expect_query(0) do
1739
- expect(documents.last.band).to eq(tool)
1740
- end
1741
- end
1742
-
1743
- it "returns the documents" do
1744
- expect(documents).to eq([ address_one, address_two ])
1745
- end
1746
- end
1747
- end
1748
- end
1749
-
1750
- context "when providing inclusions to the default scope" do
1751
-
1752
- before do
1753
- Person.default_scope(->{ Person.includes(:posts) })
1754
- end
1755
-
1756
- after do
1757
- Person.default_scoping = nil
1758
- end
1759
-
1760
- let!(:post_one) do
1761
- person.posts.create!(title: "one")
1762
- end
1763
-
1764
- let!(:post_two) do
1765
- person.posts.create!(title: "two")
1766
- end
1767
-
1768
- context "when the criteria has no options" do
1769
-
1770
- let!(:criteria) do
1771
- Person.asc(:age).all
1772
- end
1773
-
1774
- let!(:documents) do
1775
- criteria.entries
1776
- end
1777
-
1778
- it "returns the correct documents" do
1779
- expect(documents).to eq([ person ])
1780
- end
1781
-
1782
- it "eager loads the first document" do
1783
- expect_query(0) do
1784
- expect(documents.first.posts.first).to eq(post_one)
1785
- end
1786
- end
1787
-
1788
- it "eager loads the last document" do
1789
- expect_query(0) do
1790
- expect(documents.first.posts.last).to eq(post_two)
1791
- end
1792
- end
1793
-
1794
- context "when executing the query twice" do
1795
-
1796
- let!(:new_criteria) do
1797
- Person.where(id: person.id)
1798
- end
1799
-
1800
- let!(:new_context) do
1801
- new_criteria.context
1802
- end
1803
-
1804
- before do
1805
- expect(new_context).to receive(:eager_load).with([person]).once.and_call_original
1806
- end
1807
-
1808
- let!(:from_db) do
1809
- new_criteria.first
1810
- end
1811
-
1812
- it "does not duplicate documents in the relation" do
1813
- expect(person.posts.size).to eq(2)
1814
- end
1815
- end
1816
- end
1817
-
1818
- context "when calling first on the criteria" do
1819
-
1820
- let(:criteria) do
1821
- Person.asc(:age).all
1822
- end
1823
-
1824
- let!(:from_db) do
1825
- criteria.first
1826
- end
1827
-
1828
- it "returns the correct documents" do
1829
- expect(from_db).to eq(person)
1830
- end
1831
-
1832
- it "eager loads the first document" do
1833
- expect_query(0) do
1834
- expect(from_db.posts.first).to eq(post_one)
1835
- end
1836
- end
1837
-
1838
- it "eager loads the last document" do
1839
- expect_query(0) do
1840
- expect(from_db.posts.last).to eq(post_two)
1841
- end
1842
- end
1843
- end
1844
-
1845
- context "when calling last on the criteria" do
1846
-
1847
- let(:criteria) do
1848
- Person.asc(:age).all
1849
- end
1850
-
1851
- let!(:context) do
1852
- criteria.context
1853
- end
1854
-
1855
- before do
1856
- expect(context).to receive(:eager_load).with([person]).once.and_call_original
1857
- end
1858
-
1859
- let!(:from_db) do
1860
- criteria.last
1861
- end
1862
-
1863
- it "returns the correct documents" do
1864
- expect(from_db).to eq(person)
1865
- end
1866
-
1867
- it "eager loads the first document" do
1868
- expect_query(0) do
1869
- expect(from_db.posts.first).to eq(post_one)
1870
- end
1871
- end
1872
-
1873
- it "eager loads the last document" do
1874
- expect_query(0) do
1875
- expect(from_db.posts.last).to eq(post_two)
1876
- end
1877
- end
1878
- end
1879
-
1880
- context "when the criteria has limiting options" do
1881
-
1882
- let!(:person_two) do
1883
- Person.create!
1884
- end
1885
-
1886
- let!(:post_three) do
1887
- person_two.posts.create!(title: "three")
1888
- end
1889
-
1890
- let!(:criteria) do
1891
- Person.asc(:age).limit(1)
1892
- end
1893
-
1894
- let!(:documents) do
1895
- criteria.entries
1896
- end
1897
-
1898
- it "returns the correct documents" do
1899
- expect(criteria).to eq([ person ])
1900
- end
1901
-
1902
- it "eager loads the first document" do
1903
- expect_query(0) do
1904
- expect(documents.first.posts.first).to eq(post_one)
1905
- end
1906
- end
1907
-
1908
- it "eager loads the second document" do
1909
- expect_query(0) do
1910
- expect(documents.first.posts.last).to eq(post_two)
1911
- end
1912
- end
1913
- end
1914
- end
1915
-
1916
- context "when including a has and belongs to many" do
1917
-
1918
- let!(:preference_one) do
1919
- person.preferences.create!(name: "one")
1920
- end
1921
-
1922
- let!(:preference_two) do
1923
- person.preferences.create!(name: "two")
1924
- end
1925
-
1926
- context "when one of the related items is deleted" do
1927
-
1928
- before do
1929
- person.preferences = [ preference_one, preference_two ]
1930
- preference_two.delete
1931
- end
1932
-
1933
- let(:criteria) do
1934
- Person.where(id: person.id).includes(:preferences)
1935
- end
1936
-
1937
- it "only loads the existing related items" do
1938
- expect(criteria.entries.first.preferences).to eq([ preference_one ])
1939
- end
1940
- end
1941
-
1942
- context "when the criteria has no options" do
1943
-
1944
- let!(:criteria) do
1945
- Person.asc(:age).includes(:preferences)
1946
- end
1947
-
1948
- let!(:documents) do
1949
- criteria.entries
1950
- end
1951
-
1952
- it "returns the correct documents" do
1953
- expect(documents).to eq([ person ])
1954
- end
1955
-
1956
- it "eager loads the first document" do
1957
- expect_query(0) do
1958
- expect(documents.first.preferences.first).to eq(preference_one)
1959
- end
1960
- end
1961
-
1962
- it "eager loads the last document" do
1963
- expect_query(0) do
1964
- expect(documents.first.preferences.last).to eq(preference_two)
1965
- end
1966
- end
1967
- end
1968
-
1969
- context "when calling first on the criteria" do
1970
-
1971
- let!(:criteria) do
1972
- Person.asc(:age).includes(:preferences)
1973
- end
1974
-
1975
- let!(:from_db) do
1976
- criteria.first
1977
- end
1978
-
1979
- it "returns the correct documents" do
1980
- expect(from_db).to eq(person)
1981
- end
1982
-
1983
- it "eager loads the first document" do
1984
- expect_query(0) do
1985
- expect(from_db.preferences.first).to eq(preference_one)
1986
- end
1987
- end
1988
-
1989
- it "eager loads the last document" do
1990
- expect_query(0) do
1991
- expect(from_db.preferences.last).to eq(preference_two)
1992
- end
1993
- end
1994
- end
1995
-
1996
- context "when calling last on the criteria" do
1997
-
1998
- let!(:criteria) do
1999
- Person.asc(:age).includes(:preferences)
2000
- end
2001
-
2002
- let!(:from_db) do
2003
- criteria.last
2004
- end
2005
-
2006
- it "returns the correct documents" do
2007
- expect(from_db).to eq(person)
2008
- end
2009
-
2010
- it "eager loads the first document" do
2011
- expect_query(0) do
2012
- expect(from_db.preferences.first).to eq(preference_one)
2013
- end
2014
- end
2015
-
2016
- it "eager loads the last document" do
2017
- expect_query(0) do
2018
- expect(from_db.preferences.last).to eq(preference_two)
2019
- end
2020
- end
2021
- end
2022
- end
2023
-
2024
- context "when including a has many" do
2025
-
2026
- let!(:post_one) do
2027
- person.posts.create!(title: "one")
2028
- end
2029
-
2030
- let!(:post_two) do
2031
- person.posts.create!(title: "two")
2032
- end
2033
-
2034
- context "when the criteria has no options" do
2035
-
2036
- let!(:criteria) do
2037
- Person.asc(:age).includes(:posts)
2038
- end
2039
-
2040
- let!(:documents) do
2041
- criteria.entries
2042
- end
2043
-
2044
- it "returns the correct documents" do
2045
- expect(documents).to eq([ person ])
2046
- end
2047
-
2048
- it "eager loads the first document" do
2049
- expect_query(0) do
2050
- expect(documents.first.posts.first).to eq(post_one)
2051
- end
2052
- end
2053
-
2054
- it "eager loads the last document" do
2055
- expect_query(0) do
2056
- expect(documents.first.posts.last).to eq(post_two)
2057
- end
2058
- end
2059
- end
2060
-
2061
- context "when calling first on the criteria" do
2062
-
2063
- let!(:criteria) do
2064
- Person.asc(:age).includes(:posts)
2065
- end
2066
-
2067
- let!(:from_db) do
2068
- criteria.first
2069
- end
2070
-
2071
- it "returns the correct documents" do
2072
- expect(from_db).to eq(person)
2073
- end
2074
-
2075
- context "when subsequently getting all documents" do
2076
-
2077
- let!(:documents) do
2078
- criteria.entries
2079
- end
2080
-
2081
- it "returns the correct documents" do
2082
- expect(documents).to eq([ person ])
2083
- end
2084
- end
2085
- end
2086
-
2087
- context "when calling last on the criteria" do
2088
-
2089
- let!(:criteria) do
2090
- Person.asc(:age).includes(:posts)
2091
- end
2092
-
2093
- let!(:from_db) do
2094
- criteria.last
2095
- end
2096
-
2097
- it "returns the correct documents" do
2098
- expect(from_db).to eq(person)
2099
- end
2100
-
2101
- context "when subsequently getting all documents" do
2102
-
2103
- let!(:documents) do
2104
- criteria.entries
2105
- end
2106
-
2107
- it "returns the correct documents" do
2108
- expect(documents).to eq([ person ])
2109
- end
2110
- end
2111
- end
2112
-
2113
- context "when the criteria has limiting options" do
2114
-
2115
- let!(:person_two) do
2116
- Person.create!
2117
- end
2118
-
2119
- let!(:post_three) do
2120
- person_two.posts.create!(title: "three")
2121
- end
2122
-
2123
- let!(:criteria) do
2124
- Person.includes(:posts).asc(:age).limit(1)
2125
- end
2126
-
2127
- let(:context) do
2128
- criteria.context
2129
- end
2130
-
2131
- before do
2132
- expect(context).to receive(:eager_load).with([ person ]).once.and_call_original
2133
- end
2134
-
2135
- let!(:documents) do
2136
- criteria.entries
2137
- end
2138
-
2139
- it "returns the correct documents" do
2140
- expect(documents).to eq([ person ])
2141
- end
2142
- end
2143
- end
2144
-
2145
- context "when including a has one" do
2146
-
2147
- let!(:game_one) do
2148
- person.create_game(name: "one")
2149
- end
2150
-
2151
- let!(:game_two) do
2152
- person.create_game(name: "two")
2153
- end
2154
-
2155
- context "when the criteria has no options" do
2156
-
2157
- let!(:criteria) do
2158
- Person.asc(:age).includes(:game)
2159
- end
2160
-
2161
- let(:context) do
2162
- criteria.context
2163
- end
2164
-
2165
- before do
2166
- expect(context).to receive(:eager_load).with([ person ]).once.and_call_original
2167
- end
2168
-
2169
- let!(:documents) do
2170
- criteria.entries
2171
- end
2172
-
2173
- it "returns the correct documents" do
2174
- expect(documents).to eq([ person ])
2175
- end
2176
- end
2177
-
2178
- context "when the criteria has limiting options" do
2179
-
2180
- let!(:person_two) do
2181
- Person.create!(age: 2)
2182
- end
2183
-
2184
- let!(:game_three) do
2185
- person_two.create_game(name: "Skyrim")
2186
- end
2187
-
2188
- let!(:criteria) do
2189
- Person.where(id: person.id).includes(:game).asc(:age).limit(1)
2190
- end
2191
-
2192
- let(:context) do
2193
- criteria.context
2194
- end
2195
-
2196
- before do
2197
- expect(context).to receive(:eager_load).with([ person ]).once.and_call_original
2198
- end
2199
-
2200
- let!(:documents) do
2201
- criteria.entries
2202
- end
2203
-
2204
- it "returns the correct documents" do
2205
- expect(documents).to eq([ person ])
2206
- end
2207
- end
2208
- end
2209
-
2210
- context "when including a belongs to" do
2211
-
2212
- let(:person_two) do
2213
- Person.create!(age: 2)
2214
- end
2215
-
2216
- let!(:game_one) do
2217
- person.create_game(name: "one")
2218
- end
2219
-
2220
- let!(:game_two) do
2221
- person_two.create_game(name: "two")
2222
- end
2223
-
2224
- context "when providing no options" do
2225
-
2226
- let!(:criteria) do
2227
- Game.includes(:person)
2228
- end
2229
-
2230
- let(:context) do
2231
- criteria.context
2232
- end
2233
-
2234
- before do
2235
- expect(context).to receive(:preload).twice.and_call_original
2236
- end
2237
-
2238
- let!(:documents) do
2239
- criteria.entries
2240
- end
2241
-
2242
- it "returns the correct documents" do
2243
- expect(criteria).to eq([ game_one, game_two ])
2244
- end
2245
- end
2246
-
2247
- context "when the criteria has limiting options" do
2248
-
2249
- let!(:criteria) do
2250
- Game.where(id: game_one.id).includes(:person).asc(:_id).limit(1)
2251
- end
2252
-
2253
- let(:context) do
2254
- criteria.context
2255
- end
2256
-
2257
- before do
2258
- expect(context).to receive(:eager_load).with([ game_one ]).once.and_call_original
2259
- end
2260
-
2261
- let!(:documents) do
2262
- criteria.entries
2263
- end
2264
-
2265
- it "returns the correct documents" do
2266
- expect(documents).to eq([ game_one ])
2267
- end
2268
- end
2269
- end
1155
+ end
2270
1156
 
2271
- context "when including multiples in the same criteria" do
1157
+ context "when providing valid ids" do
2272
1158
 
2273
- let!(:post_one) do
2274
- person.posts.create!(title: "one")
2275
- end
1159
+ let(:criteria) do
1160
+ Person.send(method, preference_ids: [ id ])
1161
+ end
2276
1162
 
2277
- let!(:post_two) do
2278
- person.posts.create!(title: "two")
2279
- end
1163
+ it "returns the matching documents" do
1164
+ expect(criteria).to eq([ match_one ])
1165
+ end
1166
+ end
2280
1167
 
2281
- let!(:game_one) do
2282
- person.create_game(name: "one")
2283
- end
1168
+ context "when providing empty strings" do
2284
1169
 
2285
- let!(:game_two) do
2286
- person.create_game(name: "two")
2287
- end
1170
+ let(:criteria) do
1171
+ Person.send(method, preference_ids: [ id, "" ])
1172
+ end
2288
1173
 
2289
- let!(:criteria) do
2290
- Person.includes(:posts, :game).asc(:age)
2291
- end
1174
+ it "returns the matching documents" do
1175
+ expect(criteria).to eq([ match_one ])
1176
+ end
1177
+ end
2292
1178
 
2293
- let(:context) do
2294
- criteria.context
2295
- end
1179
+ context "when providing nils" do
2296
1180
 
2297
- before do
2298
- expect(context).to receive(:preload).twice.and_call_original
2299
- end
1181
+ context "when the relation is a many to many" do
2300
1182
 
2301
- let!(:documents) do
2302
- criteria.entries
2303
- end
1183
+ let(:criteria) do
1184
+ Person.send(method, preference_ids: [ id, nil ])
1185
+ end
2304
1186
 
2305
- it "returns the correct documents" do
2306
- expect(criteria).to eq([ person ])
2307
- end
2308
- end
2309
- end
1187
+ it "returns the matching documents" do
1188
+ expect(criteria).to eq([ match_one ])
1189
+ end
1190
+ end
2310
1191
 
2311
- describe "#inclusions" do
1192
+ context "when the relation is a one to one" do
2312
1193
 
2313
- let(:criteria) do
2314
- Band.includes(:records)
2315
- end
1194
+ let!(:game) do
1195
+ Game.create!
1196
+ end
2316
1197
 
2317
- let(:association) do
2318
- Band.relations["records"]
2319
- end
1198
+ let(:criteria) do
1199
+ Game.send(method, person_id: [ nil ])
1200
+ end
2320
1201
 
2321
- it "returns the inclusions" do
2322
- expect(criteria.inclusions).to eq([ association ])
1202
+ it "returns the matching documents" do
1203
+ expect(criteria).to eq([ game ])
1204
+ end
1205
+ end
1206
+ end
1207
+ end
2323
1208
  end
2324
1209
  end
2325
1210
 
2326
- describe "#inclusions=" do
1211
+ describe "#initialize" do
2327
1212
 
2328
1213
  let(:criteria) do
2329
- Band.all
1214
+ described_class.new(Band)
2330
1215
  end
2331
1216
 
2332
- let(:association) do
2333
- Band.relations["records"]
1217
+ it "sets the class" do
1218
+ expect(criteria.klass).to eq(Band)
2334
1219
  end
2335
1220
 
2336
- before do
2337
- criteria.inclusions = [ association ]
1221
+ it "sets the aliased fields" do
1222
+ expect(criteria.aliased_fields).to eq(Band.aliased_fields)
2338
1223
  end
2339
1224
 
2340
- it "sets the inclusions" do
2341
- expect(criteria.inclusions).to eq([ association ])
1225
+ it "sets the serializers" do
1226
+ expect(criteria.serializers).to eq(Band.fields)
2342
1227
  end
2343
1228
  end
2344
1229
 
@@ -3047,7 +1932,7 @@ describe Mongoid::Criteria do
3047
1932
  end
3048
1933
 
3049
1934
  with_config_values :legacy_pluck_distinct, true, false do
3050
- it "returns a array with nil values" do
1935
+ it "returns an array with nil values" do
3051
1936
  expect(plucked).to eq([nil, nil, nil])
3052
1937
  end
3053
1938
  end
@@ -3060,7 +1945,7 @@ describe Mongoid::Criteria do
3060
1945
  end
3061
1946
 
3062
1947
  with_config_values :legacy_pluck_distinct, true, false do
3063
- it "returns a nil arrays" do
1948
+ it "returns an array of arrays with nil values" do
3064
1949
  expect(plucked).to eq([[nil, nil], [nil, nil], [nil, nil]])
3065
1950
  end
3066
1951
  end
@@ -3174,7 +2059,7 @@ describe Mongoid::Criteria do
3174
2059
  end
3175
2060
 
3176
2061
  context 'when fallbacks are enabled with a locale list' do
3177
- require_fallbacks
2062
+ with_i18n_fallbacks
3178
2063
 
3179
2064
  around(:all) do |example|
3180
2065
  prev_fallbacks = I18n.fallbacks.dup
@@ -3273,18 +2158,45 @@ describe Mongoid::Criteria do
3273
2158
  context "when legacy_pluck_distinct is set" do
3274
2159
  config_override :legacy_pluck_distinct, true
3275
2160
 
3276
- it "does not demongoize the field" do
3277
- expect(plucked.first).to be_a(String)
3278
- expect(plucked.first).to eq("1E2")
2161
+ context 'when value is stored as string' do
2162
+ config_override :map_big_decimal_to_decimal128, false
2163
+
2164
+ it "does not demongoize the field" do
2165
+ expect(plucked.first).to be_a(String)
2166
+ expect(plucked.first).to eq("1E2")
2167
+ end
2168
+ end
2169
+
2170
+ context 'when value is stored as decimal128' do
2171
+ config_override :map_big_decimal_to_decimal128, true
2172
+ max_bson_version '4.99.99'
2173
+
2174
+ it "does not demongoize the field" do
2175
+ expect(plucked.first).to be_a(BSON::Decimal128)
2176
+ expect(plucked.first).to eq(BSON::Decimal128.new("1E2"))
2177
+ end
3279
2178
  end
3280
2179
  end
3281
2180
 
3282
2181
  context "when legacy_pluck_distinct is not set" do
3283
2182
  config_override :legacy_pluck_distinct, false
3284
2183
 
3285
- it "demongoizes the field" do
3286
- expect(plucked.first).to be_a(BigDecimal)
3287
- expect(plucked.first).to eq(BigDecimal("1E2"))
2184
+ context 'when value is stored as string' do
2185
+ config_override :map_big_decimal_to_decimal128, false
2186
+
2187
+ it "demongoizes the field" do
2188
+ expect(plucked.first).to be_a(BigDecimal)
2189
+ expect(plucked.first).to eq(BigDecimal("1E2"))
2190
+ end
2191
+ end
2192
+
2193
+ context 'when value is stored as decimal128' do
2194
+ config_override :map_big_decimal_to_decimal128, true
2195
+
2196
+ it "demongoizes the field" do
2197
+ expect(plucked.first).to be_a(BigDecimal)
2198
+ expect(plucked.first).to eq(BigDecimal("1E2"))
2199
+ end
3288
2200
  end
3289
2201
  end
3290
2202
  end
@@ -3297,9 +2209,11 @@ describe Mongoid::Criteria do
3297
2209
 
3298
2210
  context "when legacy_pluck_distinct is set" do
3299
2211
  config_override :legacy_pluck_distinct, true
2212
+ config_override :map_big_decimal_to_decimal128, true
2213
+ max_bson_version '4.99.99'
3300
2214
 
3301
2215
  it "returns a hash with a non-demongoized field" do
3302
- expect(plucked.first).to eq({ 'sales' => "1E2" })
2216
+ expect(plucked.first).to eq({ 'sales' => BSON::Decimal128.new('1E+2') })
3303
2217
  end
3304
2218
  end
3305
2219
 
@@ -3307,7 +2221,7 @@ describe Mongoid::Criteria do
3307
2221
  config_override :legacy_pluck_distinct, false
3308
2222
 
3309
2223
  it "demongoizes the field" do
3310
- expect(plucked.first).to eq(BigDecimal("1E2"))
2224
+ expect(plucked).to eq([ BigDecimal("1E2") ])
3311
2225
  end
3312
2226
  end
3313
2227
  end
@@ -3320,9 +2234,11 @@ describe Mongoid::Criteria do
3320
2234
 
3321
2235
  context "when legacy_pluck_distinct is set" do
3322
2236
  config_override :legacy_pluck_distinct, true
2237
+ config_override :map_big_decimal_to_decimal128, true
2238
+ max_bson_version '4.99.99'
3323
2239
 
3324
2240
  it "returns a hash with a non-demongoized field" do
3325
- expect(plucked.first).to eq([{ 'sales' => "1E2" }])
2241
+ expect(plucked.first).to eq([{ 'sales' => BSON::Decimal128.new('1E+2') }])
3326
2242
  end
3327
2243
  end
3328
2244
 
@@ -3330,7 +2246,7 @@ describe Mongoid::Criteria do
3330
2246
  config_override :legacy_pluck_distinct, false
3331
2247
 
3332
2248
  it "demongoizes the field" do
3333
- expect(plucked.first).to eq([BigDecimal("1E2")])
2249
+ expect(plucked.first).to eq([ BigDecimal("1E2") ])
3334
2250
  end
3335
2251
  end
3336
2252
  end
@@ -3357,6 +2273,66 @@ describe Mongoid::Criteria do
3357
2273
  end
3358
2274
  end
3359
2275
  end
2276
+
2277
+ context "when tallying deeply nested arrays/embedded associations" do
2278
+
2279
+ before do
2280
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
2281
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
2282
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))) ])
2283
+ end
2284
+
2285
+ let(:plucked) do
2286
+ Person.pluck("addresses.code.deepest.array.y.z")
2287
+ end
2288
+
2289
+ it "returns the correct hash" do
2290
+ expect(plucked).to eq([
2291
+ [ [ 1, 2 ] ], [ [ 1, 2 ] ], [ [ 1, 3 ] ]
2292
+ ])
2293
+ end
2294
+ end
2295
+ end
2296
+
2297
+ describe "#pick" do
2298
+
2299
+ let!(:depeche) do
2300
+ Band.create!(name: "Depeche Mode", likes: 3)
2301
+ end
2302
+
2303
+ let!(:tool) do
2304
+ Band.create!(name: "Tool", likes: 3)
2305
+ end
2306
+
2307
+ context "when picking a field" do
2308
+
2309
+ let(:criteria) do
2310
+ Band.all
2311
+ end
2312
+
2313
+ let(:picked) do
2314
+ criteria.pick(:name)
2315
+ end
2316
+
2317
+ it "returns one element" do
2318
+ expect(picked).to eq("Depeche Mode")
2319
+ end
2320
+ end
2321
+
2322
+ context "when picking multiple fields" do
2323
+
2324
+ let(:criteria) do
2325
+ Band.all
2326
+ end
2327
+
2328
+ let(:picked) do
2329
+ criteria.pick(:name, :likes)
2330
+ end
2331
+
2332
+ it "returns an array" do
2333
+ expect(picked).to eq([ "Depeche Mode", 3 ])
2334
+ end
2335
+ end
3360
2336
  end
3361
2337
 
3362
2338
  describe "#respond_to?" do
@@ -3732,20 +2708,109 @@ describe Mongoid::Criteria do
3732
2708
 
3733
2709
  context "when querying on a big decimal" do
3734
2710
 
3735
- let(:sales) do
3736
- BigDecimal('0.1')
2711
+ context 'when map_big_decimal_to_decimal128 is false' do
2712
+ config_override :map_big_decimal_to_decimal128, false
2713
+
2714
+ let(:sales) do
2715
+ BigDecimal('0.1')
2716
+ end
2717
+
2718
+ let!(:band) do
2719
+ Band.create!(name: "Boards of Canada", sales: sales)
2720
+ end
2721
+
2722
+ let(:from_db) do
2723
+ Band.where(sales: sales).first
2724
+ end
2725
+
2726
+ it "finds the document by the big decimal value" do
2727
+ expect(from_db).to eq(band)
2728
+ end
3737
2729
  end
3738
2730
 
3739
- let!(:band) do
3740
- Band.create!(name: "Boards of Canada", sales: sales)
2731
+ context 'when map_big_decimal_to_decimal128 is true' do
2732
+ config_override :map_big_decimal_to_decimal128, true
2733
+
2734
+ let(:sales) do
2735
+ BigDecimal('0.1')
2736
+ end
2737
+
2738
+ let!(:band) do
2739
+ Band.create!(name: "Boards of Canada", sales: sales)
2740
+ end
2741
+
2742
+ let(:from_db) do
2743
+ Band.where(sales: sales).first
2744
+ end
2745
+
2746
+ it "finds the document by the big decimal value" do
2747
+ expect(from_db).to eq(band)
2748
+ end
3741
2749
  end
3742
2750
 
3743
- let(:from_db) do
3744
- Band.where(sales: sales).first
2751
+ context 'when map_big_decimal_to_decimal128 was false and is now true' do
2752
+ config_override :map_big_decimal_to_decimal128, false
2753
+
2754
+ let(:sales) do
2755
+ BigDecimal('0.1')
2756
+ end
2757
+
2758
+ let!(:band) do
2759
+ Mongoid.map_big_decimal_to_decimal128 = false
2760
+ Band.create!(name: "Boards of Canada", sales: sales)
2761
+ end
2762
+
2763
+ let(:from_db) do
2764
+ Mongoid.map_big_decimal_to_decimal128 = true
2765
+ Band.where(sales: sales.to_s).first
2766
+ end
2767
+
2768
+ it "finds the document by the big decimal value" do
2769
+ expect(from_db).to eq(band)
2770
+ end
3745
2771
  end
2772
+ end
3746
2773
 
3747
- it "finds the document by the big decimal value" do
3748
- expect(from_db).to eq(band)
2774
+ context "when querying on a big decimal from a dynamic field" do
2775
+
2776
+ context 'when map_big_decimal_to_decimal128 is false' do
2777
+ config_override :map_big_decimal_to_decimal128, false
2778
+
2779
+ let(:fans) do
2780
+ BigDecimal('139432.0002')
2781
+ end
2782
+
2783
+ let!(:band) do
2784
+ Band.create!(name: "Boards of Canada", fans: fans)
2785
+ end
2786
+
2787
+ let(:from_db) do
2788
+ Band.where(fans: fans.to_s).first
2789
+ end
2790
+
2791
+ it "finds the document by the big decimal value" do
2792
+ expect(from_db).to eq(band)
2793
+ end
2794
+ end
2795
+
2796
+ context 'when map_big_decimal_to_decimal128 is true' do
2797
+ config_override :map_big_decimal_to_decimal128, true
2798
+
2799
+ let(:fans) do
2800
+ BigDecimal('139432.0002')
2801
+ end
2802
+
2803
+ let!(:band) do
2804
+ Band.create!(name: "Boards of Canada", fans: fans)
2805
+ end
2806
+
2807
+ let(:from_db) do
2808
+ Band.where(fans: fans).first
2809
+ end
2810
+
2811
+ it "only finds the document by the string value" do
2812
+ expect(from_db).to eq(band)
2813
+ end
3749
2814
  end
3750
2815
  end
3751
2816
 
@@ -3850,6 +2915,217 @@ describe Mongoid::Criteria do
3850
2915
  expect(dup_criteria.selector).to eq({ "_id" => _id })
3851
2916
  end
3852
2917
  end
2918
+
2919
+ context "when querying an embedded field" do
2920
+ let(:criteria) { Band.where("label.name": 12345) }
2921
+
2922
+ it "mongoizes the embedded field in the selector" do
2923
+ expect(criteria.selector).to eq("label.name" => "12345")
2924
+ end
2925
+ end
2926
+
2927
+ context "when querying with a range" do
2928
+
2929
+ context "when querying an embeds_many association" do
2930
+ let(:criteria) do
2931
+ Band.where("labels" => 10..15)
2932
+ end
2933
+
2934
+ it "correctly uses elemMatch without an inner key" do
2935
+ expect(criteria.selector).to eq(
2936
+ "labels" => {
2937
+ "$elemMatch" => { "$gte" => 10, "$lte" => 15 }
2938
+ }
2939
+ )
2940
+ end
2941
+ end
2942
+
2943
+ context "when querying an element in an embeds_many association" do
2944
+ let(:criteria) do
2945
+ Band.where("labels.age" => 10..15)
2946
+ end
2947
+
2948
+ it "correctly uses elemMatch" do
2949
+ expect(criteria.selector).to eq(
2950
+ "labels" => {
2951
+ "$elemMatch" => {
2952
+ "age" => { "$gte" => 10, "$lte" => 15 }
2953
+ }
2954
+ }
2955
+ )
2956
+ end
2957
+ end
2958
+
2959
+ context "when querying a field of type array" do
2960
+ let(:criteria) do
2961
+ Band.where("genres" => 10..15)
2962
+ end
2963
+
2964
+ it "correctly uses elemMatch without an inner key" do
2965
+ expect(criteria.selector).to eq(
2966
+ "genres" => {
2967
+ "$elemMatch" => { "$gte" => 10, "$lte" => 15 }
2968
+ }
2969
+ )
2970
+ end
2971
+ end
2972
+
2973
+ context "when querying an aliased field of type array" do
2974
+ let(:criteria) do
2975
+ Person.where("array" => 10..15)
2976
+ end
2977
+
2978
+ it "correctly uses the aliased field and elemMatch" do
2979
+ expect(criteria.selector).to eq(
2980
+ "a" => {
2981
+ "$elemMatch" => { "$gte" => 10, "$lte" => 15 }
2982
+ }
2983
+ )
2984
+ end
2985
+ end
2986
+
2987
+ context "when querying a field inside an array" do
2988
+ let(:criteria) do
2989
+ Band.where("genres.age" => 10..15)
2990
+ end
2991
+
2992
+ it "correctly uses elemMatch" do
2993
+ expect(criteria.selector).to eq(
2994
+ "genres" => {
2995
+ "$elemMatch" => {
2996
+ "age" => { "$gte" => 10, "$lte" => 15 }
2997
+ }
2998
+ }
2999
+ )
3000
+ end
3001
+ end
3002
+
3003
+ context "when there are no embeds_manys or Arrays" do
3004
+ let(:criteria) do
3005
+ Band.where("fans.info.age" => 10..15)
3006
+ end
3007
+
3008
+ it "does not use elemMatch" do
3009
+ expect(criteria.selector).to eq(
3010
+ "fans.info.age" => { "$gte" => 10, "$lte" => 15 }
3011
+ )
3012
+ end
3013
+ end
3014
+
3015
+ context "when querying a nested element in an embeds_many association" do
3016
+ let(:criteria) do
3017
+ Band.where("labels.age.number" => 10..15)
3018
+ end
3019
+
3020
+ it "correctly uses elemMatch" do
3021
+ expect(criteria.selector).to eq(
3022
+ "labels" => {
3023
+ "$elemMatch" => {
3024
+ "age.number" => { "$gte" => 10, "$lte" => 15 }
3025
+ }
3026
+ }
3027
+ )
3028
+ end
3029
+ end
3030
+
3031
+ context "when querying a nested element in an Array" do
3032
+ let(:criteria) do
3033
+ Band.where("genres.name.length" => 10..15)
3034
+ end
3035
+
3036
+ it "correctly uses elemMatch" do
3037
+ expect(criteria.selector).to eq(
3038
+ "genres" => {
3039
+ "$elemMatch" => {
3040
+ "name.length" => { "$gte" => 10, "$lte" => 15 }
3041
+ }
3042
+ }
3043
+ )
3044
+ end
3045
+ end
3046
+
3047
+ context "when querying a nested element in a nested embeds_many association" do
3048
+ context "when the outer association is an embeds_many" do
3049
+ let(:criteria) do
3050
+ Band.where("records.tracks.name.length" => 10..15)
3051
+ end
3052
+
3053
+ it "correctly uses elemMatch" do
3054
+ expect(criteria.selector).to eq(
3055
+ "records.tracks" => {
3056
+ "$elemMatch" => {
3057
+ "name.length" => { "$gte" => 10, "$lte" => 15 }
3058
+ }
3059
+ }
3060
+ )
3061
+ end
3062
+ end
3063
+
3064
+ context "when the outer association is an embeds_one" do
3065
+ let(:criteria) do
3066
+ Person.where("name.translations.language.length" => 10..15)
3067
+ end
3068
+
3069
+ it "correctly uses elemMatch" do
3070
+ expect(criteria.selector).to eq(
3071
+ "name.translations" => {
3072
+ "$elemMatch" => {
3073
+ "language.length" => { "$gte" => 10, "$lte" => 15 }
3074
+ }
3075
+ }
3076
+ )
3077
+ end
3078
+ end
3079
+ end
3080
+
3081
+ context "when querying a deeply nested array" do
3082
+ let(:criteria) do
3083
+ Person.where("addresses.code.deepest.array.element.item" => 10..15)
3084
+ end
3085
+
3086
+ it "correctly uses elemMatch" do
3087
+ expect(criteria.selector).to eq(
3088
+ "addresses.code.deepest.array" => {
3089
+ "$elemMatch" => {
3090
+ "element.item" => { "$gte" => 10, "$lte" => 15 }
3091
+ }
3092
+ }
3093
+ )
3094
+ end
3095
+ end
3096
+
3097
+ context "when there are multiple conditions" do
3098
+ let(:criteria) do
3099
+ Band.where("$or" => [{"labels.age" => 10..15}, {labels: 8}])
3100
+ end
3101
+
3102
+ it "correctly combines the conditions" do
3103
+ expect(criteria.selector).to eq("$or" => [
3104
+ { "labels" => {
3105
+ "$elemMatch" => {
3106
+ "age" => { "$gte" => 10, "$lte" => 15 }
3107
+ } } },
3108
+ { "labels" => 8 }
3109
+ ])
3110
+ end
3111
+ end
3112
+
3113
+ context "when the association is aliased" do
3114
+ let(:criteria) do
3115
+ Person.where("passport.passport_pages.num_stamps" => 10..18)
3116
+ end
3117
+
3118
+ it "correctly uses the aliased association" do
3119
+ expect(criteria.selector).to eq(
3120
+ "pass.passport_pages" => {
3121
+ "$elemMatch" => {
3122
+ "num_stamps" => { "$gte" => 10, "$lte" => 18 }
3123
+ }
3124
+ }
3125
+ )
3126
+ end
3127
+ end
3128
+ end
3853
3129
  end
3854
3130
 
3855
3131
  describe "#for_js" do