mongoid 7.5.3 → 8.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (417) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +3 -3
  4. data/README.md +6 -6
  5. data/Rakefile +25 -0
  6. data/lib/config/locales/en.yml +92 -43
  7. data/lib/mongoid/association/accessors.rb +40 -11
  8. data/lib/mongoid/association/bindable.rb +50 -2
  9. data/lib/mongoid/association/builders.rb +5 -3
  10. data/lib/mongoid/association/constrainable.rb +0 -1
  11. data/lib/mongoid/association/eager_loadable.rb +29 -7
  12. data/lib/mongoid/association/embedded/batchable.rb +34 -11
  13. data/lib/mongoid/association/embedded/cyclic.rb +1 -1
  14. data/lib/mongoid/association/embedded/embedded_in/binding.rb +24 -2
  15. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +2 -2
  16. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +4 -3
  17. data/lib/mongoid/association/embedded/embedded_in.rb +3 -2
  18. data/lib/mongoid/association/embedded/embeds_many/binding.rb +1 -0
  19. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +4 -3
  20. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +69 -45
  21. data/lib/mongoid/association/embedded/embeds_many.rb +2 -2
  22. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +19 -5
  23. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +24 -5
  24. data/lib/mongoid/association/embedded/embeds_one.rb +3 -3
  25. data/lib/mongoid/association/macros.rb +8 -1
  26. data/lib/mongoid/association/many.rb +11 -7
  27. data/lib/mongoid/association/nested/many.rb +5 -4
  28. data/lib/mongoid/association/nested/nested_buildable.rb +4 -4
  29. data/lib/mongoid/association/nested/one.rb +45 -7
  30. data/lib/mongoid/association/one.rb +2 -2
  31. data/lib/mongoid/association/options.rb +9 -9
  32. data/lib/mongoid/association/proxy.rb +15 -4
  33. data/lib/mongoid/association/referenced/auto_save.rb +4 -3
  34. data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
  35. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
  36. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +5 -6
  37. data/lib/mongoid/association/referenced/belongs_to.rb +2 -2
  38. data/lib/mongoid/association/referenced/counter_cache.rb +10 -10
  39. data/lib/mongoid/association/referenced/eager.rb +2 -2
  40. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +70 -13
  41. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +6 -3
  42. data/lib/mongoid/association/referenced/has_many/enumerable.rb +22 -30
  43. data/lib/mongoid/association/referenced/has_many/proxy.rb +29 -19
  44. data/lib/mongoid/association/referenced/has_many.rb +3 -3
  45. data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -1
  46. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +5 -5
  47. data/lib/mongoid/association/referenced/has_one/proxy.rb +9 -12
  48. data/lib/mongoid/association/referenced/has_one.rb +3 -3
  49. data/lib/mongoid/association/referenced/syncable.rb +4 -4
  50. data/lib/mongoid/association/reflections.rb +4 -4
  51. data/lib/mongoid/association/relatable.rb +44 -10
  52. data/lib/mongoid/association.rb +5 -5
  53. data/lib/mongoid/atomic/modifiers.rb +2 -2
  54. data/lib/mongoid/atomic.rb +7 -0
  55. data/lib/mongoid/attributes/dynamic.rb +4 -4
  56. data/lib/mongoid/attributes/nested.rb +6 -6
  57. data/lib/mongoid/attributes/processing.rb +37 -6
  58. data/lib/mongoid/attributes/projector.rb +2 -2
  59. data/lib/mongoid/attributes/readonly.rb +3 -3
  60. data/lib/mongoid/attributes.rb +51 -42
  61. data/lib/mongoid/changeable.rb +147 -14
  62. data/lib/mongoid/clients/options.rb +5 -1
  63. data/lib/mongoid/clients/sessions.rb +2 -14
  64. data/lib/mongoid/clients/storage_options.rb +2 -5
  65. data/lib/mongoid/clients/validators/storage.rb +3 -15
  66. data/lib/mongoid/collection_configurable.rb +58 -0
  67. data/lib/mongoid/composable.rb +2 -0
  68. data/lib/mongoid/config/defaults.rb +60 -0
  69. data/lib/mongoid/config/options.rb +3 -0
  70. data/lib/mongoid/config/validators/async_query_executor.rb +24 -0
  71. data/lib/mongoid/config/validators/client.rb +6 -6
  72. data/lib/mongoid/config/validators.rb +1 -0
  73. data/lib/mongoid/config.rb +140 -18
  74. data/lib/mongoid/contextual/aggregable/memory.rb +24 -16
  75. data/lib/mongoid/contextual/aggregable/mongo.rb +5 -5
  76. data/lib/mongoid/contextual/aggregable/none.rb +1 -1
  77. data/lib/mongoid/contextual/atomic.rb +1 -1
  78. data/lib/mongoid/contextual/geo_near.rb +7 -7
  79. data/lib/mongoid/contextual/map_reduce.rb +2 -2
  80. data/lib/mongoid/contextual/memory.rb +285 -58
  81. data/lib/mongoid/contextual/mongo/documents_loader.rb +177 -0
  82. data/lib/mongoid/contextual/mongo.rb +517 -346
  83. data/lib/mongoid/contextual/none.rb +193 -20
  84. data/lib/mongoid/contextual/queryable.rb +1 -1
  85. data/lib/mongoid/contextual.rb +14 -2
  86. data/lib/mongoid/copyable.rb +32 -8
  87. data/lib/mongoid/criteria/findable.rb +8 -5
  88. data/lib/mongoid/criteria/includable.rb +27 -22
  89. data/lib/mongoid/criteria/marshalable.rb +10 -2
  90. data/lib/mongoid/criteria/permission.rb +1 -1
  91. data/lib/mongoid/criteria/queryable/aggregable.rb +2 -2
  92. data/lib/mongoid/criteria/queryable/extensions/array.rb +3 -16
  93. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -4
  94. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +2 -2
  95. data/lib/mongoid/criteria/queryable/extensions/date.rb +6 -1
  96. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +6 -1
  97. data/lib/mongoid/criteria/queryable/extensions/hash.rb +1 -17
  98. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -9
  99. data/lib/mongoid/criteria/queryable/extensions/object.rb +2 -1
  100. data/lib/mongoid/criteria/queryable/extensions/range.rb +13 -5
  101. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
  102. data/lib/mongoid/criteria/queryable/extensions/set.rb +1 -1
  103. data/lib/mongoid/criteria/queryable/extensions/string.rb +4 -14
  104. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +4 -12
  105. data/lib/mongoid/criteria/queryable/extensions/time.rb +6 -1
  106. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +6 -1
  107. data/lib/mongoid/criteria/queryable/key.rb +4 -4
  108. data/lib/mongoid/criteria/queryable/mergeable.rb +1 -1
  109. data/lib/mongoid/criteria/queryable/optional.rb +11 -17
  110. data/lib/mongoid/criteria/queryable/options.rb +2 -2
  111. data/lib/mongoid/criteria/queryable/pipeline.rb +1 -1
  112. data/lib/mongoid/criteria/queryable/selectable.rb +47 -38
  113. data/lib/mongoid/criteria/queryable/selector.rb +93 -8
  114. data/lib/mongoid/criteria/queryable/smash.rb +40 -7
  115. data/lib/mongoid/criteria/queryable/storable.rb +1 -1
  116. data/lib/mongoid/criteria/queryable.rb +12 -7
  117. data/lib/mongoid/criteria/scopable.rb +2 -2
  118. data/lib/mongoid/criteria/translator.rb +45 -0
  119. data/lib/mongoid/criteria.rb +20 -40
  120. data/lib/mongoid/deprecable.rb +36 -0
  121. data/lib/mongoid/deprecation.rb +25 -0
  122. data/lib/mongoid/document.rb +127 -35
  123. data/lib/mongoid/equality.rb +8 -8
  124. data/lib/mongoid/errors/create_collection_failure.rb +33 -0
  125. data/lib/mongoid/errors/document_not_found.rb +10 -6
  126. data/lib/mongoid/errors/drop_collection_failure.rb +27 -0
  127. data/lib/mongoid/errors/immutable_attribute.rb +26 -0
  128. data/lib/mongoid/errors/invalid_async_query_executor.rb +25 -0
  129. data/lib/mongoid/errors/invalid_config_option.rb +1 -1
  130. data/lib/mongoid/errors/invalid_dependent_strategy.rb +1 -1
  131. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
  132. data/lib/mongoid/errors/invalid_field.rb +6 -2
  133. data/lib/mongoid/errors/invalid_field_type.rb +26 -0
  134. data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +22 -0
  135. data/lib/mongoid/errors/invalid_relation.rb +1 -1
  136. data/lib/mongoid/errors/invalid_relation_option.rb +1 -1
  137. data/lib/mongoid/errors/invalid_session_use.rb +1 -1
  138. data/lib/mongoid/errors/invalid_storage_options.rb +1 -1
  139. data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
  140. data/lib/mongoid/errors/mongoid_error.rb +3 -3
  141. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +1 -1
  142. data/lib/mongoid/errors/no_client_database.rb +1 -1
  143. data/lib/mongoid/errors/no_client_hosts.rb +1 -1
  144. data/lib/mongoid/errors/readonly_attribute.rb +1 -1
  145. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
  146. data/lib/mongoid/errors/unknown_attribute.rb +1 -1
  147. data/lib/mongoid/errors.rb +6 -3
  148. data/lib/mongoid/extensions/array.rb +9 -7
  149. data/lib/mongoid/extensions/big_decimal.rb +33 -10
  150. data/lib/mongoid/extensions/binary.rb +42 -0
  151. data/lib/mongoid/extensions/boolean.rb +8 -2
  152. data/lib/mongoid/extensions/date.rb +26 -20
  153. data/lib/mongoid/extensions/date_time.rb +1 -1
  154. data/lib/mongoid/extensions/false_class.rb +1 -1
  155. data/lib/mongoid/extensions/float.rb +7 -4
  156. data/lib/mongoid/extensions/hash.rb +19 -8
  157. data/lib/mongoid/extensions/integer.rb +7 -4
  158. data/lib/mongoid/extensions/module.rb +1 -1
  159. data/lib/mongoid/extensions/object.rb +10 -8
  160. data/lib/mongoid/extensions/range.rb +41 -10
  161. data/lib/mongoid/extensions/regexp.rb +11 -4
  162. data/lib/mongoid/extensions/set.rb +11 -4
  163. data/lib/mongoid/extensions/string.rb +11 -22
  164. data/lib/mongoid/extensions/symbol.rb +4 -15
  165. data/lib/mongoid/extensions/time.rb +29 -16
  166. data/lib/mongoid/extensions/time_with_zone.rb +1 -2
  167. data/lib/mongoid/extensions/true_class.rb +1 -1
  168. data/lib/mongoid/extensions.rb +1 -0
  169. data/lib/mongoid/factory.rb +55 -7
  170. data/lib/mongoid/fields/foreign_key.rb +11 -4
  171. data/lib/mongoid/fields/localized.rb +19 -4
  172. data/lib/mongoid/fields/standard.rb +17 -7
  173. data/lib/mongoid/fields/validators/macro.rb +3 -9
  174. data/lib/mongoid/fields.rb +129 -20
  175. data/lib/mongoid/findable.rb +54 -24
  176. data/lib/mongoid/indexable/specification.rb +2 -2
  177. data/lib/mongoid/indexable/validators/options.rb +6 -2
  178. data/lib/mongoid/interceptable.rb +76 -15
  179. data/lib/mongoid/matchable.rb +1 -1
  180. data/lib/mongoid/matcher/eq_impl.rb +1 -1
  181. data/lib/mongoid/matcher/type.rb +1 -1
  182. data/lib/mongoid/matcher.rb +33 -13
  183. data/lib/mongoid/persistable/creatable.rb +19 -9
  184. data/lib/mongoid/persistable/deletable.rb +2 -2
  185. data/lib/mongoid/persistable/destroyable.rb +1 -1
  186. data/lib/mongoid/persistable/savable.rb +14 -2
  187. data/lib/mongoid/persistable/unsettable.rb +2 -2
  188. data/lib/mongoid/persistable/updatable.rb +69 -12
  189. data/lib/mongoid/persistable/upsertable.rb +21 -2
  190. data/lib/mongoid/persistable.rb +6 -3
  191. data/lib/mongoid/persistence_context.rb +6 -4
  192. data/lib/mongoid/query_cache.rb +13 -261
  193. data/lib/mongoid/railties/controller_runtime.rb +1 -1
  194. data/lib/mongoid/railties/database.rake +7 -2
  195. data/lib/mongoid/reloadable.rb +10 -8
  196. data/lib/mongoid/scopable.rb +15 -13
  197. data/lib/mongoid/selectable.rb +1 -2
  198. data/lib/mongoid/serializable.rb +10 -6
  199. data/lib/mongoid/stateful.rb +57 -10
  200. data/lib/mongoid/tasks/database.rake +12 -0
  201. data/lib/mongoid/tasks/database.rb +20 -2
  202. data/lib/mongoid/threaded/lifecycle.rb +5 -5
  203. data/lib/mongoid/threaded.rb +42 -12
  204. data/lib/mongoid/timestamps/created.rb +1 -1
  205. data/lib/mongoid/timestamps/updated.rb +2 -2
  206. data/lib/mongoid/touchable.rb +2 -3
  207. data/lib/mongoid/traversable.rb +5 -4
  208. data/lib/mongoid/utils.rb +22 -0
  209. data/lib/mongoid/validatable/localizable.rb +1 -1
  210. data/lib/mongoid/validatable/macros.rb +5 -7
  211. data/lib/mongoid/validatable/presence.rb +2 -2
  212. data/lib/mongoid/validatable/uniqueness.rb +9 -8
  213. data/lib/mongoid/validatable.rb +9 -6
  214. data/lib/mongoid/version.rb +1 -1
  215. data/lib/mongoid/warnings.rb +19 -4
  216. data/lib/mongoid.rb +17 -3
  217. data/spec/config/mongoid.yml +16 -0
  218. data/spec/integration/app_spec.rb +10 -14
  219. data/spec/integration/associations/belongs_to_spec.rb +18 -0
  220. data/spec/integration/associations/embedded_spec.rb +15 -0
  221. data/spec/integration/associations/embeds_many_spec.rb +15 -2
  222. data/spec/integration/associations/embeds_one_spec.rb +18 -0
  223. data/spec/integration/associations/foreign_key_spec.rb +9 -0
  224. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
  225. data/spec/integration/associations/has_one_spec.rb +97 -1
  226. data/spec/integration/associations/scope_option_spec.rb +1 -1
  227. data/spec/integration/callbacks_models.rb +132 -1
  228. data/spec/integration/callbacks_spec.rb +360 -4
  229. data/spec/integration/criteria/range_spec.rb +95 -1
  230. data/spec/integration/discriminator_key_spec.rb +118 -80
  231. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  232. data/spec/integration/i18n_fallbacks_spec.rb +3 -32
  233. data/spec/integration/matcher_examples_spec.rb +20 -13
  234. data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
  235. data/spec/integration/matcher_operator_spec.rb +3 -5
  236. data/spec/integration/persistence/range_field_spec.rb +350 -0
  237. data/spec/mongoid/association/counter_cache_spec.rb +1 -1
  238. data/spec/mongoid/association/depending_spec.rb +9 -9
  239. data/spec/mongoid/association/eager_spec.rb +2 -1
  240. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
  241. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
  242. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +96 -9
  243. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
  244. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +255 -65
  245. data/spec/mongoid/association/embedded/embeds_many_models.rb +37 -0
  246. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +12 -0
  247. data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
  248. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
  249. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +15 -2
  250. data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
  251. data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
  252. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
  253. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
  254. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +15 -0
  255. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  256. data/spec/mongoid/association/referenced/belongs_to_spec.rb +4 -20
  257. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +186 -229
  258. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
  259. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
  260. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
  261. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +2 -56
  262. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +173 -177
  263. data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
  264. data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
  265. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
  266. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
  267. data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
  268. data/spec/mongoid/association/syncable_spec.rb +15 -1
  269. data/spec/mongoid/atomic/paths_spec.rb +0 -14
  270. data/spec/mongoid/attributes/nested_spec.rb +80 -11
  271. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  272. data/spec/mongoid/attributes/projector_spec.rb +1 -5
  273. data/spec/mongoid/attributes_spec.rb +510 -33
  274. data/spec/mongoid/changeable_spec.rb +429 -37
  275. data/spec/mongoid/clients/factory_spec.rb +23 -30
  276. data/spec/mongoid/clients/sessions_spec.rb +0 -38
  277. data/spec/mongoid/clients_spec.rb +149 -15
  278. data/spec/mongoid/collection_configurable_spec.rb +158 -0
  279. data/spec/mongoid/config/defaults_spec.rb +160 -0
  280. data/spec/mongoid/config_spec.rb +214 -31
  281. data/spec/mongoid/contextual/aggregable/memory_spec.rb +396 -158
  282. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  283. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  284. data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
  285. data/spec/mongoid/contextual/memory_spec.rb +850 -88
  286. data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +187 -0
  287. data/spec/mongoid/contextual/mongo_spec.rb +1572 -435
  288. data/spec/mongoid/contextual/none_spec.rb +60 -21
  289. data/spec/mongoid/copyable_spec.rb +453 -11
  290. data/spec/mongoid/criteria/findable_spec.rb +86 -210
  291. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  292. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  293. data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
  294. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
  295. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
  296. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
  297. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
  298. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
  299. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
  300. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +4 -69
  301. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +0 -59
  302. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
  303. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
  304. data/spec/mongoid/criteria/queryable/optional_spec.rb +15 -484
  305. data/spec/mongoid/criteria/queryable/options_spec.rb +1 -1
  306. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +469 -0
  307. data/spec/mongoid/criteria/queryable/selectable_spec.rb +78 -86
  308. data/spec/mongoid/criteria/queryable/selector_spec.rb +90 -5
  309. data/spec/mongoid/criteria/queryable/storable_spec.rb +72 -0
  310. data/spec/mongoid/criteria/translator_spec.rb +132 -0
  311. data/spec/mongoid/criteria_projection_spec.rb +1 -5
  312. data/spec/mongoid/criteria_spec.rb +469 -1205
  313. data/spec/mongoid/document_fields_spec.rb +173 -24
  314. data/spec/mongoid/document_spec.rb +32 -41
  315. data/spec/mongoid/errors/document_not_found_spec.rb +29 -2
  316. data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
  317. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  318. data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
  319. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  320. data/spec/mongoid/errors/readonly_document_spec.rb +2 -2
  321. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
  322. data/spec/mongoid/extensions/array_spec.rb +16 -2
  323. data/spec/mongoid/extensions/big_decimal_spec.rb +712 -212
  324. data/spec/mongoid/extensions/binary_spec.rb +44 -9
  325. data/spec/mongoid/extensions/boolean_spec.rb +68 -82
  326. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
  327. data/spec/mongoid/extensions/date_spec.rb +71 -1
  328. data/spec/mongoid/extensions/date_time_spec.rb +15 -9
  329. data/spec/mongoid/extensions/float_spec.rb +53 -74
  330. data/spec/mongoid/extensions/hash_spec.rb +33 -3
  331. data/spec/mongoid/extensions/integer_spec.rb +50 -64
  332. data/spec/mongoid/extensions/range_spec.rb +255 -54
  333. data/spec/mongoid/extensions/regexp_spec.rb +58 -33
  334. data/spec/mongoid/extensions/set_spec.rb +106 -0
  335. data/spec/mongoid/extensions/string_spec.rb +53 -25
  336. data/spec/mongoid/extensions/symbol_spec.rb +18 -25
  337. data/spec/mongoid/extensions/time_spec.rb +639 -106
  338. data/spec/mongoid/extensions/time_with_zone_spec.rb +24 -83
  339. data/spec/mongoid/factory_spec.rb +61 -1
  340. data/spec/mongoid/fields/localized_spec.rb +80 -37
  341. data/spec/mongoid/fields_spec.rb +500 -84
  342. data/spec/mongoid/findable_spec.rb +450 -58
  343. data/spec/mongoid/indexable/specification_spec.rb +2 -2
  344. data/spec/mongoid/indexable_spec.rb +55 -30
  345. data/spec/mongoid/interceptable_spec.rb +599 -8
  346. data/spec/mongoid/interceptable_spec_models.rb +235 -4
  347. data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
  348. data/spec/mongoid/mongoizable_spec.rb +285 -0
  349. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  350. data/spec/mongoid/persistable/deletable_spec.rb +28 -8
  351. data/spec/mongoid/persistable/destroyable_spec.rb +28 -8
  352. data/spec/mongoid/persistable/incrementable_spec.rb +37 -0
  353. data/spec/mongoid/persistable/logical_spec.rb +37 -0
  354. data/spec/mongoid/persistable/poppable_spec.rb +36 -0
  355. data/spec/mongoid/persistable/pullable_spec.rb +72 -0
  356. data/spec/mongoid/persistable/pushable_spec.rb +72 -0
  357. data/spec/mongoid/persistable/renamable_spec.rb +36 -0
  358. data/spec/mongoid/persistable/savable_spec.rb +96 -0
  359. data/spec/mongoid/persistable/settable_spec.rb +37 -0
  360. data/spec/mongoid/persistable/unsettable_spec.rb +36 -0
  361. data/spec/mongoid/persistable/updatable_spec.rb +20 -28
  362. data/spec/mongoid/persistable/upsertable_spec.rb +89 -1
  363. data/spec/mongoid/persistence_context_spec.rb +31 -57
  364. data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
  365. data/spec/mongoid/query_cache_spec.rb +56 -215
  366. data/spec/mongoid/reloadable_spec.rb +83 -6
  367. data/spec/mongoid/scopable_spec.rb +91 -1
  368. data/spec/mongoid/serializable_spec.rb +9 -30
  369. data/spec/mongoid/shardable_spec.rb +4 -4
  370. data/spec/mongoid/stateful_spec.rb +150 -8
  371. data/spec/mongoid/tasks/database_rake_spec.rb +74 -0
  372. data/spec/mongoid/tasks/database_spec.rb +127 -0
  373. data/spec/mongoid/timestamps_spec.rb +392 -4
  374. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  375. data/spec/mongoid/touchable_spec.rb +390 -2
  376. data/spec/mongoid/touchable_spec_models.rb +14 -8
  377. data/spec/mongoid/traversable_spec.rb +13 -35
  378. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  379. data/spec/mongoid/validatable/uniqueness_spec.rb +58 -31
  380. data/spec/mongoid/warnings_spec.rb +35 -0
  381. data/spec/mongoid_spec.rb +34 -16
  382. data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
  383. data/spec/rails/mongoid_spec.rb +4 -16
  384. data/spec/spec_helper.rb +5 -0
  385. data/spec/support/constraints.rb +24 -0
  386. data/spec/support/immutable_ids.rb +118 -0
  387. data/spec/support/macros.rb +78 -0
  388. data/spec/support/models/artist.rb +0 -1
  389. data/spec/support/models/augmentation.rb +12 -0
  390. data/spec/support/models/band.rb +4 -0
  391. data/spec/support/models/book.rb +1 -0
  392. data/spec/support/models/building.rb +2 -0
  393. data/spec/support/models/catalog.rb +24 -0
  394. data/spec/support/models/circus.rb +3 -0
  395. data/spec/support/models/cover.rb +10 -0
  396. data/spec/support/models/fanatic.rb +8 -0
  397. data/spec/support/models/implant.rb +9 -0
  398. data/spec/support/models/label.rb +2 -0
  399. data/spec/support/models/passport.rb +9 -0
  400. data/spec/support/models/person.rb +2 -0
  401. data/spec/support/models/player.rb +2 -0
  402. data/spec/support/models/powerup.rb +12 -0
  403. data/spec/support/models/product.rb +1 -0
  404. data/spec/support/models/purse.rb +9 -0
  405. data/spec/support/models/registry.rb +1 -0
  406. data/spec/support/models/school.rb +14 -0
  407. data/spec/support/models/shield.rb +18 -0
  408. data/spec/support/models/student.rb +14 -0
  409. data/spec/support/models/weapon.rb +12 -0
  410. data.tar.gz.sig +0 -0
  411. metadata +718 -641
  412. metadata.gz.sig +0 -0
  413. data/lib/mongoid/errors/eager_load.rb +0 -23
  414. data/lib/mongoid/errors/invalid_value.rb +0 -17
  415. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -60
  416. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -60
  417. 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
