mongoid 7.4.0 → 8.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (391) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +3 -3
  4. data/lib/config/locales/en.yml +52 -28
  5. data/lib/mongoid/association/accessors.rb +38 -9
  6. data/lib/mongoid/association/bindable.rb +50 -2
  7. data/lib/mongoid/association/builders.rb +4 -2
  8. data/lib/mongoid/association/constrainable.rb +0 -1
  9. data/lib/mongoid/association/eager_loadable.rb +29 -7
  10. data/lib/mongoid/association/embedded/batchable.rb +53 -13
  11. data/lib/mongoid/association/embedded/cyclic.rb +1 -1
  12. data/lib/mongoid/association/embedded/embedded_in/binding.rb +24 -2
  13. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +2 -2
  14. data/lib/mongoid/association/embedded/embedded_in.rb +3 -2
  15. data/lib/mongoid/association/embedded/embeds_many/binding.rb +1 -0
  16. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +1 -1
  17. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +50 -28
  18. data/lib/mongoid/association/embedded/embeds_many.rb +2 -2
  19. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +18 -4
  20. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +23 -4
  21. data/lib/mongoid/association/embedded/embeds_one.rb +3 -3
  22. data/lib/mongoid/association/macros.rb +22 -1
  23. data/lib/mongoid/association/many.rb +11 -7
  24. data/lib/mongoid/association/nested/many.rb +5 -4
  25. data/lib/mongoid/association/nested/nested_buildable.rb +4 -4
  26. data/lib/mongoid/association/nested/one.rb +5 -5
  27. data/lib/mongoid/association/one.rb +2 -2
  28. data/lib/mongoid/association/options.rb +9 -9
  29. data/lib/mongoid/association/proxy.rb +14 -3
  30. data/lib/mongoid/association/referenced/auto_save.rb +4 -3
  31. data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
  32. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
  33. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +5 -6
  34. data/lib/mongoid/association/referenced/belongs_to.rb +2 -2
  35. data/lib/mongoid/association/referenced/counter_cache.rb +10 -10
  36. data/lib/mongoid/association/referenced/eager.rb +2 -2
  37. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +66 -13
  38. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +6 -3
  39. data/lib/mongoid/association/referenced/has_many/enumerable.rb +20 -24
  40. data/lib/mongoid/association/referenced/has_many/proxy.rb +24 -18
  41. data/lib/mongoid/association/referenced/has_many.rb +3 -3
  42. data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -1
  43. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +5 -5
  44. data/lib/mongoid/association/referenced/has_one/proxy.rb +9 -12
  45. data/lib/mongoid/association/referenced/has_one.rb +3 -3
  46. data/lib/mongoid/association/referenced/syncable.rb +4 -4
  47. data/lib/mongoid/association/reflections.rb +2 -2
  48. data/lib/mongoid/association/relatable.rb +44 -10
  49. data/lib/mongoid/association.rb +5 -5
  50. data/lib/mongoid/atomic/modifiers.rb +2 -2
  51. data/lib/mongoid/atomic/paths/embedded/many.rb +19 -0
  52. data/lib/mongoid/attributes/dynamic.rb +3 -3
  53. data/lib/mongoid/attributes/nested.rb +5 -5
  54. data/lib/mongoid/attributes/processing.rb +10 -3
  55. data/lib/mongoid/attributes/projector.rb +1 -1
  56. data/lib/mongoid/attributes/readonly.rb +2 -2
  57. data/lib/mongoid/attributes.rb +43 -40
  58. data/lib/mongoid/cacheable.rb +2 -2
  59. data/lib/mongoid/changeable.rb +42 -7
  60. data/lib/mongoid/clients/options.rb +5 -1
  61. data/lib/mongoid/clients/sessions.rb +2 -14
  62. data/lib/mongoid/clients/validators/storage.rb +3 -3
  63. data/lib/mongoid/config/environment.rb +20 -4
  64. data/lib/mongoid/config/validators/client.rb +6 -6
  65. data/lib/mongoid/config.rb +32 -17
  66. data/lib/mongoid/contextual/aggregable/memory.rb +24 -16
  67. data/lib/mongoid/contextual/aggregable/mongo.rb +5 -5
  68. data/lib/mongoid/contextual/aggregable/none.rb +1 -1
  69. data/lib/mongoid/contextual/atomic.rb +1 -1
  70. data/lib/mongoid/contextual/geo_near.rb +7 -7
  71. data/lib/mongoid/contextual/map_reduce.rb +2 -2
  72. data/lib/mongoid/contextual/memory.rb +180 -21
  73. data/lib/mongoid/contextual/mongo.rb +237 -217
  74. data/lib/mongoid/contextual/none.rb +67 -5
  75. data/lib/mongoid/contextual/queryable.rb +1 -1
  76. data/lib/mongoid/contextual.rb +2 -2
  77. data/lib/mongoid/copyable.rb +32 -8
  78. data/lib/mongoid/criteria/findable.rb +7 -4
  79. data/lib/mongoid/criteria/includable.rb +24 -20
  80. data/lib/mongoid/criteria/marshalable.rb +10 -2
  81. data/lib/mongoid/criteria/permission.rb +1 -1
  82. data/lib/mongoid/criteria/queryable/aggregable.rb +2 -2
  83. data/lib/mongoid/criteria/queryable/extensions/array.rb +2 -13
  84. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -4
  85. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +2 -2
  86. data/lib/mongoid/criteria/queryable/extensions/date.rb +6 -1
  87. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +6 -1
  88. data/lib/mongoid/criteria/queryable/extensions/hash.rb +0 -14
  89. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -1
  90. data/lib/mongoid/criteria/queryable/extensions/object.rb +2 -1
  91. data/lib/mongoid/criteria/queryable/extensions/range.rb +13 -5
  92. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
  93. data/lib/mongoid/criteria/queryable/extensions/set.rb +1 -1
  94. data/lib/mongoid/criteria/queryable/extensions/string.rb +3 -3
  95. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +4 -2
  96. data/lib/mongoid/criteria/queryable/extensions/time.rb +6 -1
  97. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +6 -1
  98. data/lib/mongoid/criteria/queryable/key.rb +3 -3
  99. data/lib/mongoid/criteria/queryable/mergeable.rb +21 -0
  100. data/lib/mongoid/criteria/queryable/optional.rb +5 -11
  101. data/lib/mongoid/criteria/queryable/options.rb +2 -2
  102. data/lib/mongoid/criteria/queryable/pipeline.rb +1 -1
  103. data/lib/mongoid/criteria/queryable/selectable.rb +31 -37
  104. data/lib/mongoid/criteria/queryable/selector.rb +92 -7
  105. data/lib/mongoid/criteria/queryable/smash.rb +40 -7
  106. data/lib/mongoid/criteria/queryable.rb +12 -7
  107. data/lib/mongoid/criteria/scopable.rb +2 -2
  108. data/lib/mongoid/criteria.rb +15 -35
  109. data/lib/mongoid/deprecable.rb +36 -0
  110. data/lib/mongoid/deprecation.rb +25 -0
  111. data/lib/mongoid/document.rb +98 -34
  112. data/lib/mongoid/equality.rb +12 -12
  113. data/lib/mongoid/errors/document_not_found.rb +33 -12
  114. data/lib/mongoid/errors/invalid_config_option.rb +1 -1
  115. data/lib/mongoid/errors/invalid_dependent_strategy.rb +1 -1
  116. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
  117. data/lib/mongoid/errors/invalid_field.rb +6 -2
  118. data/lib/mongoid/errors/invalid_field_type.rb +26 -0
  119. data/lib/mongoid/errors/invalid_relation.rb +1 -1
  120. data/lib/mongoid/errors/invalid_relation_option.rb +1 -1
  121. data/lib/mongoid/errors/invalid_session_use.rb +1 -1
  122. data/lib/mongoid/errors/invalid_storage_options.rb +1 -1
  123. data/lib/mongoid/errors/mongoid_error.rb +3 -3
  124. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +1 -1
  125. data/lib/mongoid/errors/no_client_database.rb +1 -1
  126. data/lib/mongoid/errors/no_client_hosts.rb +1 -1
  127. data/lib/mongoid/errors/readonly_attribute.rb +1 -1
  128. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
  129. data/lib/mongoid/errors/unknown_attribute.rb +1 -1
  130. data/lib/mongoid/errors.rb +2 -2
  131. data/lib/mongoid/extensions/array.rb +9 -7
  132. data/lib/mongoid/extensions/big_decimal.rb +33 -10
  133. data/lib/mongoid/extensions/binary.rb +42 -0
  134. data/lib/mongoid/extensions/boolean.rb +8 -2
  135. data/lib/mongoid/extensions/date.rb +26 -20
  136. data/lib/mongoid/extensions/date_time.rb +1 -1
  137. data/lib/mongoid/extensions/false_class.rb +1 -1
  138. data/lib/mongoid/extensions/float.rb +7 -4
  139. data/lib/mongoid/extensions/hash.rb +13 -6
  140. data/lib/mongoid/extensions/integer.rb +7 -4
  141. data/lib/mongoid/extensions/module.rb +1 -1
  142. data/lib/mongoid/extensions/object.rb +8 -6
  143. data/lib/mongoid/extensions/range.rb +41 -10
  144. data/lib/mongoid/extensions/regexp.rb +11 -4
  145. data/lib/mongoid/extensions/set.rb +11 -4
  146. data/lib/mongoid/extensions/string.rb +11 -22
  147. data/lib/mongoid/extensions/symbol.rb +4 -15
  148. data/lib/mongoid/extensions/time.rb +27 -16
  149. data/lib/mongoid/extensions/time_with_zone.rb +1 -2
  150. data/lib/mongoid/extensions/true_class.rb +1 -1
  151. data/lib/mongoid/extensions.rb +1 -0
  152. data/lib/mongoid/factory.rb +42 -7
  153. data/lib/mongoid/fields/foreign_key.rb +11 -4
  154. data/lib/mongoid/fields/localized.rb +9 -4
  155. data/lib/mongoid/fields/standard.rb +7 -7
  156. data/lib/mongoid/fields/validators/macro.rb +3 -9
  157. data/lib/mongoid/fields.rb +201 -35
  158. data/lib/mongoid/findable.rb +34 -13
  159. data/lib/mongoid/indexable/specification.rb +2 -2
  160. data/lib/mongoid/indexable/validators/options.rb +6 -2
  161. data/lib/mongoid/interceptable.rb +73 -13
  162. data/lib/mongoid/matchable.rb +1 -1
  163. data/lib/mongoid/matcher.rb +12 -7
  164. data/lib/mongoid/persistable/creatable.rb +18 -9
  165. data/lib/mongoid/persistable/deletable.rb +1 -1
  166. data/lib/mongoid/persistable/destroyable.rb +1 -1
  167. data/lib/mongoid/persistable/savable.rb +2 -2
  168. data/lib/mongoid/persistable/unsettable.rb +1 -1
  169. data/lib/mongoid/persistable/updatable.rb +19 -12
  170. data/lib/mongoid/persistable/upsertable.rb +2 -2
  171. data/lib/mongoid/persistable.rb +3 -3
  172. data/lib/mongoid/persistence_context.rb +63 -10
  173. data/lib/mongoid/query_cache.rb +8 -260
  174. data/lib/mongoid/railties/controller_runtime.rb +1 -1
  175. data/lib/mongoid/reloadable.rb +7 -3
  176. data/lib/mongoid/scopable.rb +26 -22
  177. data/lib/mongoid/selectable.rb +1 -2
  178. data/lib/mongoid/serializable.rb +10 -6
  179. data/lib/mongoid/stateful.rb +35 -9
  180. data/lib/mongoid/tasks/database.rb +0 -2
  181. data/lib/mongoid/threaded/lifecycle.rb +5 -5
  182. data/lib/mongoid/threaded.rb +12 -12
  183. data/lib/mongoid/timestamps/created.rb +1 -1
  184. data/lib/mongoid/timestamps/updated.rb +2 -2
  185. data/lib/mongoid/touchable.rb +2 -3
  186. data/lib/mongoid/traversable.rb +8 -4
  187. data/lib/mongoid/validatable/localizable.rb +1 -1
  188. data/lib/mongoid/validatable/macros.rb +0 -2
  189. data/lib/mongoid/validatable/presence.rb +2 -2
  190. data/lib/mongoid/validatable/uniqueness.rb +9 -8
  191. data/lib/mongoid/validatable.rb +6 -6
  192. data/lib/mongoid/version.rb +1 -1
  193. data/lib/mongoid/warnings.rb +28 -0
  194. data/lib/mongoid.rb +2 -0
  195. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +11 -5
  196. data/spec/config/mongoid.yml +16 -0
  197. data/spec/config/mongoid_with_schema_map_uuid.yml +27 -0
  198. data/spec/integration/app_spec.rb +28 -26
  199. data/spec/integration/associations/belongs_to_spec.rb +18 -0
  200. data/spec/integration/associations/embedded_dirty_spec.rb +28 -0
  201. data/spec/integration/associations/embedded_spec.rb +15 -0
  202. data/spec/integration/associations/embeds_many_spec.rb +15 -2
  203. data/spec/integration/associations/embeds_one_spec.rb +18 -0
  204. data/spec/integration/associations/foreign_key_spec.rb +9 -0
  205. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
  206. data/spec/integration/associations/has_one_spec.rb +97 -1
  207. data/spec/integration/associations/scope_option_spec.rb +1 -1
  208. data/spec/integration/callbacks_models.rb +95 -1
  209. data/spec/integration/callbacks_spec.rb +226 -4
  210. data/spec/integration/criteria/range_spec.rb +95 -1
  211. data/spec/integration/discriminator_key_spec.rb +115 -76
  212. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  213. data/spec/integration/i18n_fallbacks_spec.rb +1 -17
  214. data/spec/integration/matcher_examples_spec.rb +20 -13
  215. data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
  216. data/spec/integration/matcher_operator_spec.rb +3 -5
  217. data/spec/integration/persistence/range_field_spec.rb +350 -0
  218. data/spec/lite_spec_helper.rb +1 -1
  219. data/spec/mongoid/association/counter_cache_spec.rb +1 -1
  220. data/spec/mongoid/association/depending_spec.rb +9 -9
  221. data/spec/mongoid/association/eager_spec.rb +2 -1
  222. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
  223. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
  224. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +69 -9
  225. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
  226. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +219 -8
  227. data/spec/mongoid/association/embedded/embeds_many_models.rb +157 -0
  228. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +12 -0
  229. data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
  230. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
  231. data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
  232. data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
  233. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
  234. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
  235. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +15 -0
  236. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  237. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -2
  238. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +67 -4
  239. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
  240. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
  241. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
  242. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +8 -8
  243. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +82 -13
  244. data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
  245. data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
  246. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
  247. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
  248. data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
  249. data/spec/mongoid/association/syncable_spec.rb +14 -0
  250. data/spec/mongoid/atomic/paths_spec.rb +0 -14
  251. data/spec/mongoid/atomic_spec.rb +22 -0
  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 +524 -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 +34 -42
  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/environment_spec.rb +39 -1
  263. data/spec/mongoid/config_spec.rb +104 -13
  264. data/spec/mongoid/contextual/aggregable/memory_spec.rb +396 -158
  265. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  266. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  267. data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
  268. data/spec/mongoid/contextual/memory_spec.rb +1336 -69
  269. data/spec/mongoid/contextual/mongo_spec.rb +1105 -174
  270. data/spec/mongoid/contextual/none_spec.rb +38 -0
  271. data/spec/mongoid/copyable_spec.rb +451 -1
  272. data/spec/mongoid/criteria/findable_spec.rb +86 -210
  273. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  274. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  275. data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
  276. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
  277. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
  278. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
  279. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
  280. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
  281. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
  282. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
  283. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
  284. data/spec/mongoid/criteria/queryable/optional_spec.rb +0 -484
  285. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +50 -0
  286. data/spec/mongoid/criteria/queryable/selectable_spec.rb +289 -124
  287. data/spec/mongoid/criteria/queryable/selector_spec.rb +14 -2
  288. data/spec/mongoid/criteria_projection_spec.rb +0 -1
  289. data/spec/mongoid/criteria_spec.rb +475 -1199
  290. data/spec/mongoid/document_fields_spec.rb +173 -24
  291. data/spec/mongoid/document_spec.rb +32 -41
  292. data/spec/mongoid/equality_spec.rb +12 -12
  293. data/spec/mongoid/errors/document_not_found_spec.rb +76 -0
  294. data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
  295. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  296. data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
  297. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  298. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
  299. data/spec/mongoid/extensions/array_spec.rb +16 -2
  300. data/spec/mongoid/extensions/big_decimal_spec.rb +712 -212
  301. data/spec/mongoid/extensions/binary_spec.rb +44 -9
  302. data/spec/mongoid/extensions/boolean_spec.rb +68 -82
  303. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
  304. data/spec/mongoid/extensions/date_spec.rb +71 -1
  305. data/spec/mongoid/extensions/date_time_spec.rb +15 -9
  306. data/spec/mongoid/extensions/float_spec.rb +53 -74
  307. data/spec/mongoid/extensions/hash_spec.rb +30 -0
  308. data/spec/mongoid/extensions/integer_spec.rb +50 -64
  309. data/spec/mongoid/extensions/range_spec.rb +255 -54
  310. data/spec/mongoid/extensions/regexp_spec.rb +58 -33
  311. data/spec/mongoid/extensions/set_spec.rb +106 -0
  312. data/spec/mongoid/extensions/string_spec.rb +53 -25
  313. data/spec/mongoid/extensions/symbol_spec.rb +18 -25
  314. data/spec/mongoid/extensions/time_spec.rb +634 -66
  315. data/spec/mongoid/extensions/time_with_zone_spec.rb +17 -31
  316. data/spec/mongoid/factory_spec.rb +61 -1
  317. data/spec/mongoid/fields/localized_spec.rb +37 -12
  318. data/spec/mongoid/fields_spec.rb +321 -50
  319. data/spec/mongoid/findable_spec.rb +80 -15
  320. data/spec/mongoid/indexable/specification_spec.rb +2 -2
  321. data/spec/mongoid/indexable_spec.rb +39 -20
  322. data/spec/mongoid/interceptable_spec.rb +584 -5
  323. data/spec/mongoid/interceptable_spec_models.rb +235 -4
  324. data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
  325. data/spec/mongoid/mongoizable_spec.rb +285 -0
  326. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  327. data/spec/mongoid/persistable/deletable_spec.rb +2 -2
  328. data/spec/mongoid/persistable/destroyable_spec.rb +2 -2
  329. data/spec/mongoid/persistable/upsertable_spec.rb +14 -0
  330. data/spec/mongoid/persistence_context_spec.rb +50 -1
  331. data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
  332. data/spec/mongoid/query_cache_spec.rb +0 -154
  333. data/spec/mongoid/reloadable_spec.rb +35 -2
  334. data/spec/mongoid/scopable_spec.rb +54 -16
  335. data/spec/mongoid/shardable_spec.rb +14 -0
  336. data/spec/mongoid/stateful_spec.rb +28 -0
  337. data/spec/mongoid/timestamps_spec.rb +390 -0
  338. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  339. data/spec/mongoid/touchable_spec.rb +116 -0
  340. data/spec/mongoid/touchable_spec_models.rb +12 -8
  341. data/spec/mongoid/traversable_spec.rb +4 -11
  342. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  343. data/spec/mongoid/validatable/uniqueness_spec.rb +59 -31
  344. data/spec/mongoid/warnings_spec.rb +35 -0
  345. data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
  346. data/spec/rails/mongoid_spec.rb +4 -16
  347. data/spec/shared/lib/mrss/constraints.rb +8 -16
  348. data/spec/shared/lib/mrss/docker_runner.rb +23 -3
  349. data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
  350. data/spec/shared/lib/mrss/lite_constraints.rb +32 -1
  351. data/spec/shared/share/Dockerfile.erb +34 -48
  352. data/spec/shared/shlib/config.sh +27 -0
  353. data/spec/shared/shlib/server.sh +32 -19
  354. data/spec/shared/shlib/set_env.sh +37 -0
  355. data/spec/support/constraints.rb +24 -0
  356. data/spec/support/macros.rb +55 -0
  357. data/spec/support/models/augmentation.rb +12 -0
  358. data/spec/support/models/band.rb +3 -0
  359. data/spec/support/models/catalog.rb +24 -0
  360. data/spec/support/models/circus.rb +3 -0
  361. data/spec/support/models/code.rb +2 -0
  362. data/spec/support/models/fanatic.rb +8 -0
  363. data/spec/support/models/implant.rb +9 -0
  364. data/spec/support/models/label.rb +2 -0
  365. data/spec/support/models/membership.rb +1 -0
  366. data/spec/support/models/passport.rb +9 -0
  367. data/spec/support/models/person.rb +1 -0
  368. data/spec/support/models/player.rb +2 -0
  369. data/spec/support/models/powerup.rb +12 -0
  370. data/spec/support/models/registry.rb +1 -0
  371. data/spec/support/models/school.rb +14 -0
  372. data/spec/support/models/shield.rb +18 -0
  373. data/spec/support/models/student.rb +14 -0
  374. data/spec/support/models/weapon.rb +12 -0
  375. data/spec/support/schema_maps/schema_map_aws.json +17 -0
  376. data/spec/support/schema_maps/schema_map_aws_key_alt_names.json +12 -0
  377. data/spec/support/schema_maps/schema_map_azure.json +17 -0
  378. data/spec/support/schema_maps/schema_map_azure_key_alt_names.json +12 -0
  379. data/spec/support/schema_maps/schema_map_gcp.json +17 -0
  380. data/spec/support/schema_maps/schema_map_gcp_key_alt_names.json +12 -0
  381. data/spec/support/schema_maps/schema_map_kmip.json +17 -0
  382. data/spec/support/schema_maps/schema_map_kmip_key_alt_names.json +12 -0
  383. data/spec/support/schema_maps/schema_map_local.json +18 -0
  384. data/spec/support/schema_maps/schema_map_local_key_alt_names.json +12 -0
  385. data/spec/support/spec_config.rb +4 -0
  386. data.tar.gz.sig +0 -0
  387. metadata +682 -619
  388. metadata.gz.sig +0 -0
  389. data/lib/mongoid/errors/eager_load.rb +0 -23
  390. data/lib/mongoid/errors/invalid_value.rb +0 -17
  391. data/spec/mongoid/errors/eager_load_spec.rb +0 -31
