mongoid 7.5.4 → 8.1.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 (421) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +3 -3
  4. data/README.md +6 -6
  5. data/lib/config/locales/en.yml +92 -43
  6. data/lib/mongoid/association/accessors.rb +40 -11
  7. data/lib/mongoid/association/bindable.rb +50 -2
  8. data/lib/mongoid/association/builders.rb +5 -3
  9. data/lib/mongoid/association/constrainable.rb +0 -1
  10. data/lib/mongoid/association/eager_loadable.rb +29 -7
  11. data/lib/mongoid/association/embedded/batchable.rb +34 -11
  12. data/lib/mongoid/association/embedded/cyclic.rb +1 -1
  13. data/lib/mongoid/association/embedded/embedded_in/binding.rb +24 -2
  14. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +2 -2
  15. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +4 -3
  16. data/lib/mongoid/association/embedded/embedded_in.rb +3 -2
  17. data/lib/mongoid/association/embedded/embeds_many/binding.rb +1 -0
  18. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +4 -3
  19. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +69 -45
  20. data/lib/mongoid/association/embedded/embeds_many.rb +2 -2
  21. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +19 -5
  22. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +24 -5
  23. data/lib/mongoid/association/embedded/embeds_one.rb +3 -3
  24. data/lib/mongoid/association/macros.rb +8 -1
  25. data/lib/mongoid/association/many.rb +11 -7
  26. data/lib/mongoid/association/nested/many.rb +5 -4
  27. data/lib/mongoid/association/nested/nested_buildable.rb +4 -4
  28. data/lib/mongoid/association/nested/one.rb +45 -7
  29. data/lib/mongoid/association/one.rb +2 -2
  30. data/lib/mongoid/association/options.rb +9 -9
  31. data/lib/mongoid/association/proxy.rb +15 -4
  32. data/lib/mongoid/association/referenced/auto_save.rb +4 -3
  33. data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
  34. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
  35. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +5 -6
  36. data/lib/mongoid/association/referenced/belongs_to.rb +2 -2
  37. data/lib/mongoid/association/referenced/counter_cache.rb +10 -10
  38. data/lib/mongoid/association/referenced/eager.rb +2 -2
  39. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +70 -13
  40. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +6 -3
  41. data/lib/mongoid/association/referenced/has_many/enumerable.rb +22 -30
  42. data/lib/mongoid/association/referenced/has_many/proxy.rb +29 -19
  43. data/lib/mongoid/association/referenced/has_many.rb +3 -3
  44. data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -1
  45. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +5 -5
  46. data/lib/mongoid/association/referenced/has_one/proxy.rb +9 -12
  47. data/lib/mongoid/association/referenced/has_one.rb +3 -3
  48. data/lib/mongoid/association/referenced/syncable.rb +4 -4
  49. data/lib/mongoid/association/reflections.rb +4 -4
  50. data/lib/mongoid/association/relatable.rb +44 -10
  51. data/lib/mongoid/association.rb +5 -5
  52. data/lib/mongoid/atomic/modifiers.rb +2 -2
  53. data/lib/mongoid/atomic.rb +7 -0
  54. data/lib/mongoid/attributes/dynamic.rb +4 -4
  55. data/lib/mongoid/attributes/nested.rb +6 -6
  56. data/lib/mongoid/attributes/processing.rb +37 -6
  57. data/lib/mongoid/attributes/projector.rb +2 -2
  58. data/lib/mongoid/attributes/readonly.rb +3 -3
  59. data/lib/mongoid/attributes.rb +51 -42
  60. data/lib/mongoid/changeable.rb +147 -14
  61. data/lib/mongoid/clients/options.rb +5 -1
  62. data/lib/mongoid/clients/sessions.rb +2 -14
  63. data/lib/mongoid/clients/storage_options.rb +2 -5
  64. data/lib/mongoid/clients/validators/storage.rb +3 -15
  65. data/lib/mongoid/collection_configurable.rb +58 -0
  66. data/lib/mongoid/composable.rb +2 -0
  67. data/lib/mongoid/config/defaults.rb +60 -0
  68. data/lib/mongoid/config/options.rb +3 -0
  69. data/lib/mongoid/config/validators/async_query_executor.rb +24 -0
  70. data/lib/mongoid/config/validators/client.rb +6 -6
  71. data/lib/mongoid/config/validators.rb +1 -0
  72. data/lib/mongoid/config.rb +153 -18
  73. data/lib/mongoid/contextual/aggregable/memory.rb +24 -16
  74. data/lib/mongoid/contextual/aggregable/mongo.rb +5 -5
  75. data/lib/mongoid/contextual/aggregable/none.rb +1 -1
  76. data/lib/mongoid/contextual/atomic.rb +1 -1
  77. data/lib/mongoid/contextual/geo_near.rb +7 -7
  78. data/lib/mongoid/contextual/map_reduce.rb +2 -2
  79. data/lib/mongoid/contextual/memory.rb +285 -58
  80. data/lib/mongoid/contextual/mongo/documents_loader.rb +177 -0
  81. data/lib/mongoid/contextual/mongo.rb +540 -346
  82. data/lib/mongoid/contextual/none.rb +193 -20
  83. data/lib/mongoid/contextual/queryable.rb +1 -1
  84. data/lib/mongoid/contextual.rb +14 -2
  85. data/lib/mongoid/copyable.rb +32 -8
  86. data/lib/mongoid/criteria/findable.rb +8 -5
  87. data/lib/mongoid/criteria/includable.rb +27 -22
  88. data/lib/mongoid/criteria/marshalable.rb +10 -2
  89. data/lib/mongoid/criteria/permission.rb +1 -1
  90. data/lib/mongoid/criteria/queryable/aggregable.rb +2 -2
  91. data/lib/mongoid/criteria/queryable/extensions/array.rb +3 -16
  92. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -4
  93. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +2 -2
  94. data/lib/mongoid/criteria/queryable/extensions/date.rb +6 -1
  95. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +6 -1
  96. data/lib/mongoid/criteria/queryable/extensions/hash.rb +1 -17
  97. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -9
  98. data/lib/mongoid/criteria/queryable/extensions/object.rb +2 -1
  99. data/lib/mongoid/criteria/queryable/extensions/range.rb +13 -5
  100. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
  101. data/lib/mongoid/criteria/queryable/extensions/set.rb +1 -1
  102. data/lib/mongoid/criteria/queryable/extensions/string.rb +4 -14
  103. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +4 -12
  104. data/lib/mongoid/criteria/queryable/extensions/time.rb +6 -1
  105. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +6 -1
  106. data/lib/mongoid/criteria/queryable/key.rb +4 -4
  107. data/lib/mongoid/criteria/queryable/mergeable.rb +1 -1
  108. data/lib/mongoid/criteria/queryable/optional.rb +11 -17
  109. data/lib/mongoid/criteria/queryable/options.rb +2 -2
  110. data/lib/mongoid/criteria/queryable/pipeline.rb +1 -1
  111. data/lib/mongoid/criteria/queryable/selectable.rb +47 -38
  112. data/lib/mongoid/criteria/queryable/selector.rb +92 -7
  113. data/lib/mongoid/criteria/queryable/smash.rb +40 -7
  114. data/lib/mongoid/criteria/queryable.rb +12 -7
  115. data/lib/mongoid/criteria/scopable.rb +2 -2
  116. data/lib/mongoid/criteria/translator.rb +45 -0
  117. data/lib/mongoid/criteria.rb +20 -40
  118. data/lib/mongoid/deprecable.rb +37 -0
  119. data/lib/mongoid/deprecation.rb +25 -0
  120. data/lib/mongoid/document.rb +127 -35
  121. data/lib/mongoid/equality.rb +8 -8
  122. data/lib/mongoid/errors/create_collection_failure.rb +33 -0
  123. data/lib/mongoid/errors/document_not_found.rb +10 -6
  124. data/lib/mongoid/errors/drop_collection_failure.rb +27 -0
  125. data/lib/mongoid/errors/immutable_attribute.rb +26 -0
  126. data/lib/mongoid/errors/invalid_async_query_executor.rb +25 -0
  127. data/lib/mongoid/errors/invalid_config_option.rb +1 -1
  128. data/lib/mongoid/errors/invalid_dependent_strategy.rb +1 -1
  129. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
  130. data/lib/mongoid/errors/invalid_field.rb +6 -2
  131. data/lib/mongoid/errors/invalid_field_type.rb +26 -0
  132. data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +22 -0
  133. data/lib/mongoid/errors/invalid_relation.rb +1 -1
  134. data/lib/mongoid/errors/invalid_relation_option.rb +1 -1
  135. data/lib/mongoid/errors/invalid_session_use.rb +1 -1
  136. data/lib/mongoid/errors/invalid_storage_options.rb +1 -1
  137. data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
  138. data/lib/mongoid/errors/mongoid_error.rb +3 -3
  139. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +1 -1
  140. data/lib/mongoid/errors/no_client_database.rb +1 -1
  141. data/lib/mongoid/errors/no_client_hosts.rb +1 -1
  142. data/lib/mongoid/errors/readonly_attribute.rb +1 -1
  143. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
  144. data/lib/mongoid/errors/unknown_attribute.rb +1 -1
  145. data/lib/mongoid/errors.rb +6 -3
  146. data/lib/mongoid/extensions/array.rb +9 -7
  147. data/lib/mongoid/extensions/big_decimal.rb +33 -10
  148. data/lib/mongoid/extensions/binary.rb +42 -0
  149. data/lib/mongoid/extensions/boolean.rb +8 -2
  150. data/lib/mongoid/extensions/date.rb +26 -20
  151. data/lib/mongoid/extensions/date_time.rb +1 -1
  152. data/lib/mongoid/extensions/false_class.rb +1 -1
  153. data/lib/mongoid/extensions/float.rb +7 -4
  154. data/lib/mongoid/extensions/hash.rb +37 -8
  155. data/lib/mongoid/extensions/integer.rb +7 -4
  156. data/lib/mongoid/extensions/module.rb +1 -1
  157. data/lib/mongoid/extensions/object.rb +10 -8
  158. data/lib/mongoid/extensions/range.rb +41 -10
  159. data/lib/mongoid/extensions/regexp.rb +11 -4
  160. data/lib/mongoid/extensions/set.rb +11 -4
  161. data/lib/mongoid/extensions/string.rb +11 -22
  162. data/lib/mongoid/extensions/symbol.rb +4 -15
  163. data/lib/mongoid/extensions/time.rb +29 -16
  164. data/lib/mongoid/extensions/time_with_zone.rb +1 -2
  165. data/lib/mongoid/extensions/true_class.rb +1 -1
  166. data/lib/mongoid/extensions.rb +1 -0
  167. data/lib/mongoid/factory.rb +55 -7
  168. data/lib/mongoid/fields/foreign_key.rb +11 -4
  169. data/lib/mongoid/fields/localized.rb +19 -4
  170. data/lib/mongoid/fields/standard.rb +17 -7
  171. data/lib/mongoid/fields/validators/macro.rb +3 -9
  172. data/lib/mongoid/fields.rb +129 -20
  173. data/lib/mongoid/findable.rb +54 -24
  174. data/lib/mongoid/indexable/specification.rb +2 -2
  175. data/lib/mongoid/indexable/validators/options.rb +6 -2
  176. data/lib/mongoid/interceptable.rb +188 -16
  177. data/lib/mongoid/matchable.rb +1 -1
  178. data/lib/mongoid/matcher/eq_impl.rb +1 -1
  179. data/lib/mongoid/matcher/type.rb +1 -1
  180. data/lib/mongoid/matcher.rb +33 -13
  181. data/lib/mongoid/persistable/creatable.rb +19 -9
  182. data/lib/mongoid/persistable/deletable.rb +2 -2
  183. data/lib/mongoid/persistable/destroyable.rb +1 -1
  184. data/lib/mongoid/persistable/savable.rb +14 -2
  185. data/lib/mongoid/persistable/unsettable.rb +2 -2
  186. data/lib/mongoid/persistable/updatable.rb +69 -12
  187. data/lib/mongoid/persistable/upsertable.rb +21 -2
  188. data/lib/mongoid/persistable.rb +6 -3
  189. data/lib/mongoid/persistence_context.rb +6 -4
  190. data/lib/mongoid/query_cache.rb +13 -261
  191. data/lib/mongoid/railties/controller_runtime.rb +1 -1
  192. data/lib/mongoid/railties/database.rake +7 -2
  193. data/lib/mongoid/reloadable.rb +10 -8
  194. data/lib/mongoid/scopable.rb +15 -13
  195. data/lib/mongoid/selectable.rb +1 -2
  196. data/lib/mongoid/serializable.rb +10 -6
  197. data/lib/mongoid/stateful.rb +57 -10
  198. data/lib/mongoid/tasks/database.rake +12 -0
  199. data/lib/mongoid/tasks/database.rb +20 -2
  200. data/lib/mongoid/threaded/lifecycle.rb +5 -5
  201. data/lib/mongoid/threaded.rb +42 -12
  202. data/lib/mongoid/timestamps/created.rb +1 -1
  203. data/lib/mongoid/timestamps/updated.rb +2 -2
  204. data/lib/mongoid/touchable.rb +2 -3
  205. data/lib/mongoid/traversable.rb +5 -4
  206. data/lib/mongoid/utils.rb +22 -0
  207. data/lib/mongoid/validatable/localizable.rb +1 -1
  208. data/lib/mongoid/validatable/macros.rb +5 -7
  209. data/lib/mongoid/validatable/presence.rb +2 -2
  210. data/lib/mongoid/validatable/uniqueness.rb +9 -8
  211. data/lib/mongoid/validatable.rb +9 -6
  212. data/lib/mongoid/version.rb +1 -1
  213. data/lib/mongoid/warnings.rb +19 -4
  214. data/lib/mongoid.rb +17 -3
  215. data/spec/config/mongoid.yml +16 -0
  216. data/spec/integration/app_spec.rb +10 -14
  217. data/spec/integration/associations/belongs_to_spec.rb +18 -0
  218. data/spec/integration/associations/embedded_spec.rb +15 -0
  219. data/spec/integration/associations/embeds_many_spec.rb +15 -2
  220. data/spec/integration/associations/embeds_one_spec.rb +18 -0
  221. data/spec/integration/associations/foreign_key_spec.rb +9 -0
  222. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
  223. data/spec/integration/associations/has_one_spec.rb +97 -1
  224. data/spec/integration/associations/scope_option_spec.rb +1 -1
  225. data/spec/integration/callbacks_models.rb +132 -1
  226. data/spec/integration/callbacks_spec.rb +381 -4
  227. data/spec/integration/criteria/range_spec.rb +95 -1
  228. data/spec/integration/discriminator_key_spec.rb +118 -80
  229. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  230. data/spec/integration/i18n_fallbacks_spec.rb +3 -32
  231. data/spec/integration/matcher_examples_spec.rb +20 -13
  232. data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
  233. data/spec/integration/matcher_operator_spec.rb +3 -5
  234. data/spec/integration/persistence/range_field_spec.rb +350 -0
  235. data/spec/mongoid/association/counter_cache_spec.rb +1 -1
  236. data/spec/mongoid/association/depending_spec.rb +9 -9
  237. data/spec/mongoid/association/eager_spec.rb +2 -1
  238. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
  239. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
  240. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +96 -9
  241. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
  242. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +255 -65
  243. data/spec/mongoid/association/embedded/embeds_many_models.rb +37 -0
  244. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +12 -0
  245. data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
  246. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
  247. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +15 -2
  248. data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
  249. data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
  250. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
  251. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
  252. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +15 -0
  253. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  254. data/spec/mongoid/association/referenced/belongs_to_spec.rb +4 -20
  255. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +186 -229
  256. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
  257. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
  258. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
  259. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +2 -56
  260. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +173 -177
  261. data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
  262. data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
  263. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
  264. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
  265. data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
  266. data/spec/mongoid/association/syncable_spec.rb +15 -1
  267. data/spec/mongoid/atomic/paths_spec.rb +0 -14
  268. data/spec/mongoid/attributes/nested_spec.rb +80 -11
  269. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  270. data/spec/mongoid/attributes/projector_spec.rb +1 -5
  271. data/spec/mongoid/attributes_spec.rb +510 -33
  272. data/spec/mongoid/changeable_spec.rb +429 -37
  273. data/spec/mongoid/clients/factory_spec.rb +23 -30
  274. data/spec/mongoid/clients/sessions_spec.rb +0 -38
  275. data/spec/mongoid/clients_spec.rb +149 -15
  276. data/spec/mongoid/collection_configurable_spec.rb +158 -0
  277. data/spec/mongoid/config/defaults_spec.rb +160 -0
  278. data/spec/mongoid/config_spec.rb +214 -31
  279. data/spec/mongoid/contextual/aggregable/memory_spec.rb +396 -158
  280. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  281. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  282. data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
  283. data/spec/mongoid/contextual/memory_spec.rb +850 -88
  284. data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +187 -0
  285. data/spec/mongoid/contextual/mongo_spec.rb +2309 -1127
  286. data/spec/mongoid/contextual/none_spec.rb +60 -21
  287. data/spec/mongoid/copyable_spec.rb +453 -11
  288. data/spec/mongoid/criteria/findable_spec.rb +86 -210
  289. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  290. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  291. data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
  292. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
  293. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
  294. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
  295. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
  296. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
  297. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
  298. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +4 -69
  299. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +0 -59
  300. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
  301. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
  302. data/spec/mongoid/criteria/queryable/optional_spec.rb +15 -484
  303. data/spec/mongoid/criteria/queryable/options_spec.rb +1 -1
  304. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +469 -0
  305. data/spec/mongoid/criteria/queryable/selectable_spec.rb +78 -86
  306. data/spec/mongoid/criteria/queryable/selector_spec.rb +15 -3
  307. data/spec/mongoid/criteria/translator_spec.rb +132 -0
  308. data/spec/mongoid/criteria_projection_spec.rb +1 -5
  309. data/spec/mongoid/criteria_spec.rb +469 -1205
  310. data/spec/mongoid/document_fields_spec.rb +173 -24
  311. data/spec/mongoid/document_spec.rb +32 -41
  312. data/spec/mongoid/errors/document_not_found_spec.rb +29 -2
  313. data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
  314. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  315. data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
  316. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  317. data/spec/mongoid/errors/readonly_document_spec.rb +2 -2
  318. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
  319. data/spec/mongoid/extensions/array_spec.rb +16 -2
  320. data/spec/mongoid/extensions/big_decimal_spec.rb +712 -212
  321. data/spec/mongoid/extensions/binary_spec.rb +44 -9
  322. data/spec/mongoid/extensions/boolean_spec.rb +68 -82
  323. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
  324. data/spec/mongoid/extensions/date_spec.rb +71 -1
  325. data/spec/mongoid/extensions/date_time_spec.rb +15 -9
  326. data/spec/mongoid/extensions/float_spec.rb +53 -74
  327. data/spec/mongoid/extensions/hash_spec.rb +33 -3
  328. data/spec/mongoid/extensions/integer_spec.rb +50 -64
  329. data/spec/mongoid/extensions/range_spec.rb +255 -54
  330. data/spec/mongoid/extensions/regexp_spec.rb +58 -33
  331. data/spec/mongoid/extensions/set_spec.rb +106 -0
  332. data/spec/mongoid/extensions/string_spec.rb +53 -25
  333. data/spec/mongoid/extensions/symbol_spec.rb +18 -25
  334. data/spec/mongoid/extensions/time_spec.rb +639 -106
  335. data/spec/mongoid/extensions/time_with_zone_spec.rb +24 -83
  336. data/spec/mongoid/factory_spec.rb +61 -1
  337. data/spec/mongoid/fields/localized_spec.rb +80 -37
  338. data/spec/mongoid/fields_spec.rb +500 -84
  339. data/spec/mongoid/findable_spec.rb +450 -58
  340. data/spec/mongoid/indexable/specification_spec.rb +2 -2
  341. data/spec/mongoid/indexable_spec.rb +55 -30
  342. data/spec/mongoid/interceptable_spec.rb +824 -22
  343. data/spec/mongoid/interceptable_spec_models.rb +235 -4
  344. data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
  345. data/spec/mongoid/mongoizable_spec.rb +285 -0
  346. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  347. data/spec/mongoid/persistable/deletable_spec.rb +28 -8
  348. data/spec/mongoid/persistable/destroyable_spec.rb +28 -8
  349. data/spec/mongoid/persistable/incrementable_spec.rb +37 -0
  350. data/spec/mongoid/persistable/logical_spec.rb +37 -0
  351. data/spec/mongoid/persistable/poppable_spec.rb +36 -0
  352. data/spec/mongoid/persistable/pullable_spec.rb +72 -0
  353. data/spec/mongoid/persistable/pushable_spec.rb +72 -0
  354. data/spec/mongoid/persistable/renamable_spec.rb +36 -0
  355. data/spec/mongoid/persistable/savable_spec.rb +96 -0
  356. data/spec/mongoid/persistable/settable_spec.rb +37 -0
  357. data/spec/mongoid/persistable/unsettable_spec.rb +36 -0
  358. data/spec/mongoid/persistable/updatable_spec.rb +20 -28
  359. data/spec/mongoid/persistable/upsertable_spec.rb +89 -1
  360. data/spec/mongoid/persistence_context_spec.rb +31 -57
  361. data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
  362. data/spec/mongoid/query_cache_spec.rb +56 -215
  363. data/spec/mongoid/reloadable_spec.rb +83 -6
  364. data/spec/mongoid/scopable_spec.rb +91 -1
  365. data/spec/mongoid/serializable_spec.rb +9 -30
  366. data/spec/mongoid/shardable_spec.rb +4 -4
  367. data/spec/mongoid/stateful_spec.rb +150 -8
  368. data/spec/mongoid/tasks/database_rake_spec.rb +74 -0
  369. data/spec/mongoid/tasks/database_spec.rb +127 -0
  370. data/spec/mongoid/timestamps_spec.rb +392 -4
  371. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  372. data/spec/mongoid/touchable_spec.rb +390 -2
  373. data/spec/mongoid/touchable_spec_models.rb +14 -8
  374. data/spec/mongoid/traversable_spec.rb +13 -35
  375. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  376. data/spec/mongoid/validatable/uniqueness_spec.rb +58 -31
  377. data/spec/mongoid/warnings_spec.rb +35 -0
  378. data/spec/mongoid_spec.rb +34 -16
  379. data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
  380. data/spec/rails/mongoid_spec.rb +4 -16
  381. data/spec/shared/lib/mrss/docker_runner.rb +8 -0
  382. data/spec/shared/lib/mrss/lite_constraints.rb +2 -2
  383. data/spec/shared/lib/mrss/server_version_registry.rb +16 -23
  384. data/spec/shared/lib/mrss/utils.rb +28 -6
  385. data/spec/shared/share/Dockerfile.erb +36 -40
  386. data/spec/shared/shlib/server.sh +28 -4
  387. data/spec/shared/shlib/set_env.sh +4 -4
  388. data/spec/spec_helper.rb +5 -0
  389. data/spec/support/constraints.rb +24 -0
  390. data/spec/support/immutable_ids.rb +118 -0
  391. data/spec/support/macros.rb +78 -0
  392. data/spec/support/models/artist.rb +0 -1
  393. data/spec/support/models/augmentation.rb +12 -0
  394. data/spec/support/models/band.rb +4 -0
  395. data/spec/support/models/book.rb +1 -0
  396. data/spec/support/models/building.rb +2 -0
  397. data/spec/support/models/catalog.rb +24 -0
  398. data/spec/support/models/circus.rb +3 -0
  399. data/spec/support/models/cover.rb +10 -0
  400. data/spec/support/models/fanatic.rb +8 -0
  401. data/spec/support/models/implant.rb +9 -0
  402. data/spec/support/models/label.rb +2 -0
  403. data/spec/support/models/passport.rb +9 -0
  404. data/spec/support/models/person.rb +2 -0
  405. data/spec/support/models/player.rb +2 -0
  406. data/spec/support/models/powerup.rb +12 -0
  407. data/spec/support/models/product.rb +1 -0
  408. data/spec/support/models/purse.rb +9 -0
  409. data/spec/support/models/registry.rb +1 -0
  410. data/spec/support/models/school.rb +14 -0
  411. data/spec/support/models/shield.rb +18 -0
  412. data/spec/support/models/student.rb +14 -0
  413. data/spec/support/models/weapon.rb +12 -0
  414. data.tar.gz.sig +0 -0
  415. metadata +100 -22
  416. metadata.gz.sig +0 -0
  417. data/lib/mongoid/errors/eager_load.rb +0 -23
  418. data/lib/mongoid/errors/invalid_value.rb +0 -17
  419. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -60
  420. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -60
  421. data/spec/mongoid/errors/eager_load_spec.rb +0 -31