@@ -1172,1173 +1165,65 @@ describe Mongoid::Criteria do
1172
1165
  end
1173
1166
  end
1174
1167
 
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
2270
-
2271
- context "when including multiples in the same criteria" do
2272
-
2273
- let!(:post_one) do
2274
- person.posts.create!(title: "one")
2275
- end
2276
-
2277
- let!(:post_two) do
2278
- person.posts.create!(title: "two")
2279
- end
2280
-
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
@@ -3068,6 +1953,7 @@ describe Mongoid::Criteria do
3068
1953
  end
3069
1954
 
3070
1955
  context 'when plucking a localized field' do
1956
+ with_default_i18n_configs
3071
1957
 
3072
1958
  before do
3073
1959
  I18n.locale = :en
@@ -3077,10 +1963,6 @@ describe Mongoid::Criteria do
3077
1963
  d.save!
3078
1964
  end
3079
1965
 
3080
- after do
3081
- I18n.locale = :en
3082
- end
3083
-
3084
1966
  context 'when plucking the entire field' do
3085
1967
  let(:plucked) do
3086
1968
  Dictionary.all.pluck(:description)
@@ -3176,15 +2058,8 @@ describe Mongoid::Criteria do
3176
2058
  context 'when fallbacks are enabled with a locale list' do