@@ -42,7 +42,12 @@ module Mongoid
42
42
  #
43
43
  # @return [ Time ] The evolved date time.
44
44
  def evolve(object)
45
- object.__evolve_time__
45
+ res = begin
46
+ object.try(:__evolve_time__)
47
+ rescue ArgumentError
48
+ nil
49
+ end
50
+ res.nil? ? object : res
46
51
  end
47
52
  end
48
53
  end
@@ -82,7 +82,7 @@ module Mongoid
82
82
  #
83
83
  # @param [ Object ] other The object to compare to.
84
84
  #
85
- # @return [ true, false ] If the objects are equal.
85
+ # @return [ true | false ] If the objects are equal.
86
86
  def ==(other)
87
87
  return false unless other.is_a?(Key)
88
88
  name == other.name && operator == other.operator && expanded == other.expanded
@@ -104,7 +104,7 @@ module Mongoid
104
104
  # @example Instantiate a key for sorting.
105
105
  # Key.new(:field, :__override__, 1)
106
106
  #
107
- # @param [ String, Symbol ] name The field name.
107
+ # @param [ String | Symbol ] name The field name.
108
108
  # @param [ Symbol ] strategy The name of the merge strategy.
109
109
  # @param [ String | Integer ] operator The MongoDB operator,