@@ -44,7 +44,9 @@ module Mongoid
44
44
  #
45
45
  # @param [ Hash ] options The options to check.
46
46
  #
47
- # @return [ true, false ] If we are validating.
47
+ # @option options [ true | false ] :validate Whether or not to validate.
48
+ #
49
+ # @return [ true | false ] If we are validating.
48
50
  def performing_validations?(options = {})
49
51
  options[:validate].nil? ? true : options[:validate]
50
52
  end
@@ -83,7 +85,7 @@ module Mongoid
83
85
  #
84
86
  # @param [ Symbol ] context The optional validation context.
85
87
  #
86
- # @return [ true, false ] True if valid, false if not.
88
+ # @return [ true | false ] True if valid, false if not.
87
89
  def valid?(context = nil)
88
90
  super context ? context : (new_record? ? :create : :update)
89
91
  end
@@ -93,7 +95,7 @@ module Mongoid
93
95
  # @example Is the document validated?
94
96
  # document.validated?
95
97
  #
96
- # @return [ true, false ] Has the document already been validated?
98
+ # @return [ true | false ] Has the document already been validated?
97
99
  def validated?
98
100
  Threaded.validated?(self)
99
101
  end
@@ -103,7 +105,7 @@ module Mongoid
103
105
  # @example Are we validating with a query?