3177
2059
  require_fallbacks
3178
2060
 
3179
- around(:all) do |example|
3180
- prev_fallbacks = I18n.fallbacks.dup
2061
+ before do
3181
2062
  I18n.fallbacks[:he] = [ :en ]
3182
- example.run
3183
- I18n.fallbacks = prev_fallbacks
3184
- end
3185
-
3186
- after do
3187
- I18n.locale = :en
3188
2063
  end
3189
2064
 
3190
2065
  let(:plucked) do
@@ -3212,6 +2087,8 @@ describe Mongoid::Criteria do
3212
2087
  end
3213
2088
 
3214
2089
  context "when the localized field is embedded" do
2090
+ with_default_i18n_configs
2091
+
3215
2092
  before do
3216
2093
  p = Passport.new
3217
2094
  I18n.locale = :en
@@ -3222,10 +2099,6 @@ describe Mongoid::Criteria do
3222
2099
  Person.create!(passport: p, employer_id: 12345)
3223
2100
  end
3224
2101
 
3225
- after do
3226
- I18n.locale = :en
3227
- end
3228
-
3229
2102
  let(:plucked) do
3230
2103
  Person.where(employer_id: 12345).pluck("pass.name").first
3231
2104
  end
@@ -3281,18 +2154,45 @@ describe Mongoid::Criteria do
3281
2154
  context "when legacy_pluck_distinct is set" do
