mongoid 7.5.1 → 8.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (429) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +3 -3
  4. data/README.md +6 -6
  5. data/Rakefile +25 -0
  6. data/lib/config/locales/en.yml +92 -43
  7. data/lib/mongoid/association/accessors.rb +40 -11
  8. data/lib/mongoid/association/bindable.rb +50 -2
  9. data/lib/mongoid/association/builders.rb +5 -3
  10. data/lib/mongoid/association/constrainable.rb +0 -1
  11. data/lib/mongoid/association/eager_loadable.rb +29 -7
  12. data/lib/mongoid/association/embedded/batchable.rb +54 -14
  13. data/lib/mongoid/association/embedded/cyclic.rb +1 -1
  14. data/lib/mongoid/association/embedded/embedded_in/binding.rb +24 -2
  15. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +2 -2
  16. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +4 -3
  17. data/lib/mongoid/association/embedded/embedded_in.rb +3 -2
  18. data/lib/mongoid/association/embedded/embeds_many/binding.rb +1 -0
  19. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +4 -3
  20. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +85 -46
  21. data/lib/mongoid/association/embedded/embeds_many.rb +2 -2
  22. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +19 -5
  23. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +24 -5
  24. data/lib/mongoid/association/embedded/embeds_one.rb +3 -3
  25. data/lib/mongoid/association/macros.rb +8 -1
  26. data/lib/mongoid/association/many.rb +11 -7
  27. data/lib/mongoid/association/nested/many.rb +5 -4
  28. data/lib/mongoid/association/nested/nested_buildable.rb +4 -4
  29. data/lib/mongoid/association/nested/one.rb +45 -7
  30. data/lib/mongoid/association/one.rb +2 -2
  31. data/lib/mongoid/association/options.rb +9 -9
  32. data/lib/mongoid/association/proxy.rb +15 -4
  33. data/lib/mongoid/association/referenced/auto_save.rb +4 -3
  34. data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
  35. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
  36. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +5 -6
  37. data/lib/mongoid/association/referenced/belongs_to.rb +2 -2
  38. data/lib/mongoid/association/referenced/counter_cache.rb +10 -10
  39. data/lib/mongoid/association/referenced/eager.rb +2 -2
  40. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +70 -13
  41. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +6 -3
  42. data/lib/mongoid/association/referenced/has_many/enumerable.rb +22 -30
  43. data/lib/mongoid/association/referenced/has_many/proxy.rb +40 -21
  44. data/lib/mongoid/association/referenced/has_many.rb +3 -3
  45. data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -1
  46. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +5 -5
  47. data/lib/mongoid/association/referenced/has_one/proxy.rb +9 -12
  48. data/lib/mongoid/association/referenced/has_one.rb +3 -3
  49. data/lib/mongoid/association/referenced/syncable.rb +4 -4
  50. data/lib/mongoid/association/reflections.rb +4 -4
  51. data/lib/mongoid/association/relatable.rb +44 -10
  52. data/lib/mongoid/association.rb +5 -5
  53. data/lib/mongoid/atomic/modifiers.rb +2 -2
  54. data/lib/mongoid/atomic/paths/embedded/many.rb +19 -0
  55. data/lib/mongoid/atomic.rb +7 -0
  56. data/lib/mongoid/attributes/dynamic.rb +4 -4
  57. data/lib/mongoid/attributes/nested.rb +6 -6
  58. data/lib/mongoid/attributes/processing.rb +37 -6
  59. data/lib/mongoid/attributes/projector.rb +2 -2
  60. data/lib/mongoid/attributes/readonly.rb +3 -3
  61. data/lib/mongoid/attributes.rb +51 -42
  62. data/lib/mongoid/cacheable.rb +2 -2
  63. data/lib/mongoid/changeable.rb +147 -14
  64. data/lib/mongoid/clients/options.rb +5 -1
  65. data/lib/mongoid/clients/sessions.rb +2 -14
  66. data/lib/mongoid/clients/storage_options.rb +2 -5
  67. data/lib/mongoid/clients/validators/storage.rb +3 -15
  68. data/lib/mongoid/collection_configurable.rb +58 -0
  69. data/lib/mongoid/composable.rb +2 -0
  70. data/lib/mongoid/config/defaults.rb +60 -0
  71. data/lib/mongoid/config/options.rb +3 -0
  72. data/lib/mongoid/config/validators/async_query_executor.rb +24 -0
  73. data/lib/mongoid/config/validators/client.rb +6 -6
  74. data/lib/mongoid/config/validators.rb +1 -0
  75. data/lib/mongoid/config.rb +158 -17
  76. data/lib/mongoid/contextual/aggregable/memory.rb +24 -16
  77. data/lib/mongoid/contextual/aggregable/mongo.rb +5 -5
  78. data/lib/mongoid/contextual/aggregable/none.rb +1 -1
  79. data/lib/mongoid/contextual/atomic.rb +1 -1
  80. data/lib/mongoid/contextual/geo_near.rb +7 -7
  81. data/lib/mongoid/contextual/map_reduce.rb +2 -2
  82. data/lib/mongoid/contextual/memory.rb +285 -58
  83. data/lib/mongoid/contextual/mongo/documents_loader.rb +177 -0
  84. data/lib/mongoid/contextual/mongo.rb +544 -333
  85. data/lib/mongoid/contextual/none.rb +193 -20
  86. data/lib/mongoid/contextual/queryable.rb +1 -1
  87. data/lib/mongoid/contextual.rb +14 -2
  88. data/lib/mongoid/copyable.rb +32 -8
  89. data/lib/mongoid/criteria/findable.rb +8 -5
  90. data/lib/mongoid/criteria/includable.rb +27 -22
  91. data/lib/mongoid/criteria/marshalable.rb +10 -2
  92. data/lib/mongoid/criteria/permission.rb +1 -1
  93. data/lib/mongoid/criteria/queryable/aggregable.rb +2 -2
  94. data/lib/mongoid/criteria/queryable/extensions/array.rb +3 -16
  95. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -4
  96. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +2 -2
  97. data/lib/mongoid/criteria/queryable/extensions/date.rb +6 -1
  98. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +6 -1
  99. data/lib/mongoid/criteria/queryable/extensions/hash.rb +1 -17
  100. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -9
  101. data/lib/mongoid/criteria/queryable/extensions/object.rb +2 -1
  102. data/lib/mongoid/criteria/queryable/extensions/range.rb +13 -5
  103. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
  104. data/lib/mongoid/criteria/queryable/extensions/set.rb +1 -1
  105. data/lib/mongoid/criteria/queryable/extensions/string.rb +4 -14
  106. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +4 -12
  107. data/lib/mongoid/criteria/queryable/extensions/time.rb +6 -1
  108. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +6 -1
  109. data/lib/mongoid/criteria/queryable/key.rb +4 -4
  110. data/lib/mongoid/criteria/queryable/mergeable.rb +1 -1
  111. data/lib/mongoid/criteria/queryable/optional.rb +11 -17
  112. data/lib/mongoid/criteria/queryable/options.rb +2 -2
  113. data/lib/mongoid/criteria/queryable/pipeline.rb +1 -1
  114. data/lib/mongoid/criteria/queryable/selectable.rb +47 -38
  115. data/lib/mongoid/criteria/queryable/selector.rb +93 -8
  116. data/lib/mongoid/criteria/queryable/smash.rb +40 -7
  117. data/lib/mongoid/criteria/queryable/storable.rb +1 -1
  118. data/lib/mongoid/criteria/queryable.rb +12 -7
  119. data/lib/mongoid/criteria/scopable.rb +2 -2
  120. data/lib/mongoid/criteria/translator.rb +45 -0
  121. data/lib/mongoid/criteria.rb +20 -40
  122. data/lib/mongoid/deprecable.rb +37 -0
  123. data/lib/mongoid/deprecation.rb +25 -0
  124. data/lib/mongoid/document.rb +135 -36
  125. data/lib/mongoid/equality.rb +8 -8
  126. data/lib/mongoid/errors/create_collection_failure.rb +33 -0
  127. data/lib/mongoid/errors/document_not_found.rb +10 -6
  128. data/lib/mongoid/errors/drop_collection_failure.rb +27 -0
  129. data/lib/mongoid/errors/immutable_attribute.rb +26 -0
  130. data/lib/mongoid/errors/invalid_async_query_executor.rb +25 -0
  131. data/lib/mongoid/errors/invalid_config_option.rb +1 -1
  132. data/lib/mongoid/errors/invalid_dependent_strategy.rb +1 -1
  133. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
  134. data/lib/mongoid/errors/invalid_field.rb +6 -2
  135. data/lib/mongoid/errors/invalid_field_type.rb +26 -0
  136. data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +22 -0
  137. data/lib/mongoid/errors/invalid_relation.rb +1 -1
  138. data/lib/mongoid/errors/invalid_relation_option.rb +1 -1
  139. data/lib/mongoid/errors/invalid_session_use.rb +1 -1
  140. data/lib/mongoid/errors/invalid_storage_options.rb +1 -1
  141. data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
  142. data/lib/mongoid/errors/mongoid_error.rb +3 -3
  143. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +1 -1
  144. data/lib/mongoid/errors/no_client_database.rb +1 -1
  145. data/lib/mongoid/errors/no_client_hosts.rb +1 -1
  146. data/lib/mongoid/errors/readonly_attribute.rb +1 -1
  147. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
  148. data/lib/mongoid/errors/unknown_attribute.rb +1 -1
  149. data/lib/mongoid/errors.rb +6 -3
  150. data/lib/mongoid/extensions/array.rb +9 -7
  151. data/lib/mongoid/extensions/big_decimal.rb +33 -10
  152. data/lib/mongoid/extensions/binary.rb +42 -0
  153. data/lib/mongoid/extensions/boolean.rb +8 -2
  154. data/lib/mongoid/extensions/date.rb +26 -20
  155. data/lib/mongoid/extensions/date_time.rb +1 -1
  156. data/lib/mongoid/extensions/false_class.rb +1 -1
  157. data/lib/mongoid/extensions/float.rb +7 -4
  158. data/lib/mongoid/extensions/hash.rb +37 -8
  159. data/lib/mongoid/extensions/integer.rb +7 -4
  160. data/lib/mongoid/extensions/module.rb +1 -1
  161. data/lib/mongoid/extensions/object.rb +10 -8
  162. data/lib/mongoid/extensions/range.rb +41 -10
  163. data/lib/mongoid/extensions/regexp.rb +11 -4
  164. data/lib/mongoid/extensions/set.rb +11 -4
  165. data/lib/mongoid/extensions/string.rb +11 -22
  166. data/lib/mongoid/extensions/symbol.rb +4 -15
  167. data/lib/mongoid/extensions/time.rb +29 -16
  168. data/lib/mongoid/extensions/time_with_zone.rb +1 -2
  169. data/lib/mongoid/extensions/true_class.rb +1 -1
  170. data/lib/mongoid/extensions.rb +1 -0
  171. data/lib/mongoid/factory.rb +55 -7
  172. data/lib/mongoid/fields/foreign_key.rb +11 -4
  173. data/lib/mongoid/fields/localized.rb +19 -4
  174. data/lib/mongoid/fields/standard.rb +17 -7
  175. data/lib/mongoid/fields/validators/macro.rb +3 -9
  176. data/lib/mongoid/fields.rb +129 -20
  177. data/lib/mongoid/findable.rb +54 -24
  178. data/lib/mongoid/indexable/specification.rb +2 -2
  179. data/lib/mongoid/indexable/validators/options.rb +6 -2
  180. data/lib/mongoid/interceptable.rb +186 -16
  181. data/lib/mongoid/matchable.rb +1 -1
  182. data/lib/mongoid/matcher/eq_impl.rb +1 -1
  183. data/lib/mongoid/matcher/type.rb +1 -1
  184. data/lib/mongoid/matcher.rb +33 -13
  185. data/lib/mongoid/persistable/creatable.rb +19 -9
  186. data/lib/mongoid/persistable/deletable.rb +2 -2
  187. data/lib/mongoid/persistable/destroyable.rb +1 -1
  188. data/lib/mongoid/persistable/savable.rb +14 -2
  189. data/lib/mongoid/persistable/unsettable.rb +2 -2
  190. data/lib/mongoid/persistable/updatable.rb +69 -12
  191. data/lib/mongoid/persistable/upsertable.rb +21 -2
  192. data/lib/mongoid/persistable.rb +6 -3
  193. data/lib/mongoid/persistence_context.rb +63 -10
  194. data/lib/mongoid/query_cache.rb +13 -261
  195. data/lib/mongoid/railties/controller_runtime.rb +1 -1
  196. data/lib/mongoid/railties/database.rake +7 -2
  197. data/lib/mongoid/reloadable.rb +10 -8
  198. data/lib/mongoid/scopable.rb +15 -13
  199. data/lib/mongoid/selectable.rb +1 -2
  200. data/lib/mongoid/serializable.rb +10 -6
  201. data/lib/mongoid/shardable.rb +35 -11
  202. data/lib/mongoid/stateful.rb +57 -10
  203. data/lib/mongoid/tasks/database.rake +12 -0
  204. data/lib/mongoid/tasks/database.rb +20 -2
  205. data/lib/mongoid/threaded/lifecycle.rb +5 -5
  206. data/lib/mongoid/threaded.rb +42 -12
  207. data/lib/mongoid/timestamps/created.rb +1 -1
  208. data/lib/mongoid/timestamps/updated.rb +2 -2
  209. data/lib/mongoid/touchable.rb +2 -3
  210. data/lib/mongoid/traversable.rb +5 -4
  211. data/lib/mongoid/utils.rb +22 -0
  212. data/lib/mongoid/validatable/localizable.rb +1 -1
  213. data/lib/mongoid/validatable/macros.rb +5 -7
  214. data/lib/mongoid/validatable/presence.rb +2 -2
  215. data/lib/mongoid/validatable/uniqueness.rb +9 -8
  216. data/lib/mongoid/validatable.rb +9 -6
  217. data/lib/mongoid/version.rb +1 -1
  218. data/lib/mongoid/warnings.rb +19 -4
  219. data/lib/mongoid.rb +17 -3
  220. data/spec/config/mongoid.yml +16 -0
  221. data/spec/integration/app_spec.rb +10 -14
  222. data/spec/integration/associations/belongs_to_spec.rb +18 -0
  223. data/spec/integration/associations/embedded_spec.rb +15 -0
  224. data/spec/integration/associations/embeds_many_spec.rb +15 -2
  225. data/spec/integration/associations/embeds_one_spec.rb +18 -0
  226. data/spec/integration/associations/foreign_key_spec.rb +9 -0
  227. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
  228. data/spec/integration/associations/has_one_spec.rb +97 -1
  229. data/spec/integration/associations/scope_option_spec.rb +1 -1
  230. data/spec/integration/callbacks_models.rb +132 -1
  231. data/spec/integration/callbacks_spec.rb +381 -4
  232. data/spec/integration/criteria/range_spec.rb +95 -1
  233. data/spec/integration/discriminator_key_spec.rb +118 -80
  234. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  235. data/spec/integration/i18n_fallbacks_spec.rb +3 -32
  236. data/spec/integration/matcher_examples_spec.rb +20 -13
  237. data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
  238. data/spec/integration/matcher_operator_spec.rb +3 -5
  239. data/spec/integration/persistence/range_field_spec.rb +350 -0
  240. data/spec/mongoid/association/counter_cache_spec.rb +1 -1
  241. data/spec/mongoid/association/depending_spec.rb +9 -9
  242. data/spec/mongoid/association/eager_spec.rb +2 -1
  243. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
  244. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
  245. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +96 -9
  246. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
  247. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +311 -65
  248. data/spec/mongoid/association/embedded/embeds_many_models.rb +158 -0
  249. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +12 -0
  250. data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
  251. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
  252. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +15 -2
  253. data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
  254. data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
  255. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
  256. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
  257. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +15 -0
  258. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  259. data/spec/mongoid/association/referenced/belongs_to_spec.rb +4 -20
  260. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +215 -228
  261. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
  262. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
  263. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
  264. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +2 -56
  265. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +235 -177
  266. data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
  267. data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
  268. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
  269. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
  270. data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
  271. data/spec/mongoid/association/syncable_spec.rb +15 -1
  272. data/spec/mongoid/atomic/paths_spec.rb +0 -14
  273. data/spec/mongoid/attributes/nested_spec.rb +80 -11
  274. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  275. data/spec/mongoid/attributes/projector_spec.rb +1 -5
  276. data/spec/mongoid/attributes_spec.rb +554 -33
  277. data/spec/mongoid/cacheable_spec.rb +3 -3
  278. data/spec/mongoid/changeable_spec.rb +429 -37
  279. data/spec/mongoid/clients/factory_spec.rb +23 -30
  280. data/spec/mongoid/clients/sessions_spec.rb +0 -38
  281. data/spec/mongoid/clients_spec.rb +179 -15
  282. data/spec/mongoid/collection_configurable_spec.rb +158 -0
  283. data/spec/mongoid/config/defaults_spec.rb +160 -0
  284. data/spec/mongoid/config_spec.rb +220 -30
  285. data/spec/mongoid/contextual/aggregable/memory_spec.rb +396 -158
  286. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  287. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  288. data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
  289. data/spec/mongoid/contextual/memory_spec.rb +850 -88
  290. data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +187 -0
  291. data/spec/mongoid/contextual/mongo_spec.rb +2307 -1105
  292. data/spec/mongoid/contextual/none_spec.rb +60 -21
  293. data/spec/mongoid/copyable_spec.rb +453 -11
  294. data/spec/mongoid/criteria/findable_spec.rb +86 -210
  295. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  296. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  297. data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
  298. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
  299. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
  300. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
  301. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
  302. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
  303. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
  304. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +4 -69
  305. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +0 -59
  306. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
  307. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
  308. data/spec/mongoid/criteria/queryable/optional_spec.rb +15 -484
  309. data/spec/mongoid/criteria/queryable/options_spec.rb +1 -1
  310. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +469 -0
  311. data/spec/mongoid/criteria/queryable/selectable_spec.rb +78 -86
  312. data/spec/mongoid/criteria/queryable/selector_spec.rb +90 -5
  313. data/spec/mongoid/criteria/queryable/storable_spec.rb +72 -0
  314. data/spec/mongoid/criteria/translator_spec.rb +132 -0
  315. data/spec/mongoid/criteria_projection_spec.rb +1 -5
  316. data/spec/mongoid/criteria_spec.rb +469 -1205
  317. data/spec/mongoid/document_fields_spec.rb +173 -24
  318. data/spec/mongoid/document_spec.rb +32 -41
  319. data/spec/mongoid/errors/document_not_found_spec.rb +29 -2
  320. data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
  321. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  322. data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
  323. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  324. data/spec/mongoid/errors/readonly_document_spec.rb +2 -2
  325. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
  326. data/spec/mongoid/extensions/array_spec.rb +16 -2
  327. data/spec/mongoid/extensions/big_decimal_spec.rb +712 -212
  328. data/spec/mongoid/extensions/binary_spec.rb +44 -9
  329. data/spec/mongoid/extensions/boolean_spec.rb +68 -82
  330. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
  331. data/spec/mongoid/extensions/date_spec.rb +71 -1
  332. data/spec/mongoid/extensions/date_time_spec.rb +15 -9
  333. data/spec/mongoid/extensions/float_spec.rb +53 -74
  334. data/spec/mongoid/extensions/hash_spec.rb +33 -3
  335. data/spec/mongoid/extensions/integer_spec.rb +50 -64
  336. data/spec/mongoid/extensions/range_spec.rb +255 -54
  337. data/spec/mongoid/extensions/regexp_spec.rb +58 -33
  338. data/spec/mongoid/extensions/set_spec.rb +106 -0
  339. data/spec/mongoid/extensions/string_spec.rb +53 -25
  340. data/spec/mongoid/extensions/symbol_spec.rb +18 -25
  341. data/spec/mongoid/extensions/time_spec.rb +639 -106
  342. data/spec/mongoid/extensions/time_with_zone_spec.rb +24 -83
  343. data/spec/mongoid/factory_spec.rb +61 -1
  344. data/spec/mongoid/fields/localized_spec.rb +80 -37
  345. data/spec/mongoid/fields_spec.rb +500 -84
  346. data/spec/mongoid/findable_spec.rb +450 -58
  347. data/spec/mongoid/indexable/specification_spec.rb +2 -2
  348. data/spec/mongoid/indexable_spec.rb +55 -30
  349. data/spec/mongoid/interceptable_spec.rb +824 -22
  350. data/spec/mongoid/interceptable_spec_models.rb +235 -4
  351. data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
  352. data/spec/mongoid/mongoizable_spec.rb +285 -0
  353. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  354. data/spec/mongoid/persistable/deletable_spec.rb +28 -8
  355. data/spec/mongoid/persistable/destroyable_spec.rb +28 -8
  356. data/spec/mongoid/persistable/incrementable_spec.rb +37 -0
  357. data/spec/mongoid/persistable/logical_spec.rb +37 -0
  358. data/spec/mongoid/persistable/poppable_spec.rb +36 -0
  359. data/spec/mongoid/persistable/pullable_spec.rb +72 -0
  360. data/spec/mongoid/persistable/pushable_spec.rb +72 -0
  361. data/spec/mongoid/persistable/renamable_spec.rb +36 -0
  362. data/spec/mongoid/persistable/savable_spec.rb +96 -0
  363. data/spec/mongoid/persistable/settable_spec.rb +37 -0
  364. data/spec/mongoid/persistable/unsettable_spec.rb +36 -0
  365. data/spec/mongoid/persistable/updatable_spec.rb +20 -28
  366. data/spec/mongoid/persistable/upsertable_spec.rb +89 -1
  367. data/spec/mongoid/persistence_context_spec.rb +57 -58
  368. data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
  369. data/spec/mongoid/query_cache_spec.rb +56 -215
  370. data/spec/mongoid/reloadable_spec.rb +83 -6
  371. data/spec/mongoid/scopable_spec.rb +91 -1
  372. data/spec/mongoid/serializable_spec.rb +9 -30
  373. data/spec/mongoid/shardable_models.rb +14 -0
  374. data/spec/mongoid/shardable_spec.rb +157 -51
  375. data/spec/mongoid/stateful_spec.rb +150 -8
  376. data/spec/mongoid/tasks/database_rake_spec.rb +74 -0
  377. data/spec/mongoid/tasks/database_spec.rb +127 -0
  378. data/spec/mongoid/timestamps_spec.rb +392 -4
  379. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  380. data/spec/mongoid/touchable_spec.rb +390 -2
  381. data/spec/mongoid/touchable_spec_models.rb +14 -8
  382. data/spec/mongoid/traversable_spec.rb +13 -35
  383. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  384. data/spec/mongoid/validatable/uniqueness_spec.rb +58 -31
  385. data/spec/mongoid/warnings_spec.rb +35 -0
  386. data/spec/mongoid_spec.rb +34 -10
  387. data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
  388. data/spec/rails/mongoid_spec.rb +4 -16
  389. data/spec/shared/lib/mrss/docker_runner.rb +8 -0
  390. data/spec/shared/lib/mrss/lite_constraints.rb +10 -2
  391. data/spec/shared/lib/mrss/server_version_registry.rb +16 -23
  392. data/spec/shared/lib/mrss/utils.rb +28 -6
  393. data/spec/shared/share/Dockerfile.erb +36 -40
  394. data/spec/shared/shlib/server.sh +32 -8
  395. data/spec/shared/shlib/set_env.sh +4 -4
  396. data/spec/spec_helper.rb +5 -0
  397. data/spec/support/constraints.rb +24 -0
  398. data/spec/support/immutable_ids.rb +118 -0
  399. data/spec/support/macros.rb +78 -0
  400. data/spec/support/models/artist.rb +0 -1
  401. data/spec/support/models/augmentation.rb +12 -0
  402. data/spec/support/models/band.rb +4 -0
  403. data/spec/support/models/book.rb +1 -0
  404. data/spec/support/models/building.rb +2 -0
  405. data/spec/support/models/catalog.rb +24 -0
  406. data/spec/support/models/circus.rb +3 -0
  407. data/spec/support/models/cover.rb +10 -0
  408. data/spec/support/models/fanatic.rb +8 -0
  409. data/spec/support/models/implant.rb +9 -0
  410. data/spec/support/models/label.rb +2 -0
  411. data/spec/support/models/passport.rb +9 -0
  412. data/spec/support/models/person.rb +2 -0
  413. data/spec/support/models/player.rb +2 -0
  414. data/spec/support/models/powerup.rb +12 -0
  415. data/spec/support/models/product.rb +1 -0
  416. data/spec/support/models/purse.rb +9 -0
  417. data/spec/support/models/registry.rb +1 -0
  418. data/spec/support/models/school.rb +14 -0
  419. data/spec/support/models/shield.rb +18 -0
  420. data/spec/support/models/student.rb +14 -0
  421. data/spec/support/models/weapon.rb +12 -0
  422. data.tar.gz.sig +0 -0
  423. metadata +722 -640
  424. metadata.gz.sig +0 -0
  425. data/lib/mongoid/errors/eager_load.rb +0 -23
  426. data/lib/mongoid/errors/invalid_value.rb +0 -17
  427. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -60
  428. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -60
  429. data/spec/mongoid/errors/eager_load_spec.rb +0 -31