104
106
  # document.validating_with_query?
105
107
  #
106
- # @return [ true, false ] If we are validating with a query.
108
+ # @return [ true | false ] If we are validating with a query.
107
109
  def validating_with_query?
108
110
  self.class.validating_with_query?
109
111
  end
@@ -129,7 +131,8 @@ module Mongoid
129
131
  # @example Validate with a specific validator.
130
132
  # validates_with MyValidator, on: :create
131
133
  #
132
- # @param [ Class<Array>, Hash ] args The validator classes and options.
134
+ # @param [ ActiveModel::Validator..., Hash ] *args The validator classes
135
+ # and options hash.
133
136
  #
134
137
  # @note See ActiveModel::Validations::With for full options. This is
135
138
  # overridden to add autosave functionality when presence validation is
@@ -151,7 +154,7 @@ module Mongoid
151
154
  # @example Are we validating with a query?
152
155
  # Model.validating_with_query?
153
156
  #
154
- # @return [ true, false ] If we are validating with a query.
157
+ # @return [ true | false ] If we are validating with a query.
155
158
  def validating_with_query?
156
159
  Threaded.executing?("#{name}-validate-with-query")
157
160
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mongoid
4
- VERSION = "7.5.4"
4
+ VERSION = "8.1.3"
5
5
  end