110
110
  # or sort direction (1 or -1).
@@ -124,7 +124,7 @@ module Mongoid
124
124
  # key.__expr_part__(50)
125
125
  #
126
126
  # @param [ Object ] object The value to be included.
127
- # @param [ true, false ] negating If the selection should be negated.
127
+ # @param [ true | false ] negating If the selection should be negated.
128
128
  #
129
129
  # @return [ Hash ] The raw MongoDB selector.
130
130
  def __expr_part__(object, negating = false)
@@ -52,6 +52,27 @@ module Mongoid
52
52
  self
53
53
  end
54
54
 
55
+ # Merge criteria with operators using the and operator.
56
+ #
57
+ # @param [ Hash ] criterion The criterion to add to the criteria.
58
+ # @param [ String ] operator The MongoDB operator.
59
+ #
60
+ # @return [ Criteria ] The resulting criteria.
61
+ def and_with_operator(criterion, operator)
62
+ crit = self
63
+ if criterion
64
+ criterion.each_pair do |field, value|
65
+ val = prepare(field, operator, value)
66
+ # The prepare method already takes the negation into account. We
67
+ # set negating to false here so that ``and`` doesn't also apply
68
+ # negation and we have a double negative.
69
+ crit.negating = false
70
+ crit = crit.and(field => val)
71
+ end
72
+ end
73
+ crit
74
+ end
75
+
55
76
  private
