mongoid 7.5.0 → 8.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (358) 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 +47 -30
  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 +2 -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 -28
  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/changeable.rb +42 -7
  59. data/lib/mongoid/clients/options.rb +5 -1
  60. data/lib/mongoid/clients/sessions.rb +2 -14
  61. data/lib/mongoid/clients/validators/storage.rb +3 -3
  62. data/lib/mongoid/config/validators/client.rb +6 -6
  63. data/lib/mongoid/config.rb +27 -17
  64. data/lib/mongoid/contextual/aggregable/memory.rb +24 -16
  65. data/lib/mongoid/contextual/aggregable/mongo.rb +5 -5
  66. data/lib/mongoid/contextual/aggregable/none.rb +1 -1
  67. data/lib/mongoid/contextual/atomic.rb +1 -1
  68. data/lib/mongoid/contextual/geo_near.rb +7 -7
  69. data/lib/mongoid/contextual/map_reduce.rb +2 -2
  70. data/lib/mongoid/contextual/memory.rb +59 -32
  71. data/lib/mongoid/contextual/mongo.rb +184 -256
  72. data/lib/mongoid/contextual/none.rb +34 -16
  73. data/lib/mongoid/contextual/queryable.rb +1 -1
  74. data/lib/mongoid/contextual.rb +2 -2
  75. data/lib/mongoid/copyable.rb +32 -8
  76. data/lib/mongoid/criteria/findable.rb +7 -4
  77. data/lib/mongoid/criteria/includable.rb +24 -20
  78. data/lib/mongoid/criteria/marshalable.rb +10 -2
  79. data/lib/mongoid/criteria/permission.rb +1 -1
  80. data/lib/mongoid/criteria/queryable/aggregable.rb +2 -2
  81. data/lib/mongoid/criteria/queryable/extensions/array.rb +2 -15
  82. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -4
  83. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +2 -2
  84. data/lib/mongoid/criteria/queryable/extensions/date.rb +6 -1
  85. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +6 -1
  86. data/lib/mongoid/criteria/queryable/extensions/hash.rb +0 -16
  87. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -1
  88. data/lib/mongoid/criteria/queryable/extensions/object.rb +2 -1
  89. data/lib/mongoid/criteria/queryable/extensions/range.rb +13 -5
  90. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
  91. data/lib/mongoid/criteria/queryable/extensions/set.rb +1 -1
  92. data/lib/mongoid/criteria/queryable/extensions/string.rb +3 -3
  93. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +4 -2
  94. data/lib/mongoid/criteria/queryable/extensions/time.rb +6 -1
  95. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +6 -1
  96. data/lib/mongoid/criteria/queryable/key.rb +3 -3
  97. data/lib/mongoid/criteria/queryable/optional.rb +5 -11
  98. data/lib/mongoid/criteria/queryable/options.rb +2 -2
  99. data/lib/mongoid/criteria/queryable/pipeline.rb +1 -1
  100. data/lib/mongoid/criteria/queryable/selectable.rb +5 -27
  101. data/lib/mongoid/criteria/queryable/selector.rb +92 -7
  102. data/lib/mongoid/criteria/queryable/smash.rb +40 -7
  103. data/lib/mongoid/criteria/queryable.rb +12 -7
  104. data/lib/mongoid/criteria/scopable.rb +2 -2
  105. data/lib/mongoid/criteria.rb +15 -37
  106. data/lib/mongoid/deprecable.rb +36 -0
  107. data/lib/mongoid/deprecation.rb +25 -0
  108. data/lib/mongoid/document.rb +98 -36
  109. data/lib/mongoid/equality.rb +12 -12
  110. data/lib/mongoid/errors/document_not_found.rb +10 -6
  111. data/lib/mongoid/errors/invalid_config_option.rb +1 -1
  112. data/lib/mongoid/errors/invalid_dependent_strategy.rb +1 -1
  113. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
  114. data/lib/mongoid/errors/invalid_field.rb +6 -2
  115. data/lib/mongoid/errors/invalid_field_type.rb +26 -0
  116. data/lib/mongoid/errors/invalid_relation.rb +1 -1
  117. data/lib/mongoid/errors/invalid_relation_option.rb +1 -1
  118. data/lib/mongoid/errors/invalid_session_use.rb +1 -1
  119. data/lib/mongoid/errors/invalid_storage_options.rb +1 -1
  120. data/lib/mongoid/errors/mongoid_error.rb +3 -3
  121. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +1 -1
  122. data/lib/mongoid/errors/no_client_database.rb +1 -1
  123. data/lib/mongoid/errors/no_client_hosts.rb +1 -1
  124. data/lib/mongoid/errors/readonly_attribute.rb +1 -1
  125. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
  126. data/lib/mongoid/errors/unknown_attribute.rb +1 -1
  127. data/lib/mongoid/errors.rb +2 -2
  128. data/lib/mongoid/extensions/array.rb +9 -7
  129. data/lib/mongoid/extensions/big_decimal.rb +29 -10
  130. data/lib/mongoid/extensions/binary.rb +42 -0
  131. data/lib/mongoid/extensions/boolean.rb +8 -2
  132. data/lib/mongoid/extensions/date.rb +26 -20
  133. data/lib/mongoid/extensions/date_time.rb +1 -1
  134. data/lib/mongoid/extensions/false_class.rb +1 -1
  135. data/lib/mongoid/extensions/float.rb +4 -5
  136. data/lib/mongoid/extensions/hash.rb +13 -6
  137. data/lib/mongoid/extensions/integer.rb +4 -5
  138. data/lib/mongoid/extensions/module.rb +1 -1
  139. data/lib/mongoid/extensions/object.rb +8 -6
  140. data/lib/mongoid/extensions/range.rb +41 -10
  141. data/lib/mongoid/extensions/regexp.rb +11 -4
  142. data/lib/mongoid/extensions/set.rb +11 -4
  143. data/lib/mongoid/extensions/string.rb +11 -22
  144. data/lib/mongoid/extensions/symbol.rb +4 -15
  145. data/lib/mongoid/extensions/time.rb +27 -16
  146. data/lib/mongoid/extensions/time_with_zone.rb +1 -2
  147. data/lib/mongoid/extensions/true_class.rb +1 -1
  148. data/lib/mongoid/extensions.rb +1 -0
  149. data/lib/mongoid/factory.rb +42 -7
  150. data/lib/mongoid/fields/foreign_key.rb +11 -4
  151. data/lib/mongoid/fields/localized.rb +2 -2
  152. data/lib/mongoid/fields/standard.rb +7 -7
  153. data/lib/mongoid/fields/validators/macro.rb +3 -9
  154. data/lib/mongoid/fields.rb +57 -15
  155. data/lib/mongoid/findable.rb +28 -22
  156. data/lib/mongoid/indexable/specification.rb +2 -2
  157. data/lib/mongoid/indexable/validators/options.rb +6 -2
  158. data/lib/mongoid/interceptable.rb +73 -13
  159. data/lib/mongoid/matchable.rb +1 -1
  160. data/lib/mongoid/matcher.rb +12 -7
  161. data/lib/mongoid/persistable/creatable.rb +18 -9
  162. data/lib/mongoid/persistable/deletable.rb +1 -1
  163. data/lib/mongoid/persistable/destroyable.rb +1 -1
  164. data/lib/mongoid/persistable/savable.rb +2 -2
  165. data/lib/mongoid/persistable/unsettable.rb +1 -1
  166. data/lib/mongoid/persistable/updatable.rb +19 -12
  167. data/lib/mongoid/persistable/upsertable.rb +1 -1
  168. data/lib/mongoid/persistable.rb +3 -3
  169. data/lib/mongoid/persistence_context.rb +22 -5
  170. data/lib/mongoid/query_cache.rb +8 -260
  171. data/lib/mongoid/railties/controller_runtime.rb +1 -1
  172. data/lib/mongoid/reloadable.rb +7 -3
  173. data/lib/mongoid/scopable.rb +17 -15
  174. data/lib/mongoid/selectable.rb +1 -2
  175. data/lib/mongoid/serializable.rb +10 -6
  176. data/lib/mongoid/stateful.rb +35 -9
  177. data/lib/mongoid/tasks/database.rb +0 -2
  178. data/lib/mongoid/threaded/lifecycle.rb +5 -5
  179. data/lib/mongoid/threaded.rb +9 -9
  180. data/lib/mongoid/timestamps/created.rb +1 -1
  181. data/lib/mongoid/timestamps/updated.rb +2 -2
  182. data/lib/mongoid/touchable.rb +2 -3
  183. data/lib/mongoid/traversable.rb +4 -3
  184. data/lib/mongoid/validatable/localizable.rb +1 -1
  185. data/lib/mongoid/validatable/macros.rb +0 -2
  186. data/lib/mongoid/validatable/presence.rb +2 -2
  187. data/lib/mongoid/validatable/uniqueness.rb +9 -8
  188. data/lib/mongoid/validatable.rb +6 -6
  189. data/lib/mongoid/version.rb +1 -1
  190. data/lib/mongoid/warnings.rb +3 -4
  191. data/lib/mongoid.rb +1 -0
  192. data/spec/config/mongoid.yml +16 -0
  193. data/spec/integration/app_spec.rb +8 -12
  194. data/spec/integration/associations/belongs_to_spec.rb +18 -0
  195. data/spec/integration/associations/embedded_spec.rb +15 -0
  196. data/spec/integration/associations/embeds_many_spec.rb +15 -2
  197. data/spec/integration/associations/embeds_one_spec.rb +18 -0
  198. data/spec/integration/associations/foreign_key_spec.rb +9 -0
  199. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
  200. data/spec/integration/associations/has_one_spec.rb +97 -1
  201. data/spec/integration/associations/scope_option_spec.rb +1 -1
  202. data/spec/integration/callbacks_models.rb +95 -1
  203. data/spec/integration/callbacks_spec.rb +226 -4
  204. data/spec/integration/criteria/range_spec.rb +95 -1
  205. data/spec/integration/discriminator_key_spec.rb +115 -76
  206. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  207. data/spec/integration/i18n_fallbacks_spec.rb +1 -15
  208. data/spec/integration/matcher_examples_spec.rb +20 -13
  209. data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
  210. data/spec/integration/matcher_operator_spec.rb +3 -5
  211. data/spec/integration/persistence/range_field_spec.rb +350 -0
  212. data/spec/mongoid/association/counter_cache_spec.rb +1 -1
  213. data/spec/mongoid/association/depending_spec.rb +9 -9
  214. data/spec/mongoid/association/eager_spec.rb +2 -1
  215. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
  216. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
  217. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +69 -9
  218. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
  219. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +219 -8
  220. data/spec/mongoid/association/embedded/embeds_many_models.rb +157 -0
  221. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +12 -0
  222. data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
  223. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
  224. data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
  225. data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
  226. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
  227. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
  228. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +15 -0
  229. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  230. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -2
  231. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +67 -4
  232. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
  233. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
  234. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
  235. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +2 -56
  236. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +82 -13
  237. data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
  238. data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
  239. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
  240. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
  241. data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
  242. data/spec/mongoid/association/syncable_spec.rb +14 -0
  243. data/spec/mongoid/atomic/paths_spec.rb +0 -14
  244. data/spec/mongoid/attributes/nested_spec.rb +80 -11
  245. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  246. data/spec/mongoid/attributes/projector_spec.rb +1 -5
  247. data/spec/mongoid/attributes_spec.rb +524 -27
  248. data/spec/mongoid/changeable_spec.rb +130 -13
  249. data/spec/mongoid/clients/factory_spec.rb +23 -30
  250. data/spec/mongoid/clients/sessions_spec.rb +0 -38
  251. data/spec/mongoid/clients_spec.rb +32 -2
  252. data/spec/mongoid/config_spec.rb +58 -13
  253. data/spec/mongoid/contextual/aggregable/memory_spec.rb +396 -158
  254. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  255. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  256. data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
  257. data/spec/mongoid/contextual/memory_spec.rb +521 -14
  258. data/spec/mongoid/contextual/mongo_spec.rb +564 -394
  259. data/spec/mongoid/contextual/none_spec.rb +11 -19
  260. data/spec/mongoid/copyable_spec.rb +451 -1
  261. data/spec/mongoid/criteria/findable_spec.rb +86 -210
  262. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  263. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  264. data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
  265. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
  266. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
  267. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
  268. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
  269. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
  270. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
  271. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
  272. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
  273. data/spec/mongoid/criteria/queryable/optional_spec.rb +0 -484
  274. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +50 -0
  275. data/spec/mongoid/criteria/queryable/selectable_spec.rb +77 -85
  276. data/spec/mongoid/criteria/queryable/selector_spec.rb +14 -2
  277. data/spec/mongoid/criteria_spec.rb +469 -1201
  278. data/spec/mongoid/document_fields_spec.rb +173 -24
  279. data/spec/mongoid/document_spec.rb +32 -41
  280. data/spec/mongoid/equality_spec.rb +12 -12
  281. data/spec/mongoid/errors/document_not_found_spec.rb +29 -2
  282. data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
  283. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  284. data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
  285. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  286. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
  287. data/spec/mongoid/extensions/array_spec.rb +16 -2
  288. data/spec/mongoid/extensions/big_decimal_spec.rb +697 -212
  289. data/spec/mongoid/extensions/binary_spec.rb +44 -9
  290. data/spec/mongoid/extensions/boolean_spec.rb +68 -82
  291. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
  292. data/spec/mongoid/extensions/date_spec.rb +71 -1
  293. data/spec/mongoid/extensions/date_time_spec.rb +15 -9
  294. data/spec/mongoid/extensions/float_spec.rb +48 -76
  295. data/spec/mongoid/extensions/hash_spec.rb +30 -0
  296. data/spec/mongoid/extensions/integer_spec.rb +45 -66
  297. data/spec/mongoid/extensions/range_spec.rb +255 -54
  298. data/spec/mongoid/extensions/regexp_spec.rb +58 -33
  299. data/spec/mongoid/extensions/set_spec.rb +106 -0
  300. data/spec/mongoid/extensions/string_spec.rb +53 -25
  301. data/spec/mongoid/extensions/symbol_spec.rb +18 -25
  302. data/spec/mongoid/extensions/time_spec.rb +634 -66
  303. data/spec/mongoid/extensions/time_with_zone_spec.rb +17 -31
  304. data/spec/mongoid/factory_spec.rb +61 -1
  305. data/spec/mongoid/fields_spec.rb +321 -50
  306. data/spec/mongoid/findable_spec.rb +64 -29
  307. data/spec/mongoid/indexable/specification_spec.rb +2 -2
  308. data/spec/mongoid/indexable_spec.rb +39 -20
  309. data/spec/mongoid/interceptable_spec.rb +584 -5
  310. data/spec/mongoid/interceptable_spec_models.rb +235 -4
  311. data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
  312. data/spec/mongoid/mongoizable_spec.rb +285 -0
  313. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  314. data/spec/mongoid/persistable/deletable_spec.rb +2 -2
  315. data/spec/mongoid/persistable/destroyable_spec.rb +2 -2
  316. data/spec/mongoid/persistable/upsertable_spec.rb +14 -0
  317. data/spec/mongoid/persistence_context_spec.rb +50 -1
  318. data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
  319. data/spec/mongoid/query_cache_spec.rb +0 -154
  320. data/spec/mongoid/reloadable_spec.rb +35 -2
  321. data/spec/mongoid/scopable_spec.rb +54 -16
  322. data/spec/mongoid/shardable_spec.rb +14 -0
  323. data/spec/mongoid/stateful_spec.rb +28 -0
  324. data/spec/mongoid/timestamps_spec.rb +390 -0
  325. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  326. data/spec/mongoid/touchable_spec.rb +116 -0
  327. data/spec/mongoid/touchable_spec_models.rb +12 -8
  328. data/spec/mongoid/traversable_spec.rb +4 -11
  329. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  330. data/spec/mongoid/validatable/uniqueness_spec.rb +60 -31
  331. data/spec/mongoid/warnings_spec.rb +35 -0
  332. data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
  333. data/spec/rails/mongoid_spec.rb +4 -16
  334. data/spec/shared/lib/mrss/event_subscriber.rb +5 -15
  335. data/spec/support/constraints.rb +24 -0
  336. data/spec/support/macros.rb +30 -0
  337. data/spec/support/models/augmentation.rb +12 -0
  338. data/spec/support/models/band.rb +3 -0
  339. data/spec/support/models/catalog.rb +24 -0
  340. data/spec/support/models/circus.rb +3 -0
  341. data/spec/support/models/fanatic.rb +8 -0
  342. data/spec/support/models/implant.rb +9 -0
  343. data/spec/support/models/label.rb +2 -0
  344. data/spec/support/models/passport.rb +9 -0
  345. data/spec/support/models/person.rb +1 -0
  346. data/spec/support/models/player.rb +2 -0
  347. data/spec/support/models/powerup.rb +12 -0
  348. data/spec/support/models/registry.rb +1 -0
  349. data/spec/support/models/school.rb +14 -0
  350. data/spec/support/models/shield.rb +18 -0
  351. data/spec/support/models/student.rb +14 -0
  352. data/spec/support/models/weapon.rb +12 -0
  353. data.tar.gz.sig +0 -0
  354. metadata +49 -13
  355. metadata.gz.sig +0 -0
  356. data/lib/mongoid/errors/eager_load.rb +0 -23
  357. data/lib/mongoid/errors/invalid_value.rb +0 -17
  358. data/spec/mongoid/errors/eager_load_spec.rb +0 -31