@@ -21,9 +21,24 @@ module Mongoid
21
21
  end
22
22
  end
23
23
 
24
- warning :id_sort_deprecated, 'The :id_sort option has been deprecated. Use Mongo#take to get a document without a sort on _id.'
25
- warning :criteria_cache_deprecated, 'The criteria cache has been deprecated and will be removed in Mongoid 8. Please enable the Mongoid QueryCache to have caching functionality.'
26
- warning :map_field_deprecated, 'The field argument to the Mongo#map method has been deprecated, please pass in a block instead. Support will be dropped in Mongoid 8.'
24
+ warning :geo_haystack_deprecated, 'The geoHaystack type is deprecated.'
25
+ warning :as_json_compact_deprecated, '#as_json :compact option is deprecated. Please call #compact on the returned Hash object instead.'
26
+ warning :symbol_type_deprecated, 'The BSON Symbol type is deprecated by MongoDB. Please use String or StringifiedSymbol field types instead of the Symbol field type.'
27
+ warning :legacy_readonly, 'The readonly! method will only mark the document readonly when the legacy_readonly feature flag is switched off.'
28
+ warning :use_activesupport_time_zone_deprecated, 'Config option :use_activesupport_time_zone is deprecated and should be removed from your config. It will always be true beginning in Mongoid 9.0.'
29
+ warning :broken_aggregables_deprecated, 'Config option :broken_aggregables is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
30
+ warning :broken_alias_handling_deprecated, 'Config option :broken_alias_handling is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
31
+ warning :broken_and_deprecated, 'Config option :broken_and is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
32
+ warning :broken_scoping_deprecated, 'Config option :broken_scoping is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
33
+ warning :broken_updates_deprecated, 'Config option :broken_updates is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
34
+ warning :compare_time_by_ms_deprecated, 'Config option :compare_time_by_ms is deprecated. It will always be true beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
35
+ warning :legacy_attributes_deprecated, 'Config option :legacy_attributes is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
36
+ warning :legacy_pluck_distinct_deprecated, 'Config option :legacy_pluck_distinct is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
37
+ warning :legacy_triple_equals_deprecated, 'Config option :legacy_triple_equals is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
38
+ warning :object_id_as_json_oid_deprecated, 'Config option :object_id_as_json_oid is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
39
+ warning :overwrite_chained_operators_deprecated, 'Config option :overwrite_chained_operators is deprecated. It will always be false beginning in Mongoid 9.0. Please use load_defaults for Mongoid 8.0 or later, then remove it from your config.'
40
+ warning :mutable_ids, 'In Mongoid 9.0 the _id field will be immutable. In earlier versions of 8.x, mutating the _id field was supported inconsistently. Prepare your code for 9.0 by setting Mongoid::Config.immutable_ids to true.'
41
+ warning :mongoid_query_cache, 'In Mongoid 9.0, Mongoid::QueryCache will be removed. Please replace it with Mongo::QueryCache.'
42
+ warning :mongoid_query_cache_clear, 'In Mongoid 9.0, Mongoid::QueryCache#clear_cache should be replaced it with Mongo::QueryCache#clear.'
27
43
  end