56
77
 
57
78
  # Adds the criterion to the existing selection.
@@ -163,7 +163,7 @@ module Mongoid
163
163
  # @example Add sorting options via a string.
164
164
  # optional.order_by("name ASC, dob DESC")
165
165
  #
166
- # @param [ Array, Hash, String ] spec The sorting specification.
166
+ # @param [ Array | Hash | String ] spec The sorting specification.
167
167
  #
168
168
  # @return [ Optional ] The cloned optional.
169
169
  def order_by(*spec)
@@ -184,7 +184,7 @@ module Mongoid
184
184
  # @example Replace the ordering.
185
185
  # optional.reorder(name: :asc)
186
186
  #
187
- # @param [ Array, Hash, String ] spec The sorting specification.
187
+ # @param [ Array | Hash | String ] spec The sorting specification.
188
188
  #
189
189
  # @return [ Optional ] The cloned optional.
190
190
  def reorder(*spec)
@@ -318,15 +318,9 @@ module Mongoid
318
318
  #
319
319
  # @return [ Optional ] The cloned optional.
320
320
  def add_sort_option(options, field, direction)
321
- if driver == :mongo1x
322
- sorting = (options[:sort] || []).dup
323
- sorting.push([ field, direction ])
324
- options.store(:sort, sorting)
325
- else
326
- sorting = (options[:sort] || {}).dup
327
- sorting[field] = direction
328
- options.store(:sort, sorting)
329
- end
321
+ sorting = (options[:sort] || {}).dup
322
+ sorting[field] = direction
323
+ options.store(:sort, sorting)
330
324
  end
