mongoid 7.4.0 → 8.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
@@ -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
@@ -18,7 +18,7 @@ module Mongoid
18
18
  # @return [ true ] True.
19
19
  def upsert(options = {})
20
20
  prepare_upsert(options) do
21
- collection.find(atomic_selector).update_one(
21
+ collection.find(atomic_selector).replace_one(
22
22
  as_attributes, upsert: true, session: _session)
23
23
  end
24
24
  end
@@ -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,13 +184,12 @@ 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.
174
191
  def set(object, options_or_context)
175
- key = "[mongoid][#{object.object_id}]:context"
176
- existing_context = Thread.current[key]
192
+ existing_context = get_context(object)
177
193
  existing_options = if existing_context
178
194
  existing_context.options
179
195
  else
@@ -184,7 +200,7 @@ module Mongoid
184
200
  end
185
201
  new_options = existing_options.merge(options_or_context)
186
202
  context = PersistenceContext.new(object, new_options)
187
- Thread.current[key] = context
203
+ store_context(object, context)
188
204
  end
189
205
 
190
206
  # Get the persistence context for a particular class or model instance.
@@ -196,7 +212,7 @@ module Mongoid
196
212
  #
197
213
  # @return [ Mongoid::PersistenceContext ] The persistence context for the object.
198
214
  def get(object)
199
- Thread.current["[mongoid][#{object.object_id}]:context"]
215
+ get_context(object)
200
216
  end
201
217
 
202
218
  # Clear the persistence context for a particular class or model instance.
@@ -204,18 +220,55 @@ module Mongoid
204
220
  # @example Clear the persistence context for a class or model instance.
205
221
  # PersistenceContext.clear(model)
206
222
  #
207
- # @param [ Class, Object ] object The class or model instance.
223
+ # @param [ Class | Object ] object The class or model instance.
208
224
  # @param [ Mongo::Cluster ] cluster The original cluster before this context was used.
209
225
  # @param [ Mongoid::PersistenceContext ] original_context The original persistence
210
226
  # context that was set before this context was used.
211
227
  def clear(object, cluster = nil, original_context = nil)
212
228
  if context = get(object)
213
229
  unless cluster.nil? || context.cluster.equal?(cluster)
214
- context.client.close
230
+ context.client.close unless context.reusable_client?
215
231
  end
216
232
  end
217
233
  ensure
218
- Thread.current["[mongoid][#{object.object_id}]:context"] = original_context
234
+ store_context(object, original_context)
235
+ end
236
+
237
+ private
238
+
239
+ # Key to store persistence contexts in the thread local storage.
240
+ #
241
+ # @api private
242
+ PERSISTENCE_CONTEXT_KEY = :"[mongoid]:persistence_context"
243
+
244
+ # Get the persistence context for a given object from the thread local
245
+ # storage.
246
+ #
247
+ # @param [ Object ] object Object to get the persistance context for.
248
+ #
249
+ # @return [ Mongoid::PersistenceContext | nil ] The persistence context
250
+ # for the object if previously stored, otherwise nil.
251
+ #
252
+ # @api private
253
+ def get_context(object)
254
+ Thread.current[PERSISTENCE_CONTEXT_KEY] ||= {}
255
+ Thread.current[PERSISTENCE_CONTEXT_KEY][object.object_id]
256
+ end
257
+
258
+ # Store persistence context for a given object in the thread local
259
+ # storage.
260
+ #
261
+ # @param [ Object ] object Object to store the persistance context for.
262
+ # @param [ Mongoid::PersistenceContext ] context Context to store
263
+ #
264
+ # @api private
265
+ def store_context(object, context)
266
+ if context.nil?
267
+ Thread.current[PERSISTENCE_CONTEXT_KEY]&.delete(object.object_id)
268
+ else
269
+ Thread.current[PERSISTENCE_CONTEXT_KEY] ||= {}
270
+ Thread.current[PERSISTENCE_CONTEXT_KEY][object.object_id] = context
271
+ end
219
272
  end
220
273
  end
221
274
  end