28
44
  end
29
-
data/lib/mongoid.rb CHANGED
@@ -12,10 +12,13 @@ require "active_support/inflector"
12
12
  require "active_support/time_with_zone"
13
13
  require "active_model"
14
14
 
15
+ require 'concurrent-ruby'
16
+
15
17
  require "mongo"
16
- require 'mongo/active_support'
18
+ require "mongo/active_support"
17
19
 
18
20
  require "mongoid/version"
21
+ require "mongoid/deprecable"
19
22
  require "mongoid/config"
20
23
  require "mongoid/persistence_context"
21
24
  require "mongoid/loggable"
@@ -24,6 +27,7 @@ require "mongoid/document"
24
27
  require "mongoid/tasks/database"
25
28
  require "mongoid/query_cache"
26
29
  require "mongoid/warnings"
30
+ require "mongoid/utils"
27
31
 
28
32
  # If we are using Rails then we will include the Mongoid railtie. This has all
29
33
  # the nifty initializers that Mongoid needs.
@@ -57,9 +61,19 @@ module Mongoid
57
61
  # }
58
62
  # end
59
63
  #
64
+ # @example Using a block without an argument. Use `config` inside
65
+ # the block to perform variable assignment.
66
+ #
67
+ # Mongoid.configure do
68
+ # connect_to("mongoid_test")
69
+ #
70
+ # config.preload_models = true
71
+ #
60
72
  # @return [ Config ] The configuration object.