3282
2155
  config_override :legacy_pluck_distinct, true
3283
2156
 
3284
- it "does not demongoize the field" do
3285
- expect(plucked.first).to be_a(String)
3286
- expect(plucked.first).to eq("1E2")
2157
+ context 'when value is stored as string' do
2158
+ config_override :map_big_decimal_to_decimal128, false
2159
+
2160
+ it "does not demongoize the field" do
2161
+ expect(plucked.first).to be_a(String)
2162
+ expect(plucked.first).to eq("1E2")
2163
+ end
2164
+ end
2165
+
2166
+ context 'when value is stored as decimal128' do
2167
+ config_override :map_big_decimal_to_decimal128, true
2168
+ max_bson_version '4.99.99'
2169
+
2170
+ it "does not demongoize the field" do
2171
+ expect(plucked.first).to be_a(BSON::Decimal128)
2172
+ expect(plucked.first).to eq(BSON::Decimal128.new("1E2"))
2173
+ end
3287
2174
  end
3288
2175
  end
3289
2176
 
3290
2177
  context "when legacy_pluck_distinct is not set" do
3291
2178
  config_override :legacy_pluck_distinct, false
3292
2179
 
3293
- it "demongoizes the field" do
3294
- expect(plucked.first).to be_a(BigDecimal)
3295
- expect(plucked.first).to eq(BigDecimal("1E2"))
2180
+ context 'when value is stored as string' do
2181
+ config_override :map_big_decimal_to_decimal128, false
2182
+
2183
+ it "demongoizes the field" do
2184
+ expect(plucked.first).to be_a(BigDecimal)
2185
+ expect(plucked.first).to eq(BigDecimal("1E2"))
2186
+ end
2187
+ end
2188
+
2189
+ context 'when value is stored as decimal128' do
2190
+ config_override :map_big_decimal_to_decimal128, true
2191
+
2192
+ it "demongoizes the field" do
2193
+ expect(plucked.first).to be_a(BigDecimal)
2194
+ expect(plucked.first).to eq(BigDecimal("1E2"))
2195
+ end
3296
2196
  end