@@ -13,7 +13,6 @@ module Mongoid
13
13
  :database,
14
14
  :default_language,
15
15
  :language_override,
16
- :drop_dups,
17
16
  :name,
18
17
  :sparse,
19
18
  :unique,
@@ -29,7 +28,8 @@ module Mongoid
29
28
  :text_version,
30
29
  :version,
31
30
  :partial_filter_expression,
32
- :collation
31
+ :collation,
32
+ :wildcard_projection,
33
33
  ]
34
34
 
35
35
  VALID_TYPES = [
@@ -98,6 +98,10 @@ module Mongoid
98
98
  unless VALID_TYPES.include?(value)
99
99
  raise Errors::InvalidIndex.new(klass, spec, options)
100
100
  end
101
+
102
+ if value == "geoHaystack"
103
+ Mongoid::Warnings.warn_geo_haystack_deprecated
104
+ end
101
105
  end
102
106
  end
103
107
  end
@@ -27,7 +27,7 @@ module Mongoid
27
27
  :before_save,
28
28
  :before_update,
29
29
  :before_upsert,
30
- :before_validation
30
+ :before_validation,
31
31
  ].freeze
32
32
 
33
33
  included do
@@ -37,6 +37,12 @@ module Mongoid
37
37
  define_model_callbacks :build, :find, :initialize, :touch, only: :after