331
325
 
332
326
  # Take the provided criterion and store it as an option in the query
@@ -54,7 +54,7 @@ module Mongoid
54
54
  # @example Store a value in the options.
55
55
  # options.store(:key, "testing")
56
56
  #
57
- # @param [ String, Symbol ] key The name of the attribute.
57
+ # @param [ String | Symbol ] key The name of the attribute.
58
58
  # @param [ Object ] value The value to add.
59
59
  #
60
60
  # @return [ Object ] The stored object.
@@ -84,7 +84,7 @@ module Mongoid
84
84
  #
85
85
  # @return [ Options ] The copied options.
86
86
  def __deep_copy__
87
- self.class.new(aliases, serializers) do |copy|
87
+ self.class.new(aliases, serializers, associations, aliased_associations) do |copy|
88
88
  each_pair do |key, value|
89
89
  copy.merge!(key => value.__deep_copy__)
90
90
  end
@@ -67,7 +67,7 @@ module Mongoid
67
67
  # pipeline.unwind(:field)
68
68
  # pipeline.unwind(document)
69
69
  #
70
- # @param [ String, Symbol, Hash ] field_or_doc A field name or a
70
+ # @param [ String | Symbol | Hash ] field_or_doc A field name or a
71
71
  # document.
72
72
  #
73
73
  # @return [ Pipeline ] The pipeline.
@@ -154,7 +154,7 @@ module Mongoid
154
154
  raise Errors::CriteriaArgumentRequired, :elem_match
155
155
  end
156
156
 
157
- __override__(criterion, "$elemMatch")
157
+ and_or_override(criterion, "$elemMatch")
158
158
  end
159
159
  key :elem_match, :override, "$elemMatch"
160
160
 
@@ -227,19 +227,6 @@ module Mongoid
227
227
  __merge__(criterion)
228
228
  end
229
229
 
230
- # Alias for +geo_spatial+.
231
- #
232
- # @deprecated
233
- def geo_spacial(criterion)
234
- # Duplicate method body so that we can raise this exception with
235
- # geo_spacial as the indicated operator rather than geo_spatial.
236
- if criterion.nil?
237
- raise Errors::CriteriaArgumentRequired, :geo_spacial
238
- end
239
-
240
- __merge__(criterion)
241
- end
242
-
243
230
  key :intersects_line, :override, "$geoIntersects", "$geometry" do |value|
244
231
  { "type" => LINE_STRING, "coordinates" => value }
245
232
  end
@@ -270,7 +257,7 @@ module Mongoid
270
257
  raise Errors::CriteriaArgumentRequired, :eq
271
258
  end
272
259
 
273
- __override__(criterion, "$eq")
260
+ and_or_override(criterion, "$eq")
274
261
  end
275
262
  key :eq, :override, "$eq"
276
263
 
@@ -290,7 +277,7 @@ module Mongoid
290
277
  raise Errors::CriteriaArgumentRequired, :gt
291
278
  end
292
279
 
293
- __override__(criterion, "$gt")
280
+ and_or_override(criterion, "$gt")
294
281
  end
295
282
  key :gt, :override, "$gt"