61
- def configure
62
- block_given? ? yield(Config) : Config
73
+ def configure(&block)
74
+ return Config unless block_given?
75
+
76
+ block.arity == 0 ? Config.instance_exec(&block) : yield(Config)
63
77
  end
64
78
 
65
79
  # Convenience method for getting the default client.
@@ -40,6 +40,22 @@ test:
40
40
  app_name: 'testing'
41
41
  background_indexing: false
42
42
  join_contexts: false
43
+ driver_options:
44
+ broken_view_options: false
45
+ # Don't set validate_update_replace here, as it is used to check if the
46
+ # default driver options are kept in Mongoid.
47
+ test_nil:
48
+ clients:
49
+ default:
50
+ database: mongoid_test
51
+ hosts:
52
+ <% SpecConfig.instance.addresses.each do |address| %>
53
+ - <%= address %>
54
+ <% end %>
55
+ driver_options:
56
+ broken_view_options:
57
+ validate_update_replace: false
58
+
43
59
  test_with_max_staleness:
44
60
  clients:
45
61
  default:
@@ -163,6 +163,14 @@ describe 'Mongoid application tests' do
163
163
  before do
164
164
  Dir.chdir(APP_PATH) do
165
165
  remove_bundler_req
166
+
167
+ if BSON::Environment.jruby?
168
+ # Remove existing Gemfile.lock - see
169
+ # https://github.com/rubygems/rubygems/issues/3231
170
+ require 'fileutils'
171
+ FileUtils.rm_f('Gemfile.lock')
172
+ end
173
+
166
174
  check_call(%w(bundle install), env: env)
167
175
  write_mongoid_yml
168
176
  end
@@ -287,18 +295,6 @@ describe 'Mongoid application tests' do
287
295
  f << lines.join
288
296
  end
289
297
  end
290
-
291
- if rails_version == '5.1'
292
- secrets = {
293
- 'development' => {
294
- 'secret_key_base' => 'abracadabra',
295
- 'my_secret_token' => 'very_secret',
296
- },
297
- }
298
- File.open('config/secrets.yml', 'w') do |f|
299
- f << YAML.dump(secrets)
300
- end
301
- end
302
298
  end
303
299
 
304
300
  def remove_bundler_req
@@ -330,7 +326,7 @@ describe 'Mongoid application tests' do
330
326
  end
331
327
 
332
328
  def wait_for_port(port, timeout, process)
333
- deadline = Time.now + timeout
329
+ deadline = Mongoid::Utils.monotonic_time + timeout
334
330
  loop do
335
331
  begin
336
332
  Socket.tcp('localhost', port, nil, nil, connect_timeout: 0.5) do |socket|
@@ -340,7 +336,7 @@ describe 'Mongoid application tests' do
340
336
  unless process.alive?
341
337
  raise "Process #{process} died while waiting for port #{port}"
342
338
  end
343
- if Time.now > deadline
339
+ if Mongoid::Utils.monotonic_time > deadline
344
340
  raise
345
341
  end
346
342
  end
@@ -12,4 +12,22 @@ describe 'belongs_to associations' do
12
12
  expect(child).to be_valid
13
13
  end
14
14
  end
15
+
16
+ context 'when an anonymous class defines a belongs_to association' do
17
+ let(:klass) do
18
+ Class.new do
19
+ include Mongoid::Document
20
+ belongs_to :movie
21
+ end
22
+ end
23
+
24
+ it 'loads the association correctly' do
25
+ expect { klass }.to_not raise_error
26
+ expect { klass.new.movie }.to_not raise_error
27
+ instance = klass.new
28
+ movie = Movie.new
29
+ instance.movie = movie
30
+ expect(instance.movie).to eq movie
31
+ end
32
+ end
15
33
  end
@@ -265,4 +265,19 @@ describe 'embedded associations' do
265
265
  end
266
266
  end
267
267
  end