38
38
  define_model_callbacks :create, :destroy, :save, :update, :upsert
39
39
 
40
+ # This callback is used internally by Mongoid to save association
41
+ # targets for referenced associations after the parent model is persisted.
42
+ #
43
+ # @api private
44
+ define_model_callbacks :persist_parent
45
+
40
46
  attr_accessor :before_callback_halted
41
47
  end
42
48
 
@@ -47,7 +53,7 @@ module Mongoid
47
53
  #
48
54
  # @param [ Symbol ] kind The type of callback.
49
55
  #
50
- # @return [ true, false ] If the callback can be executed.
56
+ # @return [ true | false ] If the callback can be executed.
51
57
  def callback_executable?(kind)
52
58
  respond_to?("_#{kind}_callbacks")
53
59
  end
@@ -60,7 +66,7 @@ module Mongoid
60
66
  #
61
67
  # @param [ Symbol ] kind The callback kind.
62
68
  #
63
- # @return [ true, false ] If the document is in a callback state.
69
+ # @return [ true | false ] If the document is in a callback state.
64
70
  def in_callback_state?(kind)
65
71
  [ :create, :destroy ].include?(kind) || new_record? || flagged_for_destroy? || changed?
66
72
  end
@@ -109,22 +115,76 @@ module Mongoid
109
115
  # end