@@ -580,10 +580,24 @@ describe Mongoid::Interceptable do
580
580
  end
581
581
 
582
582
  context "when saving the root" do
583
+ context 'with prevent_multiple_calls_of_embedded_callbacks enabled' do
584
+ config_override :prevent_multiple_calls_of_embedded_callbacks, true
585
+ config_override :around_callbacks_for_embeds, true
583
586
 
584
- it "only executes the callbacks once for each embed" do
585
- expect(note).to receive(:update_saved).twice
586
- band.save!
587
+ it "executes the callbacks only once for each document" do
588
+ expect(note).to receive(:update_saved).once
589
+ band.save!
590
+ end
591
+ end
592
+
593
+ context 'with prevent_multiple_calls_of_embedded_callbacks disabled' do
594
+ config_override :prevent_multiple_calls_of_embedded_callbacks, false
595
+ config_override :around_callbacks_for_embeds, true
596
+
597
+ it "executes the callbacks once for each ember" do
598
+ expect(note).to receive(:update_saved).twice
599
+ band.save!
600
+ end
587
601
  end
588
602
  end
589
603
  end
@@ -1746,8 +1760,12 @@ describe Mongoid::Interceptable do
1746
1760
  [InterceptableSpec::CbChild, :after_validation],
1747
1761
  [InterceptableSpec::CbParent, :after_validation],