296
283
 
@@ -310,7 +297,7 @@ module Mongoid
310
297
  raise Errors::CriteriaArgumentRequired, :gte
311
298
  end
312
299
 
313
- __override__(criterion, "$gte")
300
+ and_or_override(criterion, "$gte")
314
301
  end
315
302
  key :gte, :override, "$gte"
316
303
 
@@ -366,7 +353,7 @@ module Mongoid
366
353
  raise Errors::CriteriaArgumentRequired, :lt
367
354
  end
368
355
 
369
- __override__(criterion, "$lt")
356
+ and_or_override(criterion, "$lt")
370
357
  end
371
358
  key :lt, :override, "$lt"
372
359
 
@@ -386,7 +373,7 @@ module Mongoid
386
373
  raise Errors::CriteriaArgumentRequired, :lte
387
374
  end
388
375
 
389
- __override__(criterion, "$lte")
376
+ and_or_override(criterion, "$lte")
390
377
  end
391
378
  key :lte, :override, "$lte"
392
379
 
@@ -423,7 +410,7 @@ module Mongoid
423
410
  raise Errors::CriteriaArgumentRequired, :mod
424
411
  end
425
412
 
426
- __override__(criterion, "$mod")
413
+ and_or_override(criterion, "$mod")
427
414
  end
428
415
  key :mod, :override, "$mod"
429
416
 
@@ -443,7 +430,7 @@ module Mongoid
443
430
  raise Errors::CriteriaArgumentRequired, :ne
444
431
  end
445
432
 
446
- __override__(criterion, "$ne")
433
+ and_or_override(criterion, "$ne")
447
434
  end
448
435
  alias :excludes :ne
449
436
  key :ne, :override, "$ne"
@@ -464,7 +451,7 @@ module Mongoid
464
451
  raise Errors::CriteriaArgumentRequired, :near
465
452
  end
466
453
 
467
- __override__(criterion, "$near")
454
+ and_or_override(criterion, "$near")
468
455
  end
469
456
  key :near, :override, "$near"
470
457
 
@@ -484,7 +471,7 @@ module Mongoid
484
471
  raise Errors::CriteriaArgumentRequired, :near_sphere
485
472
  end
486
473
 
487
- __override__(criterion, "$nearSphere")
474
+ and_or_override(criterion, "$nearSphere")
488
475
  end
489
476
  key :near_sphere, :override, "$nearSphere"
490
477
 
@@ -542,7 +529,7 @@ module Mongoid
542
529
  # @example Is the selectable negating?
543
530
  # selectable.negating?
544
531
  #
545
- # @return [ true, false ] If the selectable is negating.
532
+ # @return [ true | false ] If the selectable is negating.
546
533
  def negating?
547
534
  !!negating
548
535
  end
@@ -679,16 +666,7 @@ module Mongoid
679
666
  end]
680
667
  end
681
668
  end
682
- # Should be able to do:
683
- #where('$or' => exprs)
684
- # But since that is broken do instead:
685
- clone.tap do |query|
686
- if query.selector['$or']
687
- query.selector.store('$or', query.selector['$or'] + exprs)
688
- else
689
- query.selector.store('$or', exprs)
690
- end
691
- end
669
+ self.and('$or' => exprs)
692
670
  end
693
671
  end
694
672
 
@@ -758,7 +736,7 @@ module Mongoid
758
736
  # conditions in a query. Mongoid will build such a query but the
759
737
  # server will return an error when trying to execute it.
760
738
  #
761
- # @param [ String, Symbol ] terms A string of terms that MongoDB parses
739
+ # @param [ String | Symbol ] terms A string of terms that MongoDB parses
762
740
  # and uses to query the text index.
763
741
  # @param [ Hash ] opts Text search options. See MongoDB documentation
764
742
  # for options.
@@ -796,7 +774,7 @@ module Mongoid
796
774
  # @example Add a javascript selection.
797
775
  # selectable.where("this.name == 'syd'")
798
776
  #
799
- # @param [ String, Hash ] criterion The javascript or standard selection.
777
+ # @param [ String | Hash ] criterion The javascript or standard selection.
800
778
  #
801
779
  # @return [ Selectable ] The cloned selectable.
802
780
  def where(*criteria)
@@ -874,7 +852,7 @@ module Mongoid
874
852
  # @param [ Hash ] criterion The criterion.
875
853
  def typed_override(criterion, operator)
876
854
  if criterion
877
- criterion.update_values do |value|
855
+ criterion.transform_values! do |value|
878
856
  yield(value)
879
857
  end
880
858
  end
@@ -924,6 +902,22 @@ module Mongoid
924
902
  end
925
903
  end
926
904
 
905
+ # Combine operator expessions onto a Criteria using either
906
+ # an override or ands depending on the status of the
907
+ # Mongoid.overwrite_chained_operators feature flag.
908
+ #
909
+ # @param [ Hash ] The criterion to add to the criteria.
910
+ # @param [ String ] operator The MongoDB operator.
911
+ #
912
+ # @return [ Criteria ] The resulting criteria.
913
+ def and_or_override(criterion, operator)
914
+ if Mongoid.overwrite_chained_operators
915
+ __override__(criterion, operator)
916
+ else
917
+ and_with_operator(criterion, operator)
918
+ end
919
+ end
920
+
927
921
  class << self
928
922
 
929
923
  # Get the methods on the selectable that can be forwarded to from a model.
@@ -13,7 +13,7 @@ module Mongoid
13
13
  # @example Merge in another selector.
14
14
  # selector.merge!(name: "test")
15
15
  #
16
- # @param [ Hash, Selector ] other The object to merge in.
16
+ # @param [ Hash | Selector ] other The object to merge in.
17
17
  #
18
18
  # @return [ Selector ] The selector.
19
19
  def merge!(other)
@@ -43,7 +43,7 @@ module Mongoid
43
43
  # @example Store a value in the selector.
44
44
  # selector.store(:key, "testing")
45
45
  #
46
- # @param [ String, Symbol ] key The name of the attribute.
46
+ # @param [ String | Symbol ] key The name of the attribute.
47
47
  # @param [ Object ] value The value to add.