110
116
  #
111
117
  # @param [ Symbol ] kind The type of callback to execute.
112
- # @param [ Array ] args Any options.
113
- #
114
- # @return [ Document ] The document
115
- ruby2_keywords def run_callbacks(kind, *args, &block)
116
- cascadable_children(kind).each do |child|
117
- if child.run_callbacks(child_callback_type(kind, child), *args) == false
118
- return false
118
+ # @param [ true | false ] with_children Flag specifies whether callbacks of embedded document should be run.
119
+ def run_callbacks(kind, with_children: true, &block)
120
+ if with_children
121
+ cascadable_children(kind).each do |child|
122
+ if child.run_callbacks(child_callback_type(kind, child), with_children: with_children) == false
123
+ return false
124
+ end
119
125
  end
120
126
  end
121
127
  if callback_executable?(kind)
122
- super(kind, *args, &block)
128
+ super(kind, &block)
123
129
  else
124
130
  true
125
131
  end
126
132
  end
127
133
 
134
+ # Run the callbacks for embedded documents.
135
+ #
136
+ # @param [ Symbol ] kind The type of callback to execute.
137
+ # @param [ Array<Document> ] children Children to exeute callbacks on. If
138
+ # nil, callbacks will be executed on all cascadable children of
139
+ # the document.
140
+ #
141
+ # @api private
142
+ def _mongoid_run_child_callbacks(kind, children: nil, &block)
143
+ child, *tail = (children || cascadable_children(kind))
144
+ if child.nil?
145
+ return block&.call
146
+ elsif tail.empty?
147
+ return child.run_callbacks(child_callback_type(kind, child), &block)
148
+ else
149
+ return child.run_callbacks(child_callback_type(kind, child)) do
150
+ _mongoid_run_child_callbacks(kind, children: tail, &block)
151
+ end
152
+ end
153
+ end
154
+
155
+ # This is used to store callbacks to be executed later. A good use case for
156
+ # this is delaying the after_find and after_initialize callbacks until the
157
+ # associations are set on the document. This can also be used to delay
158
+ # applying the defaults on a document.
159
+ #
160
+ # @return [ Array<Symbol> ] an array of symbols that represent the pending callbacks.
161
+ #
162
+ # @api private
163
+ def pending_callbacks
164
+ @pending_callbacks ||= [].to_set
165
+ end
166
+
167
+ # @api private
168
+ def pending_callbacks=(value)
169
+ @pending_callbacks = value
170
+ end
171
+
172
+ # Run the pending callbacks. If the callback is :apply_defaults, we will apply
173
+ # the defaults for this document. Otherwise, the callback is passed to the
174
+ # run_callbacks function.
175
+ #
176
+ # @api private
177
+ def run_pending_callbacks
178
+ pending_callbacks.each do |cb|
179
+ if [:apply_defaults, :apply_post_processed_defaults].include?(cb)
180
+ send(cb)
181
+ else
182
+ self.run_callbacks(cb, with_children: false)
183
+ end
184
+ end
185
+ pending_callbacks.clear
186
+ end
187
+
128
188
  private