3297
2197
  end
3298
2198
  end
@@ -3305,9 +2205,11 @@ describe Mongoid::Criteria do
3305
2205
 
3306
2206
  context "when legacy_pluck_distinct is set" do
3307
2207
  config_override :legacy_pluck_distinct, true
2208
+ config_override :map_big_decimal_to_decimal128, true
2209
+ max_bson_version '4.99.99'
3308
2210
 
3309
2211
  it "returns a hash with a non-demongoized field" do
3310
- expect(plucked.first).to eq({ 'sales' => "1E2" })
2212
+ expect(plucked.first).to eq({ 'sales' => BSON::Decimal128.new('1E+2') })
3311
2213
  end
3312
2214
  end
3313
2215
 
@@ -3315,7 +2217,7 @@ describe Mongoid::Criteria do
3315
2217
  config_override :legacy_pluck_distinct, false
3316
2218
 
3317
2219
  it "demongoizes the field" do
3318
- expect(plucked.first).to eq(BigDecimal("1E2"))
2220
+ expect(plucked).to eq([ BigDecimal("1E2") ])
3319
2221
  end
3320
2222
  end
3321
2223
  end
@@ -3328,9 +2230,11 @@ describe Mongoid::Criteria do
3328
2230
 
3329
2231
  context "when legacy_pluck_distinct is set" do