1748
1762
  [InterceptableSpec::CbParent, :before_save],
1763
+ [InterceptableSpec::CbParent, :around_save_open],
1749
1764
  [InterceptableSpec::CbParent, :before_create],
1765
+ [InterceptableSpec::CbParent, :around_create_open],
1766
+ [InterceptableSpec::CbParent, :around_create_close],
1750
1767
  [InterceptableSpec::CbParent, :after_create],
1768
+ [InterceptableSpec::CbParent, :around_save_close],
1751
1769
  [InterceptableSpec::CbParent, :after_save],
1752
1770
  ]
1753
1771
  end
@@ -1767,28 +1785,812 @@ describe Mongoid::Interceptable do
1767
1785
  end
1768
1786
  end
1769
1787
 
1770
- let(:expected) do
1771
- [
1772
- [InterceptableSpec::CbParent, :before_validation],
1773
- [InterceptableSpec::CbCascadedChild, :before_validation],
1774
- [InterceptableSpec::CbCascadedChild, :after_validation],
1775
- [InterceptableSpec::CbParent, :after_validation],
1776
- [InterceptableSpec::CbParent, :before_save],
1777
- [InterceptableSpec::CbCascadedChild, :before_save],
1778
- [InterceptableSpec::CbParent, :before_create],
1779
- [InterceptableSpec::CbCascadedChild, :before_create],
1780
- [InterceptableSpec::CbParent, :after_create],
1781
- [InterceptableSpec::CbCascadedChild, :after_create],
1782
- [InterceptableSpec::CbParent, :after_save],
1783
- [InterceptableSpec::CbCascadedChild, :after_save],
1784
- ]
1788
+ context 'with around callbacks' do
1789
+ config_override :around_callbacks_for_embeds, true
1790
+
1791
+ let(:expected) do
1792
+ [
1793
+ [InterceptableSpec::CbCascadedChild, :before_validation],
1794
+ [InterceptableSpec::CbCascadedChild, :after_validation],
1795
+ [InterceptableSpec::CbParent, :before_validation],
1796
+ [InterceptableSpec::CbCascadedChild, :before_validation],
1797
+ [InterceptableSpec::CbCascadedChild, :after_validation],
1798
+
1799
+ [InterceptableSpec::CbParent, :after_validation],
1800
+ [InterceptableSpec::CbParent, :before_save],
1801
+ [InterceptableSpec::CbParent, :around_save_open],
1802
+ [InterceptableSpec::CbParent, :before_create],
1803
+ [InterceptableSpec::CbParent, :around_create_open],
1804
+
1805
+ [InterceptableSpec::CbCascadedChild, :before_save],
1806
+ [InterceptableSpec::CbCascadedChild, :around_save_open],
1807
+ [InterceptableSpec::CbCascadedChild, :before_create],
1808
+ [InterceptableSpec::CbCascadedChild, :around_create_open],
1809
+
1810
+ [InterceptableSpec::CbCascadedChild, :around_create_close],
1811
+ [InterceptableSpec::CbCascadedChild, :after_create],
1812
+ [InterceptableSpec::CbCascadedChild, :around_save_close],
1813
+ [InterceptableSpec::CbCascadedChild, :after_save],
1814
+
1815
+ [InterceptableSpec::CbParent, :around_create_close],
1816
+ [InterceptableSpec::CbParent, :after_create],
1817
+ [InterceptableSpec::CbParent, :around_save_close],
1818
+ [InterceptableSpec::CbParent, :after_save]
1819
+ ]
1820
+ end
1821
+
1822
+ it 'calls callbacks in the right order' do
1823
+ parent.save!
1824
+ expect(registry.calls).to eq expected
1825
+ end
1785
1826
  end