129
189
 
130
190
  # We need to hook into this for autosave, since we don't want it firing if
@@ -135,7 +195,7 @@ module Mongoid
135
195
  # @example Was a before callback halted?
136
196
  # document.before_callback_halted?
137
197
  #
138
- # @return [ true, false ] If a before callback was halted.
198
+ # @return [ true | false ] If a before callback was halted.
139
199
  def before_callback_halted?
140
200
  !!@before_callback_halted
141
201
  end
@@ -175,7 +235,7 @@ module Mongoid
175
235
  # @param [ Symbol ] kind The type of callback.
176
236
  # @param [ Document ] child The child document.
177
237
  #
178
- # @return [ true, false ] If the child should fire the callback.
238
+ # @return [ true | false ] If the child should fire the callback.
179
239
  def cascadable_child?(kind, child, association)
180
240
  return false if kind == :initialize || kind == :find || kind == :touch
181
241
  return false if kind == :validate && association.validate?
@@ -15,7 +15,7 @@ module Mongoid
15
15
  #
16
16
  # @param [ Hash ] selector The MongoDB selector.
17
17
  #
18
- # @return [ true, false ] True if matches, false if not.
18
+ # @return [ true | false ] True if matches, false if not.
19
19
  def _matches?(selector)
20
20
  Matcher::Expression.matches?(self, selector)