3330
2232
  config_override :legacy_pluck_distinct, true
2233
+ config_override :map_big_decimal_to_decimal128, true
2234
+ max_bson_version '4.99.99'
3331
2235
 
3332
2236
  it "returns a hash with a non-demongoized field" do
3333
- expect(plucked.first).to eq([{ 'sales' => "1E2" }])
2237
+ expect(plucked.first).to eq([{ 'sales' => BSON::Decimal128.new('1E+2') }])
3334
2238
  end
3335
2239
  end
3336
2240
 
@@ -3338,7 +2242,7 @@ describe Mongoid::Criteria do
3338
2242
  config_override :legacy_pluck_distinct, false
3339
2243
 
3340
2244
  it "demongoizes the field" do
3341
- expect(plucked.first).to eq([BigDecimal("1E2")])
2245
+ expect(plucked.first).to eq([ BigDecimal("1E2") ])
3342
2246
  end
3343
2247
  end
3344
2248
  end
@@ -3365,6 +2269,66 @@ describe Mongoid::Criteria do
3365
2269
  end
3366
2270
  end
3367
2271
  end
2272
+
2273
+ context "when tallying deeply nested arrays/embedded associations" do
2274
+
2275
+ before do
2276
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
2277
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 2 } } ]))) ])
2278
+ Person.create!(addresses: [ Address.new(code: Code.new(deepest: Deepest.new(array: [ { y: { z: 1 } }, { y: { z: 3 } } ]))) ])
2279
+ end
2280
+
2281
+ let(:plucked) do
2282
+ Person.pluck("addresses.code.deepest.array.y.z")
2283
+ end
2284
+
2285
+ it "returns the correct hash" do
2286
+ expect(plucked).to eq([
2287
+ [ [ 1, 2 ] ], [ [ 1, 2 ] ], [ [ 1, 3 ] ]
2288
+ ])
2289
+ end
2290
+ end
2291
+ end
2292
+
2293
+ describe "#pick" do
2294
+
2295
+ let!(:depeche) do
2296
+ Band.create!(name: "Depeche Mode", likes: 3)
2297
+ end
2298
+
2299
+ let!(:tool) do
2300
+ Band.create!(name: "Tool", likes: 3)
2301
+ end
2302
+
2303
+ context "when picking a field" do
2304
+
2305
+ let(:criteria) do
2306
+ Band.all
2307
+ end
2308
+
2309
+ let(:picked) do
2310
+ criteria.pick(:name)
2311
+ end
2312
+
2313
+ it "returns one element" do
2314
+ expect(picked).to eq("Depeche Mode")
2315
+ end
2316
+ end
2317
+
2318
+ context "when picking multiple fields" do
2319
+
2320
+ let(:criteria) do
2321
+ Band.all
2322
+ end
2323
+
2324
+ let(:picked) do
2325
+ criteria.pick(:name, :likes)
2326
+ end
2327
+
2328
+ it "returns an array" do
2329
+ expect(picked).to eq([ "Depeche Mode", 3 ])
2330
+ end
2331
+ end
3368
2332
  end
3369
2333
 
3370
2334
  describe "#respond_to?" do
@@ -3740,20 +2704,109 @@ describe Mongoid::Criteria do
3740
2704
 
3741
2705
  context "when querying on a big decimal" do
3742
2706
 