1786
1827
 
1787
- it 'calls callbacks in the right order' do
1788
- pending 'MONGOID-3795'
1828
+ context 'without around callbacks' do
1829
+ config_override :around_callbacks_for_embeds, false
1789
1830
 
1790
- parent.save!
1791
- expect(registry.calls).to eq expected
1831
+ let(:expected) do
1832
+ [
1833
+ [InterceptableSpec::CbCascadedChild, :before_validation],
1834
+ [InterceptableSpec::CbCascadedChild, :after_validation],
1835
+ [InterceptableSpec::CbParent, :before_validation],
1836
+ [InterceptableSpec::CbCascadedChild, :before_validation],
1837
+ [InterceptableSpec::CbCascadedChild, :after_validation],
1838
+
1839
+ [InterceptableSpec::CbParent, :after_validation],
1840
+ [InterceptableSpec::CbParent, :before_save],
1841
+ [InterceptableSpec::CbParent, :around_save_open],
1842
+ [InterceptableSpec::CbParent, :before_create],
1843
+ [InterceptableSpec::CbParent, :around_create_open],
1844
+
1845
+ [InterceptableSpec::CbCascadedChild, :before_save],
1846
+ [InterceptableSpec::CbCascadedChild, :before_create],
1847
+
1848
+ [InterceptableSpec::CbCascadedChild, :after_create],
1849
+ [InterceptableSpec::CbCascadedChild, :after_save],
1850
+
1851
+ [InterceptableSpec::CbParent, :around_create_close],
1852
+ [InterceptableSpec::CbParent, :after_create],
1853
+ [InterceptableSpec::CbParent, :around_save_close],
1854
+ [InterceptableSpec::CbParent, :after_save]
1855
+ ]
1856
+ end
1857
+
1858
+ it 'calls callbacks in the right order' do
1859
+ parent.save!
1860
+ expect(registry.calls).to eq expected
1861
+ end
1862
+ end
1863
+ end
1864
+
1865
+ context "with associations" do
1866
+ context "has_one" do
1867
+ let(:registry) { InterceptableSpec::CallbackRegistry.new }
1868
+
1869
+ let(:parent) do
1870
+ InterceptableSpec::CbHasOneParent.new(registry).tap do |parent|
1871
+ parent.child = InterceptableSpec::CbHasOneChild.new(registry)
1872
+ end
1873
+ end
1874
+
1875
+ let(:expected) do
1876
+ [
1877
+ [InterceptableSpec::CbHasOneParent, :before_validation],
1878
+ [InterceptableSpec::CbHasOneChild, :before_validation],
1879
+ [InterceptableSpec::CbHasOneChild, :after_validation],
1880
+ [InterceptableSpec::CbHasOneParent, :after_validation],
1881
+ [InterceptableSpec::CbHasOneParent, :before_save],
1882
+
1883
+ [InterceptableSpec::CbHasOneParent, :around_save_open],
1884
+ [InterceptableSpec::CbHasOneParent, :before_create],
1885
+ [InterceptableSpec::CbHasOneParent, :around_create_open],
1886
+
1887
+ [InterceptableSpec::CbHasOneParent, :insert_into_database],
1888
+
1889
+ [InterceptableSpec::CbHasOneChild, :before_validation],
1890
+ [InterceptableSpec::CbHasOneChild, :after_validation],
1891
+ [InterceptableSpec::CbHasOneChild, :before_save],
1892
+ [InterceptableSpec::CbHasOneChild, :around_save_open],
1893
+ [InterceptableSpec::CbHasOneChild, :before_create],
1894
+ [InterceptableSpec::CbHasOneChild, :around_create_open],
1895
+
1896
+ [InterceptableSpec::CbHasOneChild, :around_create_close],
1897
+ [InterceptableSpec::CbHasOneChild, :after_create],
1898
+ [InterceptableSpec::CbHasOneChild, :around_save_close],
1899
+ [InterceptableSpec::CbHasOneChild, :after_save],
1900
+
1901
+ [InterceptableSpec::CbHasOneParent, :around_create_close],
1902
+ [InterceptableSpec::CbHasOneParent, :after_create],
1903
+ [InterceptableSpec::CbHasOneParent, :around_save_close],
1904
+ [InterceptableSpec::CbHasOneParent, :after_save],
1905
+ ]
1906
+ end
1907
+
1908
+ it 'calls callbacks in the right order' do
1909
+ parent.save!
1910
+ expect(registry.calls).to eq expected
1911
+ end
1912
+ end
1913
+
1914
+ context "embeds_one" do
1915
+ let(:registry) { InterceptableSpec::CallbackRegistry.new }
1916
+
1917
+ let(:parent) do
1918
+ InterceptableSpec::CbEmbedsOneParent.new(registry).tap do |parent|
1919
+ parent.child = InterceptableSpec::CbEmbedsOneChild.new(registry)
1920
+ end
1921
+ end
1922
+
1923
+ context "create" do
1924
+ context "with around callbacks" do
1925
+ config_override :around_callbacks_for_embeds, true
1926
+
1927
+ let(:expected) do
1928
+ [
1929
+ [InterceptableSpec::CbEmbedsOneChild, :before_validation],
1930
+ [InterceptableSpec::CbEmbedsOneChild, :after_validation],
1931
+ [InterceptableSpec::CbEmbedsOneParent, :before_validation],
1932
+ [InterceptableSpec::CbEmbedsOneChild, :before_validation],
1933
+ [InterceptableSpec::CbEmbedsOneChild, :after_validation],
1934
+ [InterceptableSpec::CbEmbedsOneParent, :after_validation],
1935
+
1936
+ [InterceptableSpec::CbEmbedsOneParent, :before_save],
1937
+ [InterceptableSpec::CbEmbedsOneParent, :around_save_open],
1938
+ [InterceptableSpec::CbEmbedsOneParent, :before_create],
1939
+ [InterceptableSpec::CbEmbedsOneParent, :around_create_open],
1940
+
1941
+ [InterceptableSpec::CbEmbedsOneChild, :before_save],
1942
+ [InterceptableSpec::CbEmbedsOneChild, :around_save_open],
1943
+ [InterceptableSpec::CbEmbedsOneChild, :before_create],
1944
+ [InterceptableSpec::CbEmbedsOneChild, :around_create_open],
1945
+
1946
+ [InterceptableSpec::CbEmbedsOneParent, :insert_into_database],
1947
+
1948
+ [InterceptableSpec::CbEmbedsOneChild, :around_create_close],
1949
+ [InterceptableSpec::CbEmbedsOneChild, :after_create],
1950
+ [InterceptableSpec::CbEmbedsOneChild, :around_save_close],
1951
+ [InterceptableSpec::CbEmbedsOneChild, :after_save],
1952
+
1953
+ [InterceptableSpec::CbEmbedsOneParent, :around_create_close],
1954
+ [InterceptableSpec::CbEmbedsOneParent, :after_create],
1955
+ [InterceptableSpec::CbEmbedsOneParent, :around_save_close],
1956
+ [InterceptableSpec::CbEmbedsOneParent, :after_save]
1957
+ ]
1958
+ end
1959
+
1960
+ it 'calls callbacks in the right order' do
1961
+ parent.save!
1962
+ expect(registry.calls).to eq expected
1963
+ end
1964
+ end
1965
+
1966
+ context "without around callbacks" do
1967
+ config_override :around_callbacks_for_embeds, false
1968
+
1969
+ let(:expected) do
1970
+ [
1971
+ [InterceptableSpec::CbEmbedsOneChild, :before_validation],
1972
+ [InterceptableSpec::CbEmbedsOneChild, :after_validation],
1973
+ [InterceptableSpec::CbEmbedsOneParent, :before_validation],
1974
+ [InterceptableSpec::CbEmbedsOneChild, :before_validation],
1975
+ [InterceptableSpec::CbEmbedsOneChild, :after_validation],
1976
+ [InterceptableSpec::CbEmbedsOneParent, :after_validation],
1977
+
1978
+ [InterceptableSpec::CbEmbedsOneParent, :before_save],
1979
+ [InterceptableSpec::CbEmbedsOneParent, :around_save_open],
1980
+ [InterceptableSpec::CbEmbedsOneParent, :before_create],
1981
+ [InterceptableSpec::CbEmbedsOneParent, :around_create_open],
1982
+
1983
+ [InterceptableSpec::CbEmbedsOneChild, :before_save],
1984
+ [InterceptableSpec::CbEmbedsOneChild, :before_create],
1985
+
1986
+ [InterceptableSpec::CbEmbedsOneParent, :insert_into_database],
1987
+
1988
+ [InterceptableSpec::CbEmbedsOneChild, :after_create],
1989
+ [InterceptableSpec::CbEmbedsOneChild, :after_save],
1990
+
1991
+ [InterceptableSpec::CbEmbedsOneParent, :around_create_close],
1992
+ [InterceptableSpec::CbEmbedsOneParent, :after_create],
1993
+ [InterceptableSpec::CbEmbedsOneParent, :around_save_close],
1994
+ [InterceptableSpec::CbEmbedsOneParent, :after_save]
1995
+ ]
1996
+ end
1997
+
1998
+ it 'calls callbacks in the right order' do
1999
+ parent.save!
2000
+ expect(registry.calls).to eq expected
2001
+ end
2002
+ end
2003
+ end
2004
+
2005
+ context "update" do
2006
+ context "with around callbacks" do
2007
+ config_override :around_callbacks_for_embeds, true
2008
+
2009
+ let(:expected) do
2010
+ [
2011
+ [InterceptableSpec::CbEmbedsOneChild, :before_validation],
2012
+ [InterceptableSpec::CbEmbedsOneChild, :after_validation],
2013
+ [InterceptableSpec::CbEmbedsOneParent, :before_validation],
2014
+ [InterceptableSpec::CbEmbedsOneChild, :before_validation],
2015
+ [InterceptableSpec::CbEmbedsOneChild, :after_validation],
2016
+ [InterceptableSpec::CbEmbedsOneParent, :after_validation],
2017
+
2018
+ [InterceptableSpec::CbEmbedsOneParent, :before_save],
2019
+ [InterceptableSpec::CbEmbedsOneParent, :around_save_open],
2020
+ [InterceptableSpec::CbEmbedsOneParent, :before_update],
2021
+ [InterceptableSpec::CbEmbedsOneParent, :around_update_open],
2022
+
2023
+ [InterceptableSpec::CbEmbedsOneChild, :before_save],
2024
+ [InterceptableSpec::CbEmbedsOneChild, :around_save_open],
2025
+ [InterceptableSpec::CbEmbedsOneChild, :before_update],
2026
+ [InterceptableSpec::CbEmbedsOneChild, :around_update_open],
2027
+
2028
+ [InterceptableSpec::CbEmbedsOneChild, :around_update_close],
2029
+ [InterceptableSpec::CbEmbedsOneChild, :after_update],
2030
+ [InterceptableSpec::CbEmbedsOneChild, :around_save_close],
2031
+ [InterceptableSpec::CbEmbedsOneChild, :after_save],
2032
+
2033
+ [InterceptableSpec::CbEmbedsOneParent, :around_update_close],
2034
+ [InterceptableSpec::CbEmbedsOneParent, :after_update],
2035
+ [InterceptableSpec::CbEmbedsOneParent, :around_save_close],
2036
+ [InterceptableSpec::CbEmbedsOneParent, :after_save]
2037
+ ]
2038
+ end
2039
+
2040
+ it 'calls callbacks in the right order' do
2041
+ parent.callback_registry = nil
2042
+ parent.child.callback_registry = nil
2043
+ parent.save!
2044
+
2045
+ parent.callback_registry = registry
2046
+ parent.child.callback_registry = registry
2047
+ parent.name = "name"
2048
+ parent.child.age = 10
2049
+
2050
+ parent.save!
2051
+ expect(registry.calls).to eq expected
2052
+ end
2053
+ end
2054
+
2055
+ context "without around callbacks" do
2056
+ config_override :around_callbacks_for_embeds, false
2057
+
2058
+ let(:expected) do
2059
+ [
2060
+ [InterceptableSpec::CbEmbedsOneChild, :before_validation],
2061
+ [InterceptableSpec::CbEmbedsOneChild, :after_validation],
2062
+ [InterceptableSpec::CbEmbedsOneParent, :before_validation],
2063
+ [InterceptableSpec::CbEmbedsOneChild, :before_validation],
2064
+ [InterceptableSpec::CbEmbedsOneChild, :after_validation],
2065
+ [InterceptableSpec::CbEmbedsOneParent, :after_validation],
2066
+
2067
+ [InterceptableSpec::CbEmbedsOneParent, :before_save],
2068
+ [InterceptableSpec::CbEmbedsOneParent, :around_save_open],
2069
+ [InterceptableSpec::CbEmbedsOneParent, :before_update],
2070
+ [InterceptableSpec::CbEmbedsOneParent, :around_update_open],
2071
+
2072
+ [InterceptableSpec::CbEmbedsOneChild, :before_save],
2073
+ [InterceptableSpec::CbEmbedsOneChild, :before_update],
2074
+
2075
+ [InterceptableSpec::CbEmbedsOneChild, :after_update],
2076
+ [InterceptableSpec::CbEmbedsOneChild, :after_save],
2077
+
2078
+ [InterceptableSpec::CbEmbedsOneParent, :around_update_close],
2079
+ [InterceptableSpec::CbEmbedsOneParent, :after_update],
2080
+ [InterceptableSpec::CbEmbedsOneParent, :around_save_close],
2081
+ [InterceptableSpec::CbEmbedsOneParent, :after_save]
2082
+ ]
2083
+ end
2084
+
2085
+ it 'calls callbacks in the right order' do
2086
+ parent.callback_registry = nil
2087
+ parent.child.callback_registry = nil
2088
+ parent.save!
2089
+
2090
+ parent.callback_registry = registry
2091
+ parent.child.callback_registry = registry
2092
+ parent.name = "name"
2093
+ parent.child.age = 10
2094
+
2095
+ parent.save!
2096
+ expect(registry.calls).to eq expected
2097
+ end
2098
+ end
2099
+ end
2100
+ end
2101
+
2102
+ context "has_many" do
2103
+ let(:registry) { InterceptableSpec::CallbackRegistry.new }
2104
+
2105
+ let(:parent) do
2106
+ InterceptableSpec::CbHasManyParent.new(registry).tap do |parent|
2107
+ parent.children = [
2108
+ InterceptableSpec::CbHasManyChild.new(registry),
2109
+ InterceptableSpec::CbHasManyChild.new(registry)
2110
+ ]
2111
+ end
2112
+ end
2113
+
2114
+ let(:expected) do
2115
+ [
2116
+ [InterceptableSpec::CbHasManyParent, :before_validation],
2117
+ [InterceptableSpec::CbHasManyChild, :before_validation],
2118
+ [InterceptableSpec::CbHasManyChild, :after_validation],
2119
+ [InterceptableSpec::CbHasManyChild, :before_validation],
2120
+ [InterceptableSpec::CbHasManyChild, :after_validation],
2121
+ [InterceptableSpec::CbHasManyParent, :after_validation],
2122
+
2123
+ [InterceptableSpec::CbHasManyParent, :before_save],
2124
+ [InterceptableSpec::CbHasManyParent, :around_save_open],
2125
+ [InterceptableSpec::CbHasManyParent, :before_create],
2126
+ [InterceptableSpec::CbHasManyParent, :around_create_open],
2127
+
2128
+ [InterceptableSpec::CbHasManyParent, :insert_into_database],
2129
+
2130
+ [InterceptableSpec::CbHasManyChild, :before_validation],
2131
+ [InterceptableSpec::CbHasManyChild, :after_validation],
2132
+ [InterceptableSpec::CbHasManyChild, :before_save],
2133
+ [InterceptableSpec::CbHasManyChild, :around_save_open],
2134
+ [InterceptableSpec::CbHasManyChild, :before_create],
2135
+ [InterceptableSpec::CbHasManyChild, :around_create_open],
2136
+ [InterceptableSpec::CbHasManyChild, :around_create_close],
2137
+ [InterceptableSpec::CbHasManyChild, :after_create],
2138
+ [InterceptableSpec::CbHasManyChild, :around_save_close],
2139
+ [InterceptableSpec::CbHasManyChild, :after_save],
2140
+
2141
+ [InterceptableSpec::CbHasManyChild, :before_validation],
2142
+ [InterceptableSpec::CbHasManyChild, :after_validation],
2143
+ [InterceptableSpec::CbHasManyChild, :before_save],
2144
+ [InterceptableSpec::CbHasManyChild, :around_save_open],
2145
+ [InterceptableSpec::CbHasManyChild, :before_create],
2146
+ [InterceptableSpec::CbHasManyChild, :around_create_open],
2147
+ [InterceptableSpec::CbHasManyChild, :around_create_close],
2148
+ [InterceptableSpec::CbHasManyChild, :after_create],
2149
+ [InterceptableSpec::CbHasManyChild, :around_save_close],
2150
+ [InterceptableSpec::CbHasManyChild, :after_save],
2151
+
2152
+ [InterceptableSpec::CbHasManyParent, :around_create_close],
2153
+ [InterceptableSpec::CbHasManyParent, :after_create],
2154
+ [InterceptableSpec::CbHasManyParent, :around_save_close],
2155
+ [InterceptableSpec::CbHasManyParent, :after_save]
2156
+ ]
2157
+ end
2158
+
2159
+ it 'calls callbacks in the right order' do
2160
+ parent.save!
2161
+ expect(registry.calls).to eq expected
2162
+ end
2163
+ end
2164
+
2165
+ context "embeds_many" do
2166
+ let(:registry) { InterceptableSpec::CallbackRegistry.new }
2167
+
2168
+ let(:parent) do
2169
+ InterceptableSpec::CbEmbedsManyParent.new(registry).tap do |parent|
2170
+ parent.children = [
2171
+ InterceptableSpec::CbEmbedsManyChild.new(registry),
2172
+ InterceptableSpec::CbEmbedsManyChild.new(registry),
2173
+ ]
2174
+ end
2175
+ end
2176
+
2177
+ context "with around callbacks" do
2178
+ config_override :around_callbacks_for_embeds, true
2179
+
2180
+ let(:expected) do
2181
+ [
2182
+ [InterceptableSpec::CbEmbedsManyChild, :before_validation],
2183
+ [InterceptableSpec::CbEmbedsManyChild, :after_validation],
2184
+ [InterceptableSpec::CbEmbedsManyChild, :before_validation],
2185
+ [InterceptableSpec::CbEmbedsManyChild, :after_validation],
2186
+ [InterceptableSpec::CbEmbedsManyParent, :before_validation],
2187
+ [InterceptableSpec::CbEmbedsManyChild, :before_validation],
2188
+ [InterceptableSpec::CbEmbedsManyChild, :after_validation],
2189
+ [InterceptableSpec::CbEmbedsManyChild, :before_validation],
2190
+ [InterceptableSpec::CbEmbedsManyChild, :after_validation],
2191
+ [InterceptableSpec::CbEmbedsManyParent, :after_validation],
2192
+
2193
+ [InterceptableSpec::CbEmbedsManyParent, :before_save],
2194
+ [InterceptableSpec::CbEmbedsManyParent, :around_save_open],
2195
+ [InterceptableSpec::CbEmbedsManyParent, :before_create],
2196
+ [InterceptableSpec::CbEmbedsManyParent, :around_create_open],
2197
+
2198
+ [InterceptableSpec::CbEmbedsManyChild, :before_save],
2199
+ [InterceptableSpec::CbEmbedsManyChild, :around_save_open],
2200
+ [InterceptableSpec::CbEmbedsManyChild, :before_save],
2201
+
2202
+ [InterceptableSpec::CbEmbedsManyChild, :around_save_open],
2203
+ [InterceptableSpec::CbEmbedsManyChild, :before_create],
2204
+ [InterceptableSpec::CbEmbedsManyChild, :around_create_open],
2205
+
2206
+ [InterceptableSpec::CbEmbedsManyChild, :before_create],
2207
+ [InterceptableSpec::CbEmbedsManyChild, :around_create_open],
2208
+
2209
+ [InterceptableSpec::CbEmbedsManyParent, :insert_into_database],
2210
+
2211
+ [InterceptableSpec::CbEmbedsManyChild, :around_create_close],
2212
+ [InterceptableSpec::CbEmbedsManyChild, :after_create],
2213
+
2214
+ [InterceptableSpec::CbEmbedsManyChild, :around_create_close],
2215
+ [InterceptableSpec::CbEmbedsManyChild, :after_create],
2216
+
2217
+ [InterceptableSpec::CbEmbedsManyChild, :around_save_close],
2218
+ [InterceptableSpec::CbEmbedsManyChild, :after_save],
2219
+
2220
+ [InterceptableSpec::CbEmbedsManyChild, :around_save_close],
2221
+ [InterceptableSpec::CbEmbedsManyChild, :after_save],
2222
+
2223
+ [InterceptableSpec::CbEmbedsManyParent, :around_create_close],
2224
+ [InterceptableSpec::CbEmbedsManyParent, :after_create],
2225
+ [InterceptableSpec::CbEmbedsManyParent, :around_save_close],
2226
+ [InterceptableSpec::CbEmbedsManyParent, :after_save]
2227
+ ]
2228
+ end
2229
+
2230
+ it 'calls callbacks in the right order' do
2231
+ parent.save!
2232
+ expect(registry.calls).to eq expected
2233
+ end
2234
+ end
2235
+
2236
+ context "without around callbacks" do
2237
+ config_override :around_callbacks_for_embeds, false
2238
+
2239
+ let(:expected) do
2240
+ [
2241
+ [InterceptableSpec::CbEmbedsManyChild, :before_validation],
2242
+ [InterceptableSpec::CbEmbedsManyChild, :after_validation],
2243
+ [InterceptableSpec::CbEmbedsManyChild, :before_validation],
2244
+ [InterceptableSpec::CbEmbedsManyChild, :after_validation],
2245
+ [InterceptableSpec::CbEmbedsManyParent, :before_validation],
2246
+ [InterceptableSpec::CbEmbedsManyChild, :before_validation],
2247
+ [InterceptableSpec::CbEmbedsManyChild, :after_validation],
2248
+ [InterceptableSpec::CbEmbedsManyChild, :before_validation],
2249
+ [InterceptableSpec::CbEmbedsManyChild, :after_validation],
2250
+ [InterceptableSpec::CbEmbedsManyParent, :after_validation],
2251
+
2252
+ [InterceptableSpec::CbEmbedsManyParent, :before_save],
2253
+ [InterceptableSpec::CbEmbedsManyParent, :around_save_open],
2254
+ [InterceptableSpec::CbEmbedsManyParent, :before_create],
2255
+ [InterceptableSpec::CbEmbedsManyParent, :around_create_open],
2256
+
2257
+ [InterceptableSpec::CbEmbedsManyChild, :before_save],
2258
+ [InterceptableSpec::CbEmbedsManyChild, :before_save],
2259
+
2260
+ [InterceptableSpec::CbEmbedsManyChild, :before_create],
2261
+
2262
+ [InterceptableSpec::CbEmbedsManyChild, :before_create],
2263
+
2264
+ [InterceptableSpec::CbEmbedsManyParent, :insert_into_database],
2265
+
2266
+ [InterceptableSpec::CbEmbedsManyChild, :after_create],
2267
+
2268
+ [InterceptableSpec::CbEmbedsManyChild, :after_create],
2269
+
2270
+ [InterceptableSpec::CbEmbedsManyChild, :after_save],
2271
+
2272
+ [InterceptableSpec::CbEmbedsManyChild, :after_save],
2273
+
2274
+ [InterceptableSpec::CbEmbedsManyParent, :around_create_close],
2275
+ [InterceptableSpec::CbEmbedsManyParent, :after_create],
2276
+ [InterceptableSpec::CbEmbedsManyParent, :around_save_close],
2277
+ [InterceptableSpec::CbEmbedsManyParent, :after_save]
2278
+ ]
2279
+ end
2280
+
2281
+ it 'calls callbacks in the right order' do
2282
+ parent.save!
2283
+ expect(registry.calls).to eq expected
2284
+ end
2285
+ end
2286
+ end
2287
+ end
2288
+
2289
+ context "when accessing parent document from callbacks" do
2290
+ shared_examples 'accesses the correct parent' do
2291
+ it "accesses the correct parent in after_find" do
2292
+ expect(from_db.after_find_player).to eq(player._id)
2293
+ end
2294
+
2295
+ it "accesses the correct parent in after_initialize" do
2296
+ expect(from_db.after_initialize_player).to eq(player._id)
2297
+ end
2298
+
2299
+ it "accesses the correct parent in default" do
2300
+ expect(from_db.after_default_player).to eq(player._id)
2301
+ end
2302
+
2303
+ it "accesses the correct parent in unpersisted after_initialize" do
2304
+ expect(unpersisted.after_initialize_player).to eq(player._id)
2305
+ end
2306
+ end
2307
+
2308
+ context "when using create methods" do
2309
+
2310
+ context "when the child is an embeds_many association" do
2311
+ let!(:player) do
2312
+ Player.create!.tap do |player|
2313
+ player.implants.create!
2314
+ end
2315
+ end
2316
+
2317
+ let(:unpersisted) { player.implants.first }
2318
+
2319
+ before do
2320
+ # The default is originally set when creating this document, and it is
2321
+ # subsequently persisted to the database. Therefore when we retrieve
2322
+ # this document from the database, this field is already set, and
2323
+ # the default Proc is not called. This unset is needed to allow the
2324
+ # default Proc to be called when the document is retrieved from the
2325
+ # database.
2326
+ Player.find(player.id).implants.first.unset(:after_default_player)
2327
+ end
2328
+
2329
+ let(:from_db) do
2330
+ Player.find(player.id).implants.first
2331
+ end
2332
+
2333
+ include_examples 'accesses the correct parent'
2334
+ end
2335
+
2336
+ context "when the child is an embeds_one association" do
2337
+ let!(:player) do
2338
+ Player.create!.tap do |player|
2339
+ player.create_augmentation
2340
+ end
2341
+ end
2342
+
2343
+ let(:unpersisted) { player.augmentation }
2344
+
2345
+ before do
2346
+ Player.find(player.id).augmentation.unset(:after_default_player)
2347
+ end
2348
+
2349
+ let(:from_db) do
2350
+ Player.find(player.id).augmentation
2351
+ end
2352
+
2353
+ include_examples 'accesses the correct parent'
2354
+ end
2355
+
2356
+ context "when the child is a has_many association" do
2357
+ let!(:player) do
2358
+ Player.create!.tap do |player|
2359
+ player.weapons.create!
2360
+ end
2361
+ end
2362
+
2363
+ let(:unpersisted) { player.weapons.first }
2364
+
2365
+ before do
2366
+ Player.find(player.id).weapons.first.unset(:after_default_player)
2367
+ end
2368
+
2369
+ let(:from_db) do
2370
+ Player.find(player.id).weapons.first
2371
+ end
2372
+
2373
+ include_examples 'accesses the correct parent'
2374
+ end
2375
+
2376
+ context "when the child is a has_one association" do
2377
+ let!(:player) do
2378
+ Player.create!.tap do |player|
2379
+ player.create_powerup
2380
+ player.save!
2381
+ end
2382
+ end
2383
+
2384
+ let(:unpersisted) { player.powerup }
2385
+
2386
+ before do
2387
+ Player.find(player.id).powerup.unset(:after_default_player)
2388
+ end
2389
+
2390
+ let(:from_db) do
2391
+ Player.find(player.id).powerup
2392
+ end
2393
+
2394
+ include_examples 'accesses the correct parent'
2395
+ end
2396
+
2397
+ context "when the child is a has_and_belongs_to_many association" do
2398
+ let!(:player) do
2399
+ Player.create!.tap do |player|
2400
+ player.shields.create!
2401
+ end
2402
+ end
2403
+
2404
+ let(:unpersisted) { player.shields.first }
2405
+
2406
+ before do
2407
+ Player.find(player.id).shields.unset(:after_default_player)
2408
+ end
2409
+
2410
+ let(:from_db) do
2411
+ Player.find(player.id).shields.first
2412
+ end
2413
+
2414
+ include_examples 'accesses the correct parent'
2415
+ end
2416
+ end
2417
+
2418
+ context "when using build methods" do
2419
+
2420
+ context "when the child is an embeds_many association" do
2421
+ let!(:player) do
2422
+ Player.create!.tap do |player|
2423
+ player.implants.build
2424
+ player.implants.first.save!
2425
+ end
2426
+ end
2427
+
2428
+ let(:unpersisted) { player.implants.first }
2429
+
2430
+ before do
2431
+ Player.find(player.id).implants.first.unset(:after_default_player)
2432
+ end
2433
+
2434
+ let(:from_db) do
2435
+ Player.find(player.id).implants.first
2436
+ end
2437
+
2438
+ include_examples 'accesses the correct parent'
2439
+ end
2440
+
2441
+ context "when the child is an embeds_one association" do
2442
+ let!(:player) do
2443
+ Player.create!.tap do |player|
2444
+ player.build_augmentation
2445
+ player.save!
2446
+ end
2447
+ end
2448
+
2449
+ let(:unpersisted) { player.augmentation }
2450
+
2451
+ before do
2452
+ Player.find(player.id).augmentation.unset(:after_default_player)
2453
+ end
2454
+
2455
+ let(:from_db) do
2456
+ Player.find(player.id).augmentation
2457
+ end
2458
+
2459
+ include_examples 'accesses the correct parent'
2460
+ end
2461
+
2462
+ context "when the child is a has_many association" do
2463
+ let!(:player) do
2464
+ Player.create!.tap do |player|
2465
+ player.weapons.build
2466
+ player.weapons.first.save!
2467
+ end
2468
+ end
2469
+
2470
+ let(:unpersisted) { player.weapons.first }
2471
+
2472
+ before do
2473
+ Player.find(player.id).weapons.first.unset(:after_default_player)
2474
+ end
2475
+
2476
+ let(:from_db) do
2477
+ Player.find(player.id).weapons.first
2478
+ end
2479
+
2480
+ include_examples 'accesses the correct parent'
2481
+ end
2482
+
2483
+ context "when the child is a has_one association" do
2484
+ let!(:player) do
2485
+ Player.create!.tap do |player|
2486
+ player.build_powerup
2487
+ player.powerup.save!
2488
+ end
2489
+ end
2490
+
2491
+ let(:unpersisted) { player.powerup }
2492
+
2493
+ before do
2494
+ Player.find(player.id).powerup.unset(:after_default_player)
2495
+ end
2496
+
2497
+ let(:from_db) do
2498
+ Player.find(player.id).powerup
2499
+ end
2500
+
2501
+ include_examples 'accesses the correct parent'
2502
+ end
2503
+
2504
+ context "when the child is a has_and_belongs_to_many association" do
2505
+ let!(:player) do
2506
+ Player.create!.tap do |player|
2507
+ player.shields.build
2508
+ player.shields.first.save!
2509
+ end
2510
+ end
2511
+
2512
+ let(:unpersisted) { player.shields.first }
2513
+
2514
+ before do
2515
+ Player.find(player.id).shields.unset(:after_default_player)
2516
+ end
2517
+
2518
+ let(:from_db) do
2519
+ Player.find(player.id).shields.first
2520
+ end
2521
+
2522
+ include_examples 'accesses the correct parent'
2523
+ end
2524
+ end
2525
+ end
2526
+
2527
+ context "when accessing associations in defaults" do
2528
+ context "when not using autobuilding" do
2529
+ let(:band) { InterceptableBand.create(name: "Molejo") }
2530
+ let(:song) { band.songs.create(name: "Cilada") }
2531
+
2532
+ it "assigns the default correctly" do
2533
+ expect(song.band_name).to eq("Molejo")
2534
+ end
2535
+ end
2536
+
2537
+ context "when using autobuilding" do
2538
+ before do
2539
+ InterceptablePlane.create!.tap do |plane|
2540
+ plane.wings.create!
2541
+ end
2542
+ end
2543
+
2544
+ let(:plane) { InterceptablePlane.first }
2545
+ let(:wing) { InterceptableWing.first }
2546
+ let(:engine) { wing.engine }
2547
+
2548
+ it "sets the defaults correctly" do
2549
+ expect(wing._id).to eq("hello-wing")
2550
+ expect(wing.p_id).to eq(plane._id.to_s)
2551
+ expect(wing.e_id).to eq(engine._id.to_s)
2552
+ expect(engine._id).to eq("hello-engine-#{wing.id}")
2553
+ end
2554
+ end
2555
+ end
2556
+
2557
+ # This case is rather niche. The _ids method used to use the `.only` method
2558
+ # to get only the _ids for an association, which was causing a
2559
+ # MissingAttributeError to be raised when accessing another association. This
2560
+ # was fixed by using `.pluck` over `.only`. Look at MONGOID-5306 for a more
2561
+ # detailed explanation.
2562
+ context "when accessing _ids in validate and access an association in after_initialize" do
2563
+ it "doesn't raise a MissingAttributeError" do
2564
+ company = InterceptableCompany.create!
2565
+ shop = InterceptableShop.create!(company: company)
2566
+ user = InterceptableUser.new
2567
+ user.company = company
2568
+ expect do
2569
+ user.save!
2570
+ end.to_not raise_error(ActiveModel::MissingAttributeError)
2571
+ end
2572
+ end
2573
+
2574
+ context "when around callbacks for embedded are disabled" do
2575
+ config_override :around_callbacks_for_embeds, false
2576
+
2577
+ context "when around callback is defined" do
2578
+ let(:registry) { InterceptableSpec::CallbackRegistry.new }
2579
+
2580
+ let(:parent) do
2581
+ InterceptableSpec::CbEmbedsOneParent.new(registry).tap do |parent|
2582
+ parent.child = InterceptableSpec::CbEmbedsOneChild.new(registry)
2583
+ end
2584
+ end
2585
+
2586
+ before do
2587
+ expect(Mongoid.logger).to receive(:warn).with(/Around callbacks are disabled for embedded documents/).twice.and_call_original
2588
+ expect(Mongoid.logger).to receive(:warn).with(/To enable around callbacks for embedded documents/).twice.and_call_original
2589
+ end
2590
+
2591
+ it "logs a warning" do
2592
+ parent.save!
2593
+ end
1792
2594
  end
1793
2595
  end
1794
2596
  end