21
21
  end
@@ -24,17 +24,22 @@ module Mongoid
24
24
  # an array of values of the `bar` field in each of the hashes in the
25
25
  # `foo` array.
26
26
  #
27
- # The return value is a two-element array. The first element is the value
28
- # retrieved, or an array of values. The second element is a boolean flag
29
- # indicating whether an array was expanded at any point during the key
30
- # traversal (because the respective document field was an array).
27
+ # This method can return an individual field value in some document
28
+ # or an array of values from multiple documents. The array can be returned
29
+ # because a field value in the specified path is an array of primitive
30
+ # values (e.g. integers) or because a field value in the specified path
31
+ # is an array of documents (e.g. a one-to-many embedded association),
32
+ # in which case the leaf value may be a scalar for each individual document.
33
+ # If the leaf value is an array and a one-to-many association was traversed,
34
+ # the return value will be an array of arrays. Note that an individual
35
+ # field value can also be an array and this case is indistinguishable
36
+ # from and behaves identically to association traversal for the purposes
37
+ # of, for example, subsequent array element retrieval.
31
38
  #
32
39
  # @param [ Document | Hash ] document The document to extract from.
33
40
  # @param [ String ] key The key path to extract.
34
41
  #
35
- # @return [ Array<true | false, Object | Array, true | false> ]
36
- # Whether the value existed in the document, the extracted value
37
- # and the array expansion flag.
42
+ # @return [ Object | Array ] Field value or values.
38
43
  module_function def extract_attribute(document, key)
39
44
  if document.respond_to?(:as_attributes, true)
40
45
  # If a document has hash fields, as_attributes would keep those fields
@@ -102,13 +102,22 @@ module Mongoid
102
102
  def prepare_insert(options = {})
103
103
  return self if performing_validations?(options) &&
104
104
  invalid?(options[:context] || :create)
105
- result = run_callbacks(:save) do
106
- run_callbacks(:create) do
107
- yield(self)
108
- post_process_insert
105
+ run_callbacks(:save, with_children: false) do
106
+ run_callbacks(:create, with_children: false) do
107
+ run_callbacks(:persist_parent, with_children: false) do
108
+ _mongoid_run_child_callbacks(:save) do
109
+ _mongoid_run_child_callbacks(:create) do
110
+ result = yield(self)
111
+ if !result.is_a?(Document) || result.errors.empty?
112
+ post_process_insert
113
+ post_process_persist(result, options)
114
+ end
115
+ end
116
+ end
117
+ end
109
118
  end
110
119
  end
111
- post_process_persist(result, options) and self
120
+ self
112
121
  end
113
122
 
114
123
  module ClassMethods
@@ -123,10 +132,10 @@ module Mongoid
123
132
  # @example Create multiple new documents.
124
133
  # Person.create({ title: "Mr" }, { title: "Mrs" })
125
134
  #
126
- # @param [ Hash, Array ] attributes The attributes to create with, or an
135
+ # @param [ Hash | Array ] attributes The attributes to create with, or an
127
136
  # Array of multiple attributes for multiple documents.
128
137
  #
129
- # @return [ Document, Array<Document> ] The newly created document(s).
138
+ # @return [ Document | Array<Document> ] The newly created document(s).
130
139
  def create(attributes = nil, &block)
131
140
  _creating do
132
141
  if attributes.is_a?(::Array)
@@ -150,10 +159,10 @@ module Mongoid
150
159
  # @example Create multiple new documents.
151
160
  # Person.create!({ title: "Mr" }, { title: "Mrs" })
152
161
  #
153
- # @param [ Hash, Array ] attributes The attributes to create with, or an
162
+ # @param [ Hash | Array ] attributes The attributes to create with, or an
154
163
  # Array of multiple attributes for multiple documents.
155
164
  #
156
- # @return [ Document, Array<Document> ] The newly created document(s).
165
+ # @return [ Document | Array<Document> ] The newly created document(s).
157
166
  def create!(attributes = nil, &block)
158
167
  _creating do
159
168
  if attributes.is_a?(::Array)
@@ -86,7 +86,7 @@ module Mongoid
86
86
  #
87
87
  # @param [ Hash ] options The delete options.
88
88
  #