48
48
  #
49
49
  # @return [ Object ] The stored object.
@@ -53,8 +53,7 @@ module Mongoid
53
53
  store_name = name
54
54
  store_value = evolve_multi(value)
55
55
  else
56
- store_name = localized_key(name, serializer)
57
- store_value = evolve(serializer, value)
56
+ store_name, store_value = store_creds(name, serializer, value)
58
57
  end
59
58
  super(store_name, store_value)
60
59
  end
@@ -74,6 +73,24 @@ module Mongoid
74
73
 
75
74
  private
76
75
 
76
+ # Get the store name and store value. If the value is of type range,
77
+ # we need may need to change the store_name as well as the store_value,
78
+ # therefore, we cannot just use the evole method.
79
+ #
80
+ # @param [ String ] name The name of the field.
81
+ # @param [ Object ] serializer The optional serializer for the field.
82
+ # @param [ Object ] value The value to serialize.
83
+ #
84
+ # @return [ Array<String, String> ] The store name and store value.
85
+ def store_creds(name, serializer, value)
86
+ store_name = localized_key(name, serializer)
87
+ if Range === value
88
+ evolve_range(store_name, serializer, value)
89
+ else
90
+ [ store_name, evolve(serializer, value) ]
91
+ end
92
+ end
93
+
77
94
  # Evolves a multi-list selection, like an $and or $or criterion, and
78
95
  # performs the necessary serialization.
79
96
  #
@@ -103,11 +120,10 @@ module Mongoid
103
120
  # some reason, although per its documentation Smash supposedly
104
121
  # owns both.
105
122
  name, serializer = storage_pair(key)
106
- final_key = localized_key(name, serializer)
107
123
  # This performs type conversions on the value and transformations
108
124
  # that depend on the type of the field that the value is stored
109
125
  # in, but not transformations that have to do with query shape.
110
- evolved_value = evolve(serializer, value)
126
+ final_key, evolved_value = store_creds(name, serializer, value)
111
127
 
112
128
  # This builds a query shape around the value, when the query
113
129
  # involves complex keys. For example, {:foo.lt => 5} produces
@@ -139,6 +155,8 @@ module Mongoid
139
155
  evolve_hash(serializer, value)
140
156
  when Array
141
157
  evolve_array(serializer, value)
158
+ when Range
159
+ value.__evolve_range__(serializer: serializer)
142
160
  else
143
161
  (serializer || value.class).evolve(value)
144
162
  end
@@ -182,6 +200,73 @@ module Mongoid
182
200
  end
183
201
  end
184
202
 
203
+ # Evolve a single key selection with range values. This method traverses
204
+ # the association tree to build a query for the given value and
205
+ # serializer. There are three parts to the query here:
206
+ #
207
+ # (1) "klass.child.gchild" => {
208
+ # "$elemMatch" => {
209
+ # (2) "ggchild.field" => (3) { "$gte" => 6, "$lte" => 10 }
210
+ # }
211
+ # }
212
+ # (1) The first n fields are dotted together until the last
213
+ # embeds_many or field of type array. In the above case, gchild
214
+ # would be an embeds_many or Array, and ggchild would be an
215
+ # embeds_one or a hash.
216
+ # (2) The last fields are used inside the $elemMatch. This one is
217
+ # actually optional, and will be ignored if the last field is an
218
+ # array or embeds_many. If the last field is an array (1), (2) and
219
+ # (3) will look like:
220
+ #
221
+ # "klass.child.gchild.ggchild.field" => {
222
+ # { "$elemMatch" => { "$gte" => 6, "$lte" => 10 } }
223
+ # }
224
+ #
225
+ # (3) This is calculated by:
226
+ #
227
+ # value.__evolve_range__(serializer: serializer).
228
+ #
229
+ # @api private
230
+ #
231
+ # @param [ String ] key The to store the range for.
232
+ # @param [ Object ] serializer The optional serializer for the field.
233
+ # @param [ Range ] value The Range to serialize.
234
+ #
235
+ # @return [ Array<String, Hash> ] The store name and serialized Range.
236
+ def evolve_range(key, serializer, value)
237
+ v = value.__evolve_range__(serializer: serializer)
238
+ assocs = []
239
+ Fields.traverse_association_tree(key, serializers, associations, aliased_associations) do |meth, obj, is_field|
240
+ assocs.push([meth, obj, is_field])
241
+ end
242
+
243
+ # Iterate backwards until you get a field with type
244
+ # Array or an embeds_many association.
245
+ inner_key = ""
246
+ loop do
247
+ # If there are no arrays or embeds_many associations, just return
248
+ # the key and value without $elemMatch.
249
+ return [ key, v ] if assocs.empty?
250
+
251
+ meth, obj, is_field = assocs.last
252
+ break if (is_field && obj.type == Array) || (!is_field && obj.is_a?(Association::Embedded::EmbedsMany))
253
+
254
+ assocs.pop
255
+ inner_key = "#{meth}.#{inner_key}"
256
+ end
257
+
258
+ # If the last array or embeds_many association is the last field,
259
+ # the inner key (2) is ignored, and the outer key (1) is the original
260
+ # key.
261
+ if inner_key.blank?
262
+ [ key, { "$elemMatch" => v }]
263
+ else
264
+ store_key = assocs.map(&:first).join('.')
265
+ store_value = { "$elemMatch" => { inner_key.chop => v } }
266
+ [ store_key, store_value ]
267
+ end
268
+ end
269
+
185
270
  # Determines if the selection is a multi-select, like an $and or $or or $nor
186
271
  # selection.
187
272
  #
@@ -192,7 +277,7 @@ module Mongoid
192
277
  #
193
278
  # @param [ String ] key The key to check.
194
279
  #
195
- # @return [ true, false ] If the key is for a multi-select.
280
+ # @return [ true | false ] If the key is for a multi-select.
196
281
  def multi_selection?(key)
197
282
  %w($and $or $nor).include?(key)
198
283
  end
@@ -8,8 +8,16 @@ module Mongoid
8
8
  class Smash < Hash