3743
- let(:sales) do
3744
- BigDecimal('0.1')
2707
+ context 'when map_big_decimal_to_decimal128 is false' do
2708
+ config_override :map_big_decimal_to_decimal128, false
2709
+
2710
+ let(:sales) do
2711
+ BigDecimal('0.1')
2712
+ end
2713
+
2714
+ let!(:band) do
2715
+ Band.create!(name: "Boards of Canada", sales: sales)
2716
+ end
2717
+
2718
+ let(:from_db) do
2719
+ Band.where(sales: sales).first
2720
+ end
2721
+
2722
+ it "finds the document by the big decimal value" do
2723
+ expect(from_db).to eq(band)
2724
+ end
3745
2725
  end
3746
2726
 
3747
- let!(:band) do
3748
- Band.create!(name: "Boards of Canada", sales: sales)
2727
+ context 'when map_big_decimal_to_decimal128 is true' do
2728
+ config_override :map_big_decimal_to_decimal128, true
2729
+
2730
+ let(:sales) do
2731
+ BigDecimal('0.1')
2732
+ end
2733
+
2734
+ let!(:band) do
2735
+ Band.create!(name: "Boards of Canada", sales: sales)
2736
+ end
2737
+
2738
+ let(:from_db) do
2739
+ Band.where(sales: sales).first
2740
+ end
2741
+
2742
+ it "finds the document by the big decimal value" do
2743
+ expect(from_db).to eq(band)
2744
+ end
3749
2745
  end
3750
2746
 
3751
- let(:from_db) do
3752
- Band.where(sales: sales).first
2747
+ context 'when map_big_decimal_to_decimal128 was false and is now true' do
2748
+ config_override :map_big_decimal_to_decimal128, false
2749
+
2750
+ let(:sales) do
2751
+ BigDecimal('0.1')
2752
+ end
2753
+
2754
+ let!(:band) do
2755
+ Mongoid.map_big_decimal_to_decimal128 = false
2756
+ Band.create!(name: "Boards of Canada", sales: sales)
2757
+ end
2758
+
2759
+ let(:from_db) do
2760
+ Mongoid.map_big_decimal_to_decimal128 = true
2761
+ Band.where(sales: sales.to_s).first
2762
+ end
2763
+
2764
+ it "finds the document by the big decimal value" do
2765
+ expect(from_db).to eq(band)
2766
+ end
3753
2767
  end
2768
+ end
3754
2769
 
3755
- it "finds the document by the big decimal value" do
3756
- expect(from_db).to eq(band)
2770
+ context "when querying on a big decimal from a dynamic field" do
2771
+
2772
+ context 'when map_big_decimal_to_decimal128 is false' do
2773
+ config_override :map_big_decimal_to_decimal128, false
2774
+
2775
+ let(:fans) do
2776
+ BigDecimal('139432.0002')
2777
+ end
2778
+
2779
+ let!(:band) do
2780
+ Band.create!(name: "Boards of Canada", fans: fans)
2781
+ end
2782
+
2783
+ let(:from_db) do
2784
+ Band.where(fans: fans.to_s).first
2785
+ end
2786
+
2787
+ it "finds the document by the big decimal value" do
2788
+ expect(from_db).to eq(band)
2789
+ end
2790
+ end
2791
+
2792
+ context 'when map_big_decimal_to_decimal128 is true' do
2793
+ config_override :map_big_decimal_to_decimal128, true
2794
+
2795
+ let(:fans) do
2796
+ BigDecimal('139432.0002')
2797
+ end
2798
+
2799
+ let!(:band) do
2800
+ Band.create!(name: "Boards of Canada", fans: fans)
2801
+ end
2802
+
2803
+ let(:from_db) do
2804
+ Band.where(fans: fans).first
2805
+ end
2806
+
2807
+ it "only finds the document by the string value" do
2808
+ expect(from_db).to eq(band)
2809
+ end
3757
2810
  end
3758
2811
  end
3759
2812
 
@@ -3858,6 +2911,217 @@ describe Mongoid::Criteria do
3858
2911
  expect(dup_criteria.selector).to eq({ "_id" => _id })
3859
2912
  end
3860
2913
  end