89
- # @return [ true, false ] If the parent should be notified.
89
+ # @return [ true | false ] If the parent should be notified.
90
90
  def notifying_parent?(options = {})
91
91
  !options.delete(:suppress)
92
92
  end
@@ -14,7 +14,7 @@ module Mongoid
14
14
  #
15
15
  # @param [ Hash ] options Options to pass to destroy.
16
16
  #
17
- # @return [ true, false ] True if successful, false if not.
17
+ # @return [ true | false ] True if successful, false if not.
18
18
  def destroy(options = nil)
19
19
  raise Errors::ReadonlyDocument.new(self.class) if readonly?
20
20
  self.flagged_for_destroy = true
@@ -14,7 +14,7 @@ module Mongoid
14
14
  #
15
15
  # @param [ Hash ] options Options to pass to the save.
16
16
  #
17
- # @return [ true, false ] True is success, false if not.
17
+ # @return [ true | false ] True is success, false if not.
18
18
  def save(options = {})
19
19
  if new_record?
20
20
  !insert(options).new_record?
@@ -34,7 +34,7 @@ module Mongoid
34
34
  # @raise [ Errors::Validations ] If validation failed.
35
35
  # @raise [ Errors::Callback ] If a callback returns false.
36
36
  #
37
- # @return [ true, false ] True if validation passed.
37
+ # @return [ true | false ] True if validation passed.
38
38
  def save!(options = {})
39
39
  unless save(options)
40
40
  fail_due_to_validation! unless errors.empty?
@@ -13,7 +13,7 @@ module Mongoid
13
13
  # @example Unset the values.
14
14
  # document.unset(:first_name, :last_name, :middle)
15
15
  #
16
- # @param [ Array<String, Symbol> ] fields The names of the fields to
16
+ # @param [ Array<String | Symbol> ] fields The names of the fields to
17
17
  # unset.
18
18
  #
19
19
  # @return [ Document ] The document.
@@ -13,13 +13,13 @@ module Mongoid
13
13
  # @example Update the attribute.
14
14
  # person.update_attribute(:title, "Sir")
15
15
  #
16
- # @param [ Symbol, String ] name The name of the attribute.
16
+ # @param [ Symbol | String ] name The name of the attribute.
17
17
  # @param [ Object ] value The new value of the attribute.a
18
18
  #
19
19
  # @raise [ Errors::ReadonlyAttribute ] If the field cannot be changed due
20
20
  # to being flagged as read-only.
21
21
  #
22
- # @return [ true, false ] True if save was successful, false if not.
22
+ # @return [ true | false ] True if save was successful, false if not.
23
23
  def update_attribute(name, value)
24
24
  as_writable_attribute!(name, value) do |access|
25
25
  normalized = name.to_s
@@ -35,7 +35,7 @@ module Mongoid
35
35
  #
36
36
  # @param [ Hash ] attributes The attributes to update.
37
37
  #
38
- # @return [ true, false ] True if validation passed, false if not.
38
+ # @return [ true | false ] True if validation passed, false if not.
39
39
  def update(attributes = {})
40
40
  assign_attributes(attributes)
41
41
  save
@@ -53,7 +53,7 @@ module Mongoid
53
53
  # @raise [ Errors::Validations ] If validation failed.
54
54
  # @raise [ Errors::Callbacks ] If a callback returns false.
55
55
  #
56
- # @return [ true, false ] True if validation passed.
56
+ # @return [ true | false ] True if validation passed.
57
57
  def update!(attributes = {})
58
58
  result = update_attributes(attributes)
59
59
  unless result
@@ -91,18 +91,25 @@ module Mongoid
91
91
  #
92
92
  # @param [ Hash ] options The options.
93
93
  #
94
- # @return [ true, false ] The result of the update.
94
+ # @return [ true | false ] The result of the update.
95
95
  def prepare_update(options = {})
96
96
  return false if performing_validations?(options) &&
97
97
  invalid?(options[:context] || :update)
98
98
  process_flagged_destroys
99
- result = run_callbacks(:save) do
100
- run_callbacks(:update) do
101
- yield(self)
102
- true
99
+ run_callbacks(:save, with_children: false) do
100
+ run_callbacks(:update, with_children: false) do
101
+ run_callbacks(:persist_parent, with_children: false) do
102
+ _mongoid_run_child_callbacks(:save) do
103
+ _mongoid_run_child_callbacks(:update) do
104
+ result = yield(self)
105
+ self.previously_new_record = false
106
+ post_process_persist(result, options)
107
+ true
108
+ end
109
+ end
110
+ end
103
111
  end
104
112
  end
105
- post_process_persist(result, options) and result
106
113
  end
107
114
 
108
115
  # Update the document in the database.
@@ -112,9 +119,9 @@ module Mongoid
112
119
  #
113
120
  # @param [ Hash ] options Options to pass to update.
114
121
  #