9
9
 
10
10
  # @attribute [r] aliases The aliases.
11
+ attr_reader :aliases
12
+
11
13
  # @attribute [r] serializers The serializers.
12
- attr_reader :aliases, :serializers
14
+ attr_reader :serializers
15
+
16
+ # @attribute [r] associations The associations.
17
+ attr_reader :associations
18
+
19
+ # @attribute [r] aliased_associations The aliased_associations.
20
+ attr_reader :aliased_associations
13
21
 
14
22
  # Perform a deep copy of the smash.
15
23
  #
@@ -18,7 +26,7 @@ module Mongoid
18
26
  #
19
27
  # @return [ Smash ] The copied hash.
20
28
  def __deep_copy__
21
- self.class.new(aliases, serializers) do |copy|
29
+ self.class.new(aliases, serializers, associations, aliased_associations) do |copy|
22
30
  each_pair do |key, value|
23
31
  copy.store(key, value.__deep_copy__)
24
32
  end
@@ -36,8 +44,15 @@ module Mongoid
36
44
  # responsible for serializing values. The keys of the hash must be
37
45
  # strings that match the field name, and the values must respond to
38
46
  # #localized? and #evolve(object).
39
- def initialize(aliases = {}, serializers = {})
40
- @aliases, @serializers = aliases, serializers
47
+ # @param [ Hash ] associations An optional hash of names to association
48
+ # objects.
49
+ # @param [ Hash ] aliased_associations An optional hash of mappings from
50
+ # aliases for associations to their actual field names in the database.
51
+ def initialize(aliases = {}, serializers = {}, associations = {}, aliased_associations = {})
52
+ @aliases = aliases
53
+ @serializers = serializers
54
+ @associations = associations
55
+ @aliased_associations = aliased_associations
41
56
  yield(self) if block_given?
42
57
  end
43
58
 
@@ -80,14 +95,32 @@ module Mongoid
80
95
  # @example Get the name and serializer.
81
96
  # smash.storage_pair("id")
82
97
  #
83
- # @param [ Symbol, String ] key The key provided to the selection.
98
+ # @param [ Symbol | String ] key The key provided to the selection.
84
99
  #
85
100
  # @return [ Array<String, Object> ] The name of the db field and
86
101
  # serializer.
87
102
  def storage_pair(key)
88
103
  field = key.to_s
89
- name = aliases[field] || field
90
- [ name, serializers[name] ]
104
+ name = Fields.database_field_name(field, associations, aliases, aliased_associations)
105
+ [ name, get_serializer(name) ]
106
+ end
107
+
108
+ private
109
+
110
+ # Retrieves the serializer for the given name. If the name exists in
111
+ # the serializers hash then return that immediately, otherwise
112
+ # recursively look through the associations and find the appropriate
113
+ # field.
114
+ #
115
+ # @param [ String ] name The name of the db field.
116
+ #
117
+ # @return [ Object ] The serializer.
118
+ def get_serializer(name)
119
+ if s = serializers[name]
120
+ s
121
+ else
122
+ Fields.traverse_association_tree(name, serializers, associations, aliased_associations)
123
+ end
91
124
  end
92
125
  end
93
126
  end
@@ -33,9 +33,10 @@ module Mongoid
33
33
  include Optional
34
34
 
35
35
  # @attribute [r] aliases The aliases.
36
- # @attribute [r] driver The Mongo driver being used.
36
+ attr_reader :aliases
37
+
37
38
  # @attribute [r] serializers The serializers.
38
- attr_reader :aliases, :driver, :serializers
39
+ attr_reader :serializers
39
40
 
40
41
  # Is this queryable equal to another object? Is true if the selector and
41
42
  # options are equal.
@@ -45,7 +46,7 @@ module Mongoid
45
46
  #
46
47
  # @param [ Object ] other The object to compare against.
47
48
  #
48
- # @return [ true, false ] If the objects are equal.
49
+ # @return [ true | false ] If the objects are equal.
49
50
  def ==(other)
50
51
  return false unless other.is_a?(Queryable)
51
52
  selector == other.selector && options == other.options
@@ -59,11 +60,15 @@ module Mongoid
59
60
  #
60
61
  # @param [ Hash ] aliases The optional field aliases.
61
62
  # @param [ Hash ] serializers The optional field serializers.
63
+ # @param [ Hash ] associations The optional associations.
64
+ # @param [ Hash ] aliased_associations The optional aliased associations.
62
65
  # @param [ Symbol ] driver The driver being used.
63
- def initialize(aliases = {}, serializers = {}, driver = :mongo)
64
- @aliases, @driver, @serializers = aliases, driver.to_sym, serializers
65
- @options = Options.new(aliases, serializers)
66
- @selector = Selector.new(aliases, serializers)
66
+ #
67
+ # @api private
68
+ def initialize(aliases = {}, serializers = {}, associations = {}, aliased_associations = {})
69
+ @aliases, @serializers = aliases, serializers
70
+ @options = Options.new(aliases, serializers, associations, aliased_associations)
71
+ @selector = Selector.new(aliases, serializers, associations, aliased_associations)
67
72
  @pipeline = Pipeline.new(aliases)
68
73
  @aggregating = nil
69
74
  yield(self) if block_given?
@@ -83,7 +83,7 @@ module Mongoid
83
83
  # @example Is the default scope applied?
84
84
  # criteria.scoped?
85
85
  #
86
- # @return [ true, false ] If the default scope is applied.
86
+ # @return [ true | false ] If the default scope is applied.
87
87
  def scoped?
88
88
  !!(defined?(@scoped) ? @scoped : nil)
89
89
  end
@@ -108,7 +108,7 @@ module Mongoid
108
108
  # @example Is the criteria unscoped?
109
109
  # criteria.unscoped?
110
110
  #
111
- # @return [ true, false ] If the criteria is force unscoped.
111
+ # @return [ true | false ] If the criteria is force unscoped.
112
112
  def unscoped?
113
113
  !!(defined?(@unscoped) ? @unscoped : nil)
114
114
  end