2914
+
2915
+ context "when querying an embedded field" do
2916
+ let(:criteria) { Band.where("label.name": 12345) }
2917
+
2918
+ it "mongoizes the embedded field in the selector" do
2919
+ expect(criteria.selector).to eq("label.name" => "12345")
2920
+ end
2921
+ end
2922
+
2923
+ context "when querying with a range" do
2924
+
2925
+ context "when querying an embeds_many association" do
2926
+ let(:criteria) do
2927
+ Band.where("labels" => 10..15)
2928
+ end
2929
+
2930
+ it "correctly uses elemMatch without an inner key" do
2931
+ expect(criteria.selector).to eq(
2932
+ "labels" => {
2933
+ "$elemMatch" => { "$gte" => 10, "$lte" => 15 }
2934
+ }
2935
+ )
2936
+ end
2937
+ end
2938
+
2939
+ context "when querying an element in an embeds_many association" do
2940
+ let(:criteria) do
2941
+ Band.where("labels.age" => 10..15)
2942
+ end
2943
+
2944
+ it "correctly uses elemMatch" do
2945
+ expect(criteria.selector).to eq(
2946
+ "labels" => {
2947
+ "$elemMatch" => {
2948
+ "age" => { "$gte" => 10, "$lte" => 15 }
2949
+ }
2950
+ }
2951
+ )
2952
+ end
2953
+ end
2954
+
2955
+ context "when querying a field of type array" do
2956
+ let(:criteria) do
2957
+ Band.where("genres" => 10..15)
2958
+ end
2959
+
2960
+ it "correctly uses elemMatch without an inner key" do
2961
+ expect(criteria.selector).to eq(
2962
+ "genres" => {
2963
+ "$elemMatch" => { "$gte" => 10, "$lte" => 15 }
2964
+ }
2965
+ )
2966
+ end
2967
+ end
2968
+
2969
+ context "when querying an aliased field of type array" do
2970
+ let(:criteria) do
2971
+ Person.where("array" => 10..15)
2972
+ end
2973
+
2974
+ it "correctly uses the aliased field and elemMatch" do
2975
+ expect(criteria.selector).to eq(
2976
+ "a" => {
2977
+ "$elemMatch" => { "$gte" => 10, "$lte" => 15 }
2978
+ }
2979
+ )
2980
+ end
2981
+ end
2982
+
2983
+ context "when querying a field inside an array" do
2984
+ let(:criteria) do
2985
+ Band.where("genres.age" => 10..15)
2986
+ end
2987
+
2988
+ it "correctly uses elemMatch" do
2989
+ expect(criteria.selector).to eq(
2990
+ "genres" => {
2991
+ "$elemMatch" => {
2992
+ "age" => { "$gte" => 10, "$lte" => 15 }
2993
+ }
2994
+ }
2995
+ )
2996
+ end
2997
+ end
2998
+
2999
+ context "when there are no embeds_manys or Arrays" do
3000
+ let(:criteria) do
3001
+ Band.where("fans.info.age" => 10..15)
3002
+ end
3003
+
3004
+ it "does not use elemMatch" do
3005
+ expect(criteria.selector).to eq(
3006
+ "fans.info.age" => { "$gte" => 10, "$lte" => 15 }
3007
+ )
3008
+ end
3009
+ end
3010
+
3011
+ context "when querying a nested element in an embeds_many association" do
3012
+ let(:criteria) do
3013
+ Band.where("labels.age.number" => 10..15)
3014
+ end
3015
+
3016
+ it "correctly uses elemMatch" do
3017
+ expect(criteria.selector).to eq(
3018
+ "labels" => {
3019
+ "$elemMatch" => {
3020
+ "age.number" => { "$gte" => 10, "$lte" => 15 }
3021
+ }
3022
+ }
3023
+ )
3024
+ end
3025
+ end
3026
+
3027
+ context "when querying a nested element in an Array" do
3028
+ let(:criteria) do
3029
+ Band.where("genres.name.length" => 10..15)
3030
+ end
3031
+
3032
+ it "correctly uses elemMatch" do
3033
+ expect(criteria.selector).to eq(
3034
+ "genres" => {
3035
+ "$elemMatch" => {
3036
+ "name.length" => { "$gte" => 10, "$lte" => 15 }
3037
+ }
3038
+ }
3039
+ )
3040
+ end
3041
+ end
3042
+
3043
+ context "when querying a nested element in a nested embeds_many association" do
3044
+ context "when the outer association is an embeds_many" do
3045
+ let(:criteria) do
3046
+ Band.where("records.tracks.name.length" => 10..15)
3047
+ end
3048
+
3049
+ it "correctly uses elemMatch" do
3050
+ expect(criteria.selector).to eq(
3051
+ "records.tracks" => {
3052
+ "$elemMatch" => {
3053
+ "name.length" => { "$gte" => 10, "$lte" => 15 }
3054
+ }
3055
+ }
3056
+ )
3057
+ end
3058
+ end
3059
+
3060
+ context "when the outer association is an embeds_one" do
3061
+ let(:criteria) do
3062
+ Person.where("name.translations.language.length" => 10..15)
3063
+ end
3064
+
3065
+ it "correctly uses elemMatch" do
3066
+ expect(criteria.selector).to eq(
3067
+ "name.translations" => {
3068
+ "$elemMatch" => {
3069
+ "language.length" => { "$gte" => 10, "$lte" => 15 }
3070
+ }
3071
+ }
3072
+ )
3073
+ end
3074
+ end
3075
+ end
3076
+
3077
+ context "when querying a deeply nested array" do
3078
+ let(:criteria) do
3079
+ Person.where("addresses.code.deepest.array.element.item" => 10..15)
3080
+ end
3081
+
3082
+ it "correctly uses elemMatch" do
3083
+ expect(criteria.selector).to eq(
3084
+ "addresses.code.deepest.array" => {
3085
+ "$elemMatch" => {
3086
+ "element.item" => { "$gte" => 10, "$lte" => 15 }
3087
+ }
3088
+ }
3089
+ )
3090
+ end
3091
+ end
3092
+
3093
+ context "when there are multiple conditions" do
3094
+ let(:criteria) do
3095
+ Band.where("$or" => [{"labels.age" => 10..15}, {labels: 8}])
3096
+ end
3097
+
3098
+ it "correctly combines the conditions" do
3099
+ expect(criteria.selector).to eq("$or" => [
3100
+ { "labels" => {
3101
+ "$elemMatch" => {
3102
+ "age" => { "$gte" => 10, "$lte" => 15 }
3103
+ } } },
3104
+ { "labels" => 8 }
3105
+ ])
3106
+ end
3107
+ end
3108
+
3109
+ context "when the association is aliased" do
3110
+ let(:criteria) do
3111
+ Person.where("passport.passport_pages.num_stamps" => 10..18)
3112
+ end
3113
+
3114
+ it "correctly uses the aliased association" do
3115
+ expect(criteria.selector).to eq(
3116
+ "pass.passport_pages" => {
3117
+ "$elemMatch" => {
3118
+ "num_stamps" => { "$gte" => 10, "$lte" => 18 }
3119
+ }
3120
+ }
3121
+ )
3122
+ end
3123
+ end
3124
+ end
3861
3125
  end
3862
3126
 
3863
3127
  describe "#for_js" do