115
- # @option options [ true, false ] :validate Whether or not to validate.
122
+ # @option options [ true | false ] :validate Whether or not to validate.
116
123
  #
117
- # @return [ true, false ] True if succeeded, false if not.
124
+ # @return [ true | false ] True if succeeded, false if not.
118
125
  def update_document(options = {})
119
126
  prepare_update(options) do
120
127
  updates, conflicts = init_atomic_updates
@@ -36,7 +36,7 @@ module Mongoid
36
36
  #
37
37
  # @param [ Hash ] options The options hash.
38
38
  #
39
- # @return [ true, false ] If the operation succeeded.
39
+ # @return [ true | false ] If the operation succeeded.
40
40
  def prepare_upsert(options = {})
41
41
  return false if performing_validations?(options) && invalid?(:upsert)
42
42
  result = run_callbacks(:upsert) do
@@ -79,11 +79,11 @@ module Mongoid
79
79
  # document.set name: "Tool"
80
80
  # end
81
81
  #
82
- # @param [ true, false ] join_context Join the context (i.e. merge
82
+ # @param [ true | false ] join_context Join the context (i.e. merge
83
83
  # declared atomic operations) of the atomically block wrapping this one
84
84
  # for the same document, if one exists.
85
85
  #
86
- # @return [ true, false ] If the operation succeeded.
86
+ # @return [ true | false ] If the operation succeeded.
87
87
  def atomically(join_context: nil)
88
88
  join_context = Mongoid.join_contexts if join_context.nil?
89
89
  call_depth = @atomic_depth ||= 0
@@ -146,7 +146,7 @@ module Mongoid
146
146
  # @example Are we executing atomically?
147
147
  # document.executing_atomically?
148
148
  #
149
- # @return [ true, false ] If we are current executing atomically.
149
+ # @return [ true | false ] If we are current executing atomically.
150
150
  def executing_atomically?
151
151
  !@atomic_updates_to_execute_stack.nil?
152
152
  end
@@ -57,7 +57,9 @@ module Mongoid
57
57
  # @return [ Mongo::Collection ] The collection for this persistence
58
58
  # context.
59
59
  def collection(parent = nil)
60
- parent ? parent.collection.with(client_options) : client[collection_name.to_sym]
60
+ parent ?
61
+ parent.collection.with(client_options.except(:database, "database")) :
62
+ client[collection_name.to_sym]
61
63
  end
62
64
 
63
65
  # Get the collection name for this persistence context.
@@ -116,12 +118,27 @@ module Mongoid
116
118
  #
117
119
  # @param [ Object ] other The object to be compared with this one.
118
120
  #
119
- # @return [ true, false ] Whether the two persistence contexts are equal.
121
+ # @return [ true | false ] Whether the two persistence contexts are equal.
120
122
  def ==(other)
121
123
  return false unless other.is_a?(PersistenceContext)
122
124
  options == other.options
123
125
  end
124
126
 
127
+ # Whether the client of the context can be reused later, and therefore should
128
+ # not be closed.
129
+ #
130
+ # If the persistence context is requested with :client option only, it means
131
+ # that the context should use a client configured in mongoid.yml.
132
+ # Such clients should not be closed when the context is cleared since they
133
+ # will be reused later.
134
+ #
135
+ # @return [ true | false ] True if client can be reused, otherwise false.
136
+ #
137
+ # @api private
138
+ def reusable_client?
139
+ @options.keys == [:client]
140
+ end
141
+
125
142
  private
126
143
 
127
144
  def set_options!(opts)
@@ -167,7 +184,7 @@ module Mongoid
167
184
  # PersistenceContext.set(model)
168
185
  #
169
186
  # @param [ Object ] object The class or model instance.
170
- # @param [ Hash, Mongoid::PersistenceContext ] options_or_context The persistence
187
+ # @param [ Hash | Mongoid::PersistenceContext ] options_or_context The persistence
171
188
  # options or a persistence context object.
172
189
  #
173
190
  # @return [ Mongoid::PersistenceContext ] The persistence context for the object.
@@ -204,14 +221,14 @@ module Mongoid
204
221
  # @example Clear the persistence context for a class or model instance.
205
222
  # PersistenceContext.clear(model)
206
223
  #
207
- # @param [ Class, Object ] object The class or model instance.
224
+ # @param [ Class | Object ] object The class or model instance.
208
225
  # @param [ Mongo::Cluster ] cluster The original cluster before this context was used.
209
226
  # @param [ Mongoid::PersistenceContext ] original_context The original persistence
210
227
  # context that was set before this context was used.
211
228
  def clear(object, cluster = nil, original_context = nil)
212
229
  if context = get(object)
213
230
  unless cluster.nil? || context.cluster.equal?(cluster)
214
- context.client.close
231
+ context.client.close unless context.reusable_client?
215
232
  end
216
233
  end
217
234
  ensure