268
+
269
+ context "when summing properties on an embedded child" do
270
+ let(:user) { EmmUser.new }
271
+ before do
272
+ user.orders.build(amount: 200)
273
+ expect(user.orders.sum(:amount)).to eq(200)
274
+
275
+ user.orders.delete_all
276
+ user.orders.build(amount: 500)
277
+ end
278
+
279
+ it "the cache is cleared after deletion" do
280
+ expect(user.orders.sum(:amount)).to eq(500)
281
+ end
282
+ end
268
283
  end
@@ -172,8 +172,6 @@ describe 'embeds_many associations' do
172
172
  # Mongoid uses the new value of `x` in the $pullAll query,
173
173
  # which doesn't match the document that is in the database,
174
174
  # resulting in the empty array assignment not taking effect.
175
- pending 'MONGOID-5037'
176
-
177
175
  canvas.shapes.first.x = 1
178
176
  canvas.shapes = []
179
177
  canvas.save!
@@ -203,4 +201,19 @@ describe 'embeds_many associations' do
203
201
  end
204
202
  end
205
203
  end
204
+
205
+ context 'when an anonymous class defines an embeds_many association' do
206
+ let(:klass) do
207
+ Class.new do
208
+ include Mongoid::Document
209
+ embeds_many :addresses
210
+ end
211
+ end
212
+
213
+ it 'loads the association correctly' do
214
+ expect { klass }.to_not raise_error
215
+ expect { klass.new.addresses }.to_not raise_error
216
+ expect(klass.new.addresses.build).to be_a Address
217
+ end
218
+ end
206
219
  end
@@ -20,4 +20,22 @@ describe 'embeds_one associations' do
20
20
  end
21
21
  end
22
22
  end
23
+
24
+ context 'when an anonymous class defines an embeds_one association' do
25
+ let(:klass) do
26
+ Class.new do
27
+ include Mongoid::Document
28
+ embeds_one :address
29
+ end
30
+ end
31
+
32
+ it 'loads the association correctly' do
33
+ expect { klass }.to_not raise_error
34
+ expect { klass.new.address }.to_not raise_error
35
+ instance = klass.new
36
+ address = Address.new
37
+ instance.address = address
38
+ expect(instance.address).to eq address
39
+ end
40
+ end
23
41
  end
@@ -27,6 +27,15 @@ describe 'Association foreign key configuration' do
27
27
  expect(email.company.id).to eq(company.id)
28
28
  end
29
29
 
30
+ it "has the correct criteria" do
31
+ company = ForeignKeySpec::Company.create!(c: "3")
32
+ email = ForeignKeySpec::Email.create!(company: company)
33
+
34
+ criteria = ForeignKeySpec::Email.where(company: company)
35
+
36
+ expect(criteria.selector).to eq({ "c_ref" => "3" })
37
+ end
38
+
30
39
  context 'with default scope' do
31
40
  context 'using default scope' do
32
41
  it 'looks up child' do
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'has_and_belongs_to_many associations' do
6
+
7
+ context 'when an anonymous class defines a has_and_belongs_to_many association' do
8
+ let(:klass) do
9
+ Class.new do
10
+ include Mongoid::Document
11
+ has_and_belongs_to_many :movies, inverse_of: nil
12
+ end
13
+ end
14
+
15
+ it 'loads the association correctly' do
16
+ expect { klass }.to_not raise_error
17
+ expect { klass.new.movies }.to_not raise_error
18
+ expect(klass.new.movies.build).to be_a Movie
19
+ end
20
+ end
21
+ end
@@ -94,7 +94,7 @@ describe 'has_one associations' do
94
94
  context 'using send' do
95
95
  it 'delegates to the field' do
96
96
  if reloaded
97
- pending 'MONGOID-4018'
97
+ pending 'MONGOID-5018'
98
98
  end
99
99
 
100
100
  parent.accreditation.send(:format).should == 'fmt'
@@ -173,4 +173,100 @@ describe 'has_one associations' do
173
173
  end
174
174
  end
175
175
  end
176
+
177
+ context "when assigning to a has_one" do
178
+ let(:post) { HomPost.create! }
179
+ let(:comment1) { HomComment.create!(content: "Comment 1") }
180
+
181
+ context "when assigning the same value" do
182
+ let(:comment2) { HomComment.create! }
183
+
184
+ it "persists it correctly" do
185
+ post.comment = comment1
186
+ post.reload
187
+ expect(post.comment).to eq(comment1)
188
+
189
+ post.comment = comment1
190
+ post.reload
191
+ expect(post.comment).to eq(comment1)
192
+ end
193
+ end
194
+
195
+ context "when assigning two values with the same _id" do
196
+ let(:comment2) { HomComment.new(id: comment1.id) }
197
+
198
+ it "raises a duplicate key error" do
199
+ post.comment = comment1
200
+ expect do
201
+ post.comment = comment2
202
+ end.to raise_error(Mongo::Error::OperationFailure, /duplicate key/)
203
+ end
204
+ end
205
+
206
+ context "when duping the object and changing attributes" do
207
+ let(:comment2) { comment1.dup }
208
+
209
+ before do
210
+ comment2.content = "Comment 2"
211
+
212
+ post.comment = comment1
213
+ post.reload
214
+ end
215
+
216
+ it "updates the attributes correctly" do
217
+ post.comment = comment2
218
+ post.reload
219
+
220
+ expect(post.comment).to eq(comment2)
221
+ expect(post.comment.content).to eq(comment2.content)
222
+ end
223
+ end
224
+
225
+ context "when explicitly setting the foreign key" do
226
+ let(:comment2) { HomComment.new(post_id: post.id, content: "2") }
227
+
228
+ it "persists the new comment" do
229
+ post.comment = comment1
230
+ post.reload
231
+
232
+ post.comment = comment2
233
+ post.reload
234
+
235
+ expect(post.comment).to eq(comment2)
236
+ expect(post.comment.content).to eq(comment2.content)
237
+ end
238
+ end
239
+
240
+ context "when reassigning the same value" do
241
+ let(:comment2) { HomComment.create!(content: "Comment 2") }
242
+
243
+ it "persists it correctly" do
244
+ post.comment = comment1
245
+ post.reload
246
+ expect(post.comment).to eq(comment1)
247
+
248
+ post.comment = comment2
249
+ post.reload
250
+ expect(post.comment).to eq(comment2)
251
+
252
+ post.comment = comment1
253
+ post.reload
254
+ expect(post.comment).to eq(nil)
255
+ end
256
+ end
257
+ end
258
+
259
+ context "when overwriting an association" do
260
+ let(:post1) { HomPost.create!(title: "post 1") }
261
+ let(:post2) { HomPost.create!(title: "post 2") }
262
+ let(:comment) { HomComment.create(post: post1) }
263
+
264
+ it "does not overwrite the original value" do
265
+ pending "MONGOID-3999"
266
+ p1 = comment.post
267
+ expect(p1.title).to eq("post 1")
268
+ comment.post = post2
269
+ expect(p1.title).to eq("post 1")
270
+ end
271
+ end
176
272
  end
@@ -49,7 +49,7 @@ describe 'association :scope option' do
49
49
  it 'initially associates the documents in-memory' do
50
50
  expect(trainer1.animal).to eq animal2
51
51
  expect(trainer2.animal).to eq animal3
52
- expect(animal1.trainer).to eq trainer1
52
+ expect(animal1.trainer).to be_nil
53
53
  expect(animal2.trainer).to eq trainer1
54
54
  expect(animal3.trainer).to eq trainer2
55
55
  end
@@ -1,12 +1,17 @@
1
1
  class Galaxy
2
2
  include Mongoid::Document
3
+ include Mongoid::Timestamps
3
4
 
4
5
  field :age, type: Integer
5
-
6
+ field :was_touched, type: Mongoid::Boolean, default: false
6
7
  before_validation :set_age
7
8
 
8
9
  embeds_many :stars
9
10
 
11
+ set_callback(:touch, :before) do |document|
12
+ self.was_touched = true
13
+ end
14
+
10
15
  private
11
16
 
12
17
  def set_age
@@ -16,15 +21,21 @@ end
16
21
 
17
22
  class Star
18
23
  include Mongoid::Document
24
+ include Mongoid::Timestamps
19
25
 
20
26
  embedded_in :galaxy
21
27
 
22
28
  field :age, type: Integer
29
+ field :was_touched_after_parent, type: Mongoid::Boolean, default: false
23
30
 
24
31
  before_validation :set_age
25
32
 
26
33
  embeds_many :planets
27
34
 
35
+ set_callback(:touch, :before) do |document|
36
+ self.was_touched_after_parent = true if galaxy.was_touched
37
+ end
38
+
28
39
  private
29
40
 
30
41
  def set_age
@@ -34,13 +45,19 @@ end
34
45
 
35
46
  class Planet
36
47
  include Mongoid::Document
48
+ include Mongoid::Timestamps
37
49
 
38
50
  embedded_in :star
39
51
 
40
52
  field :age, type: Integer
53
+ field :was_touched_after_parent, type: Mongoid::Boolean, default: false
41
54
 
42
55
  before_validation :set_age
43
56
 
57
+ set_callback(:touch, :before) do |document|
58
+ self.was_touched_after_parent = true if star.was_touched_after_parent
59
+ end
60
+
44
61
  private
45
62
 
46
63
  def set_age
@@ -59,3 +76,117 @@ class Emission
59
76
 
60
77
  attr_reader :previous
61
78
  end
79
+
80
+ class Country
81
+ include Mongoid::Document
82
+
83
+ field :age
84
+
85
+ before_validation :set_age
86
+
87
+ embeds_one :president
88
+
89
+ private
90
+
91
+ def set_age
92
+ self.age ||= 245
93
+ end
94
+ end
95
+
96
+ class President
97
+ include Mongoid::Document
98
+
99
+ embedded_in :country
100
+
101
+ field :age
102
+
103
+ field :name
104
+
105
+ before_validation :set_age
106
+
107
+ embeds_one :first_spouse
108
+
109
+ private
110
+
111
+ def set_age
112
+ self.age ||= 79
113
+ end
114
+ end
115
+
116
+ class FirstSpouse
117
+ include Mongoid::Document
118
+
119
+ embedded_in :president
120
+
121
+ field :name
122
+ field :age, type: Integer
123
+
124
+ before_validation :set_age
125
+
126
+ private
127
+
128
+ def set_age
129
+ self.age ||= 70
130
+ end
131
+ end
132
+
133
+ class Architect
134
+ include Mongoid::Document
135
+
136
+ has_and_belongs_to_many :buildings, after_add: :after_add_callback,
137
+ after_remove: :after_remove_callback, dependent: :nullify
138
+
139
+ field :after_add_num_buildings, type: Integer
140
+ field :after_remove_num_buildings, type: Integer
141
+
142
+ def after_add_callback(obj)
143
+ self.after_add_num_buildings = self.buildings.length
144
+ end
145
+
146
+ def after_remove_callback(obj)
147
+ self.after_remove_num_buildings = self.buildings.length
148
+ end
149
+ end
150
+
151
+ class Building
152
+ include Mongoid::Document
153
+
154
+ has_and_belongs_to_many :architects, dependent: :nullify
155
+ end
156
+
157
+ class Root
158
+ include Mongoid::Document
159
+ embeds_many :embedded_once, cascade_callbacks: true
160
+ after_save :trace
161
+
162
+ attr_accessor :logger
163
+
164
+ def trace
165
+ logger << :root
166
+ end
167
+ end
168
+
169
+ class EmbeddedOnce
170
+ include Mongoid::Document
171
+ embeds_many :embedded_twice, cascade_callbacks: true
172
+ embedded_in :root
173
+ after_save :trace
174
+
175
+ attr_accessor :logger
176
+
177
+ def trace
178
+ logger << :embedded_once
179
+ end
180
+ end
181
+
182
+ class EmbeddedTwice
183
+ include Mongoid::Document
184
+ embedded_in :embedded_once
185
+ after_save :trace
186
+
187
+ attr_accessor :logger
188
+
189
+ def trace
190
+ logger << :embedded_twice
191
+ end
192
+ end