mongoid 7.5.4 → 8.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (414) 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 +140 -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 +517 -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 +36 -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 +19 -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 +76 -15
  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 +360 -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 +1572 -435
  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 +599 -8
  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/spec_helper.rb +5 -0
  382. data/spec/support/constraints.rb +24 -0
  383. data/spec/support/immutable_ids.rb +118 -0
  384. data/spec/support/macros.rb +78 -0
  385. data/spec/support/models/artist.rb +0 -1
  386. data/spec/support/models/augmentation.rb +12 -0
  387. data/spec/support/models/band.rb +4 -0
  388. data/spec/support/models/book.rb +1 -0
  389. data/spec/support/models/building.rb +2 -0
  390. data/spec/support/models/catalog.rb +24 -0
  391. data/spec/support/models/circus.rb +3 -0
  392. data/spec/support/models/cover.rb +10 -0
  393. data/spec/support/models/fanatic.rb +8 -0
  394. data/spec/support/models/implant.rb +9 -0
  395. data/spec/support/models/label.rb +2 -0
  396. data/spec/support/models/passport.rb +9 -0
  397. data/spec/support/models/person.rb +2 -0
  398. data/spec/support/models/player.rb +2 -0
  399. data/spec/support/models/powerup.rb +12 -0
  400. data/spec/support/models/product.rb +1 -0
  401. data/spec/support/models/purse.rb +9 -0
  402. data/spec/support/models/registry.rb +1 -0
  403. data/spec/support/models/school.rb +14 -0
  404. data/spec/support/models/shield.rb +18 -0
  405. data/spec/support/models/student.rb +14 -0
  406. data/spec/support/models/weapon.rb +12 -0
  407. data.tar.gz.sig +0 -0
  408. metadata +93 -15
  409. metadata.gz.sig +0 -0
  410. data/lib/mongoid/errors/eager_load.rb +0 -23
  411. data/lib/mongoid/errors/invalid_value.rb +0 -17
  412. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -60
  413. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -60
  414. data/spec/mongoid/errors/eager_load_spec.rb +0 -31
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ce7f228fdc033dc1142f46f4771395d36acafc97e0c144599cd063af537c7ae3
4
- data.tar.gz: 15f8f0efbb076eb03f25f23898cbe27d044e7441e4a7ae4bc8d22f036838bb98
3
+ metadata.gz: 2100bfc3ff5a707914028bbcca16fe61db68cfc271f2603b79a9f420baccdd3a
4
+ data.tar.gz: c1147f2941f122d45a5678ed2c9d95ab840a65e1f8883970384f846f979bfb9f
5
5
  SHA512:
6
- metadata.gz: 91f40b7136ae729e6831c5033c60c0a1e2207cd98d80bf5caaef50844230d6830efe555748571d9bdef62a101f75ffd21d2a7942278f84b68e2a51fc6a8f20df
7
- data.tar.gz: 3555b90da32865e1faadb9efccc6db0262adea620b4dd473d5dc1ee533b00451039dfaacd982ef5c8f6be4009ccff589119b2f512971a1b5ac509bb7ae4aa96e
6
+ metadata.gz: 4710b315e359d87807dc3b882b39d929eb52bf53612bf2d37e6bbf409309b3116773eab6e810b8b7dbbbfc33f24e135758c757b3de43dca4c591881b39d1e2df
7
+ data.tar.gz: 758af68d937986c4a01963ff9e8c6f106276fc40805c1133966d88461eabd19ca7b41e412b50566fe962b180525a925bae529ff5b58846fa8433336d8880a6ad
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -63,7 +63,7 @@ For instructions on upgrading to newer versions, visit
63
63
 
64
64
  * Mongoid now uses the official Mongo Ruby Driver 2.x instead of Moped.
65
65
 
66
- * Most driver specific configuration options have changed, please see [here](http://docs.mongodb.org/ecosystem/tutorial/ruby-driver-tutorial/#ruby-options) for the new options.
66
+ * Most driver specific configuration options have changed, please see [here](https://www.mongodb.com/docs/ecosystem/tutorial/ruby-driver-tutorial/#ruby-options) for the new options.
67
67
 
68
68
  * All references to `session` are now replaced with `client`. This includes the mongoid.yml configuration, `store_in` options, and all exceptions and modules with `Session` in the name.
69
69
 
@@ -872,8 +872,8 @@ child elements.
872
872
  handling of validations. (Gerad Suyderhoud)
873
873
 
874
874
  * \#2443 `expire_after_seconds` is now a valid index option
875
- (http://docs.mongodb.org/manual/core/indexes/#ttl-indexes,
876
- http://docs.mongodb.org/manual/tutorial/expire-data/).
875
+ (https://www.mongodb.com/docs/manual/core/indexes/#ttl-indexes,
876
+ https://www.mongodb.com/docs/manual/tutorial/expire-data/).
877
877
 
878
878
  class Event
879
879
  include Mongoid::Document
data/README.md CHANGED
@@ -8,20 +8,20 @@ Mongoid is an ODM (Object-Document Mapper) framework for MongoDB in Ruby.
8
8
  Documentation
9
9
  -------------
10
10
 
11
- Mongoid has [extensive user documentation](https://docs.mongodb.com/mongoid/current/).
12
- [API documentation](https://docs.mongodb.com/mongoid/current/api/) is also available.
11
+ Mongoid has [extensive user documentation](https://www.mongodb.com/docs/mongoid/current/).
12
+ [API documentation](https://www.mongodb.com/docs/mongoid/current/api/) is also available.
13
13
 
14
14
  Mongoid is built on top of the MongoDB Ruby driver which has
15
- [its own user documentation](https://docs.mongodb.com/ruby-driver/current/).
15
+ [its own user documentation](https://www.mongodb.com/docs/ruby-driver/current/).
16
16
 
17
17
  Compatibility
18
18
  -------------
19
19
 
20
20
  Mongoid supports and is tested against:
21
21
 
22
- - MRI 2.5 - 3.1
23
- - JRuby 9.2
24
- - MongoDB server 2.6 - 6.0
22
+ - MRI 2.6 - 3.1
23
+ - JRuby 9.3
24
+ - MongoDB server 3.6 - 6.0
25
25
 
26
26
  Issues
27
27
  ------
@@ -1,4 +1,8 @@
1
1
  en:
2
+ errors:
3
+ messages:
4
+ taken: "has already been taken"
5
+
2
6
  mongoid:
3
7
  errors:
4
8
  messages:
@@ -27,6 +31,17 @@ en:
27
31
  since the document did not actually get saved."
28
32
  resolution: "Double check all before callbacks to make sure they are
29
33
  not unintentionally returning false."
34
+ create_collection_failure:
35
+ message: "Cannot create collection %{collection_name}
36
+ with options %{collection_options}. The following error was raised:
37
+ %{error}."
38
+ summary: "The server rejected createCollection command with given collection
39
+ options. This may happen when some of the options are invalid, or not
40
+ supported by your version of the server."
41
+ resolution: "Double check that collection options for the collection
42
+ %{collection_name} are valid. Consult with Ruby driver documentation
43
+ and MongoDB documentation if the desired options are supported by
44
+ your version of the server."
30
45
  criteria_argument_required:
31
46
  message: "Calling Criteria methods with nil arguments is not allowed."
32
47
  summary: "Arguments to Criteria methods cannot be nil, and most
@@ -61,7 +76,7 @@ en:
61
76
  and the following ids were not found: %{missing}."
62
77
  resolution: "Search for an id that is in the database or set
63
78
  the Mongoid.raise_not_found_error configuration option to false,
64
- which will cause a nil to be returned instead of raising this error when
79
+ which will cause nil to be returned instead of raising this error when
65
80
  searching for a single id, or only the matched documents when searching
66
81
  for multiples."
67
82
  document_with_attributes_not_found:
@@ -71,20 +86,35 @@ en:
71
86
  will be raised."
72
87
  resolution: "Search for attributes that are in the database or set
73
88
  the Mongoid.raise_not_found_error configuration option to false,
74
- which will cause a nil to be returned instead of raising this error."
75
- eager_load:
76
- message: "Eager loading :%{name} is not supported since it is a
77
- polymorphic belongs_to association."
78
- summary: "Mongoid cannot currently determine the classes it needs to
79
- eager load when the association is polymorphic. The parents reside in
80
- different collections so a simple id lookup is not sufficient enough."
81
- resolution: "Don't attempt to perform this action and have patience,
82
- maybe this will be supported in the future."
89
+ which will cause nil to be returned instead of raising this error."
90
+ document_with_shard_key_not_found:
91
+ message: "Document not found for class %{klass} with id %{missing} and
92
+ shard key %{shard_key}."
93
+ summary: "When calling %{klass}.find with an id and a shard key, each
94
+ parameter must match a document in the database or this error will
95
+ be raised. The search was for the id: %{missing} with
96
+ shard_key: %{shard_key} and it was not found."
97
+ resolution: "Search for an id/shard key that is in the database or set
98
+ the Mongoid.raise_not_found_error configuration option to false,
99
+ which will cause nil to be returned instead of raising this error."
100
+ drop_collection_failure:
101
+ message: "Cannot drop collection %{collection_name}."
102
+ summary: "Mongoid tried to drop collection %{collection_name}, but the
103
+ collection still exists in the database."
104
+ resolution: "Try to drop the collection manually using Ruby driver or
105
+ mongo shell."
83
106
  empty_config_file:
84
107
  message: "Empty configuration file: %{path}."
85
108
  summary: "Your mongoid.yml configuration file appears to be empty."
86
109
  resolution: "Ensure your configuration file contains the correct contents.
87
- Refer to: https://docs.mongodb.com/mongoid/current/reference/configuration/"
110
+ Refer to: https://www.mongodb.com/docs/mongoid/current/reference/configuration/"
111
+ immutable_attribute:
112
+ message: "Attempted to change the immutable attribute '%{name}' with
113
+ the value: %{value}."
114
+ summary: "Immutable attributes can only have values set when the
115
+ document is a new record."
116
+ resolution: "Do not attempt to update the value of '%{name}' after
117
+ the document is persisted."
88
118
  invalid_collection:
89
119
  message: "Access to the collection for %{klass} is not allowed."
90
120
  summary: "%{klass}.collection was called, and %{klass} is an embedded
@@ -99,12 +129,20 @@ en:
99
129
  A collation option is only supported if the query is executed on a MongoDB server
100
130
  with version >= 3.4."
101
131
  resolution: "Remove the collation option from the query."
132
+ invalid_async_query_executor:
133
+ message: "Invalid async_query_executor option: %{executor}."
134
+ summary: "A invalid async query executor was specified.
135
+ The valid options are: %{options}."
136
+ resolution: "Pick an allowed option or fix the typo. If you were
137
+ expecting the option to be there, please consult the following page
138
+ with respect to Mongoid's configuration:\n\n
139
+ \_\_https://www.mongodb.com/docs/mongoid/current/reference/configuration/#mongoid-configuration-options"
102
140
  invalid_config_file:
103
141
  message: "Invalid configuration file: %{path}."
104
142
  summary: "Your mongoid.yml configuration file does not contain the
105
143
  correct file structure."
106
144
  resolution: "Ensure your configuration file contains the correct contents.
107
- Refer to: https://docs.mongodb.com/mongoid/current/reference/configuration/"
145
+ Refer to: https://www.mongodb.com/docs/mongoid/current/reference/configuration/"
108
146
  invalid_config_option:
109
147
  message: "Invalid configuration option: %{name}."
110
148
  summary: "A invalid configuration option was provided in your
@@ -126,6 +164,17 @@ en:
126
164
  allowed."
127
165
  resolution: "Try setting the discriminator key on %{superclass} or one of %{class_name}'s
128
166
  ancestors."
167
+ invalid_dot_dollar_assignment:
168
+ message: "Cannot set the %{attr} attribute on the %{klass} class."
169
+ summary: "Calling the setters for fields that start with a dollar
170
+ sign ($) or contain a dot/period (.) is prohibited. See the
171
+ Mongoid documentation on Field Names with Dots/Periods (.) and
172
+ Dollar Signs ($) for more information."
173
+ resolution: "In order to set fields that start with a dollar
174
+ sign ($) or contain a dot/period (.), the aggregation pipeline can
175
+ be used. MongoDB provides specific operators for working with these
176
+ fields. Refer to the MongoDB documentation here:
177
+ https://www.mongodb.com/docs/manual/core/dot-dollar-considerations/"
129
178
  invalid_elem_match_operator:
130
179
  message: "Invalid $elemMatch operator '%{operator}'."
131
180
  summary: "You misspelled an operator or are using an operator that
@@ -146,7 +195,7 @@ en:
146
195
  resolution: "Valid expression operators are: %{valid_operators}.
147
196
  Ensure you are using one of these operators."
148
197
  invalid_field:
149
- message: "Defining a field named '%{name}' is not allowed."
198
+ message: "Defining a field named '%{field}' is not allowed."
150
199
  summary: "Defining this field would override the method '%{name}',
151
200
  which would cause issues with expectations around the original
152
201
  method and cause extremely hard to debug issues. The original
@@ -180,7 +229,21 @@ en:
180
229
  \_\_\_\_field :%{name}, %{option}: true\n
181
230
  \_\_end\n\n
182
231
  Refer to:
183
- https://docs.mongodb.com/mongoid/current/reference/fields/#custom-field-options"
232
+ https://www.mongodb.com/docs/mongoid/current/reference/fields/#custom-field-options"
233
+ invalid_field_type:
234
+ message: "Invalid field type %{type_inspection} for field '%{field}' on model '%{klass}'."
235
+ summary: "Model '%{klass}' defines a field '%{field}' with an unknown type value
236
+ %{type_inspection}."
237
+ resolution: "Please provide a valid type value for the field.
238
+ Refer to:
239
+ https://www.mongodb.com/docs/mongoid/current/reference/fields/#using-symbols-or-strings-instead-of-classes"
240
+ invalid_global_executor_concurrency:
241
+ message: "Invalid global_executor_concurrency option."
242
+ summary: "You set global_executor_concurrency while async_query_executor
243
+ option is not set to :global_thread_pool. The global_executor_concurrency is
244
+ allowed only for the global thread pool executor."
245
+ resolution: "Set global_executor_concurrency option to :global_thread_pool
246
+ or remove global_executor_concurrency option."
184
247
  invalid_includes:
185
248
  message: "Invalid includes directive: %{klass}.includes(%{args})"
186
249
  summary: "Eager loading in Mongoid only supports providing arguments
@@ -196,7 +259,6 @@ en:
196
259
  Valid options are:\n
197
260
  \_\_background: true|false\n
198
261
  \_\_database: 'database_name'\n
199
- \_\_drop_dups: true|false\n
200
262
  \_\_name: 'index_name'\n
201
263
  \_\_sparse: true|false\n
202
264
  \_\_unique: true|false\n
@@ -215,7 +277,8 @@ en:
215
277
  \_\_language_override\n
216
278
  \_\_default_language\n
217
279
  \_\_collation\n
218
- Valid types are: 1, -1, '2d', '2dsphere', 'geoHaystack', 'text', 'hashed'\n\n
280
+ \_\_wildcard_projection: { 'path.to.field.a': 1, 'path.to.field.b': 0 }\n
281
+ Valid types are: 1, -1, '2d', '2dsphere', 'geoHaystack (deprecated)', 'text', 'hashed'\n\n
219
282
  Example:\n
220
283
  \_\_class Band\n
221
284
  \_\_\_\_include Mongoid::Document\n
@@ -291,7 +354,7 @@ en:
291
354
  invalid_storage_options:
292
355
  message: "Invalid options passed to %{klass}.store_in: %{options}."
293
356
  summary: "The :store_in macro takes only a hash of parameters with
294
- the keys :database, :collection, or :client."
357
+ the keys :database, :collection, :collection_options, or :client."
295
358
  resolution: "Change the options passed to store_in to match the
296
359
  documented API, and ensure all keys in the options hash are
297
360
  symbols.\n\n
@@ -300,12 +363,6 @@ en:
300
363
  \_\_\_\_include Mongoid::Document\n
301
364
  \_\_\_\_store_in collection: 'artists', database: 'music'\n
302
365
  \_\_end\n\n"
303
- invalid_storage_parent:
304
- message: "Invalid store_in call on class %{klass}."
305
- summary: "The :store_in macro can only be called on a base Mongoid Document"
306
- resolution: "Remove the store_in call on class %{klass}, as it will use its
307
- parent store configuration. Or remove the hierarchy extension for this
308
- class."
309
366
  invalid_time:
310
367
  message: "'%{value}' is not a valid Time."
311
368
  summary: "Mongoid tries to serialize the values for Date, DateTime, and
@@ -349,10 +406,6 @@ en:
349
406
  from the child side which association to go in."
350
407
  resolution: "Set the values from the parent, or redefine the association
351
408
  with only a single definition in the parent."
352
- invalid_value:
353
- message: "Value of type %{value_class} cannot be written to a field of type %{field_class}"
354
- summary: "Tried to set a value of type %{value_class} to a field of type %{field_class}"
355
- resolution: "Verify if the value to be set correspond to field definition"
356
409
  mixed_relations:
357
410
  message: "Referencing a(n) %{embedded} document from the %{root}
358
411
  document via a non-embedded association is not allowed since the
@@ -409,19 +462,18 @@ en:
409
462
  summary: "Mongoid attempted to find a document of the class %{klass}
410
463
  but none exist."
411
464
  resolution: "Create a document of class %{klass} or use a finder
412
- method that returns nil when no documents are found instead of
413
- raising an exception."
465
+ method that does not raise an exception when no documents are
466
+ found."
414
467
  no_environment:
415
468
  message: "Could not load the configuration since no environment
416
469
  was defined."
417
- summary: "Mongoid attempted to find the appropriate environment
418
- but no Rails.env, Sinatra::Base.environment, RACK_ENV, or
419
- MONGOID_ENV could be found."
420
- resolution: "Make sure some environment is set from the mentioned
421
- options. Mongoid cannot load configuration from the yaml without
422
- knowing which environment it is in, and we have considered
423
- defaulting to development an undesirable side effect of this not
424
- being defined."
470
+ summary: "Mongoid could not determine the environment to use because
471
+ it was not specified in any of the following locations:
472
+ Rails.env, Sinatra::Base.environment,
473
+ ENV[\"RACK_ENV\"], ENV[\"MONGOID_ENV\"]. Without knowing the
474
+ environment, Mongoid cannot load its configuration."
475
+ resolution: "Please ensure an environment is set in one of the
476
+ listed locations. The environment must be explicitly set."
425
477
  no_map_reduce_output:
426
478
  message: "No output location was specified for the map/reduce
427
479
  operation."
@@ -526,9 +578,8 @@ en:
526
578
  resolution: "Don't define '%{name}' as readonly, or do not attempt
527
579
  to update its value after the document is persisted."
528
580
  readonly_document:
529
- message: "Attempted to persist the readonly document '%{klass}'."
530
- summary: "Documents loaded from the database using #only
531
- cannot be persisted."
581
+ message: "Attempted to persist a readonly document of class '%{klass}'."
582
+ summary: "Documents that are marked readonly cannot be persisted."
532
583
  resolution: "Don't attempt to persist documents that are flagged as
533
584
  readonly."
534
585
  scope_overwrite:
@@ -548,11 +599,9 @@ en:
548
599
  server versions 3.6 and higher."
549
600
  resolution: "Verify that all servers in your deployment are at least
550
601
  version 3.6 or don't attempt to use sessions with older server versions."
551
- taken:
552
- "is already taken"
553
602
  too_many_nested_attribute_records:
554
603
  message: "Accepting nested attributes for %{association} is limited
555
- to %{limit} records."
604
+ to %{limit} documents."
556
605
  summary: "More documents were sent to be processed than the allowed
557
606
  limit."
558
607
  resolution: "The limit is set as an option to the macro, for example:
@@ -15,8 +15,8 @@ module Mongoid
15
15
  # @example Build the association.
16
16
  # person.__build__(:addresses, { :_id => 1 }, association)
17
17
  #
18
- # @param [ String, Symbol ] name The name of the association.
19
- # @param [ Hash, BSON::ObjectId ] object The id or attributes to use.
18
+ # @param [ String | Symbol ] name The name of the association.
19
+ # @param [ Hash | BSON::ObjectId ] object The id or attributes to use.
20
20
  # @param [ Association ] association The association metadata.
21
21
  # @param [ Hash ] selected_fields Fields which were retrieved via #only.
22
22
  # If selected_fields is specified, fields not listed in it will not be
@@ -33,7 +33,7 @@ module Mongoid
33
33
  # @example Create the association.
34
34
  # person.create_relation(document, association)
35
35
  #
36
- # @param [ Document, Array<Document> ] object The association target.
36
+ # @param [ Document | Array<Document> ] object The association target.
37
37
  # @param [ Association ] association The association metadata.
38
38
  # @param [ Hash ] selected_fields Fields which were retrieved via #only.
39
39
  # If selected_fields is specified, fields not listed in it will not be
@@ -42,8 +42,23 @@ module Mongoid
42
42
  # @return [ Proxy ] The association.
43
43
  def create_relation(object, association, selected_fields = nil)
44
44
  type = @attributes[association.inverse_type]
45
- target = association.build(self, object, type, selected_fields)
46
- target ? association.create_relation(self, target) : nil
45
+ target = if t = association.build(self, object, type, selected_fields)
46
+ association.create_relation(self, t)
47
+ else
48
+ nil
49
+ end
50
+
51
+ # Only need to do this on embedded associations. The pending callbacks
52
+ # are only added when materializing the documents, which only happens
53
+ # on embedded associations. There is no call to the database in the
54
+ # construction of a referenced association.
55
+ if association.embedded?
56
+ Array(target).each do |doc|
57
+ doc.try(:run_pending_callbacks)
58
+ end
59
+ end
60
+
61
+ target
47
62
  end
48
63
 
49
64
  # Resets the criteria inside the association proxy. Used by many-to-many
@@ -65,7 +80,7 @@ module Mongoid
65
80
  # @example Set the proxy on the document.
66
81
  # person.set(:addresses, addresses)
67
82
  #
68
- # @param [ String, Symbol ] name The name of the association.
83
+ # @param [ String | Symbol ] name The name of the association.
69
84
  # @param [ Proxy ] relation The association to set.
70
85
  #
71
86
  # @return [ Proxy ] The association.
@@ -86,10 +101,23 @@ module Mongoid
86
101
  # @param [ Symbol ] name The name of the association.
87
102
  # @param [ Association ] association The association metadata.
88
103
  # @param [ Object ] object The object used to build the association.
89
- # @param [ true, false ] reload If the association is to be reloaded.
104
+ # @param [ true | false ] reload If the association is to be reloaded.
90
105
  #
91
106
  # @return [ Proxy ] The association.
92
107
  def get_relation(name, association, object, reload = false)
108
+ field_name = database_field_name(name)
109
+
110
+ # As per the comments under MONGOID-5034, I've decided to only raise on
111
+ # embedded associations for a missing attribute. Rails does not raise
112
+ # for a missing attribute on referenced associations.
113
+ # We also don't want to raise if we're retrieving an association within
114
+ # the codebase. This is often done when retrieving the inverse association
115
+ # during binding or when cascading callbacks. Whenever we retrieve
116
+ # associations within the codebase, we use without_autobuild.
117
+ if !without_autobuild? && association.embedded? && attribute_missing?(field_name)
118
+ raise ActiveModel::MissingAttributeError, "Missing attribute: '#{field_name}'"
119
+ end
120
+
93
121
  if !reload && (value = ivar(name)) != false
94
122
  value
95
123
  else
@@ -178,7 +206,7 @@ module Mongoid
178
206
 
179
207
  # Positional projection is specified as "foo.$". In this case the
180
208
  # document that the $ is referring to should be retrieved with all
181
- # fields. See https://docs.mongodb.com/manual/reference/operator/projection/positional/
209
+ # fields. See https://www.mongodb.com/docs/manual/reference/operator/projection/positional/
182
210
  # and https://jira.mongodb.org/browse/MONGOID-4769.
183
211
  if filtered.keys == %w($)
184
212
  filtered = nil
@@ -197,7 +225,7 @@ module Mongoid
197
225
  # @example Is autobuild disabled?
198
226
  # document.without_autobuild?
199
227
  #
200
- # @return [ true, false ] If autobuild is disabled.
228
+ # @return [ true | false ] If autobuild is disabled.
201
229
  def without_autobuild?
202
230
  Threaded.executing?(:without_autobuild)
203
231
  end
@@ -223,7 +251,7 @@ module Mongoid
223
251
  # @example Parse the args.
224
252
  # doc.parse_args(:name => "Joe")
225
253
  #
226
- # @param [ Array ] args The arguments.
254
+ # @param [ Hash... ] *args The arguments.
227
255
  #
228
256
  # @return [ Array<Hash> ] The attributes and options.
229
257
  def parse_args(*args)
@@ -291,7 +319,7 @@ module Mongoid
291
319
  ids_method = "#{association.name.to_s.singularize}_ids"
292
320
  association.inverse_class.tap do |klass|
293
321
  klass.re_define_method(ids_method) do
294
- send(association.name).only(:_id).map(&:_id)
322
+ send(association.name).pluck(:_id)
295
323
  end
296
324
  end
297
325
  end
@@ -341,6 +369,7 @@ module Mongoid
341
369
  # @return [ Class ] The class being set up.
342
370
  def self.define_ids_setter!(association)
343
371
  ids_method = "#{association.name.to_s.singularize}_ids="
372
+ association.inverse_class.aliased_associations[ids_method.chop] = association.name.to_s
344
373
  association.inverse_class.tap do |klass|
345
374
  klass.re_define_method(ids_method) do |ids|
346
375
  send(association.setter, association.relation_class.find(ids.reject(&:blank?)))
@@ -15,7 +15,7 @@ module Mongoid
15
15
  # Binding.new(base, target, association)
16
16
  #
17
17
  # @param [ Document ] base The base of the binding.
18
- # @param [ Document, Array<Document> ] target The target of the binding.
18
+ # @param [ Document | Array<Document> ] target The target of the binding.
19
19
  # @param [ Association ] association The association metadata.
20
20
  def initialize(base, target, association)
21
21
  @_base, @_target, @_association = base, target, association
@@ -60,6 +60,53 @@ module Mongoid
60
60
  end
61
61
  end
62
62
 
63
+ # Remove the associated document from the inverse's association.
64
+ #
65
+ # @param [ Document ] doc The document to remove.
66
+ def remove_associated(doc)
67
+ if inverse = _association.inverse(doc)
68
+ if _association.many?
69
+ remove_associated_many(doc, inverse)
70
+ elsif _association.in_to?
71
+ remove_associated_in_to(doc, inverse)
72
+ end
73
+ end
74
+ end
75
+
76
+ # Remove the associated document from the inverse's association.
77
+ #
78
+ # This method removes the associated on *_many relationships.
79
+ #
80
+ # @param [ Document ] doc The document to remove.
81
+ # @param [ Symbol ] inverse The name of the inverse.
82
+ def remove_associated_many(doc, inverse)
83
+ # We only want to remove the inverse association when the inverse
84
+ # document is in memory.
85
+ if inv = doc.ivar(inverse)
86
+ # This first condition is needed because when assigning the
87
+ # embeds_many association using the same embeds_many
88
+ # association, we delete from the array we are about to assign.
89
+ if _base != inv && (associated = inv.ivar(_association.name))
90
+ associated.delete(doc)
91
+ end
92
+ end
93
+ end
94
+
95
+ # Remove the associated document from the inverse's association.
96
+ #
97
+ # This method removes associated on belongs_to and embedded_in
98
+ # associations.
99
+ #
100
+ # @param [ Document ] doc The document to remove.
101
+ # @param [ Symbol ] inverse The name of the inverse.
102
+ def remove_associated_in_to(doc, inverse)
103
+ # We only want to remove the inverse association when the inverse
104
+ # document is in memory.
105
+ if associated = doc.ivar(inverse)
106
+ associated.send(_association.setter, nil)
107
+ end
108
+ end
109
+
63
110
  # Set the id of the related document in the foreign key field on the
64
111
  # keyed document.
65
112
  #
@@ -134,6 +181,7 @@ module Mongoid
134
181
  # @param [ Document ] doc The document to bind.
135
182
  def bind_from_relational_parent(doc)
136
183
  check_inverse!(doc)
184
+ remove_associated(doc)
137
185
  bind_foreign_key(doc, record_id(_base))
138
186
  bind_polymorphic_type(doc, _base.class.name)
139
187
  bind_inverse(doc, _base)
@@ -152,7 +200,7 @@ module Mongoid
152
200
  # @example Set the base association.
153
201
  # binding.set_base_association
154
202
  #
155
- # @return [ true, false ] If the association changed.
203
+ # @return [ true | false ] If the association changed.
156
204
  def set_base_association
157
205
  inverse_association = _association.inverse_association(_target)
158
206
  if inverse_association != _association && !inverse_association.nil?
@@ -27,7 +27,7 @@ module Mongoid
27
27
  # @example Parse the args.
28
28
  # doc.parse_args(:name => "Joe")
29
29
  #
30
- # @param [ Array ] args The arguments.
30
+ # @param [ Hash... ] *args The arguments.
31
31
  #
32
32
  # @return [ Array<Hash> ] The attributes and options.
33
33
  def parse_args(*args)
@@ -46,9 +46,10 @@ module Mongoid
46
46
  association.inverse_class.tap do |klass|
47
47
  klass.re_define_method("build_#{association.name}") do |*args|
48
48
  attributes, _options = parse_args(*args)
49
- document = Factory.build(association.relation_class, attributes)
49
+ document = Factory.execute_build(association.relation_class, attributes, execute_callbacks: false)
50
50
  _building do
51
51
  child = send("#{association.name}=", document)
52
+ child.run_pending_callbacks
52
53
  child.run_callbacks(:build)
53
54
  child
54
55
  end
@@ -69,10 +70,11 @@ module Mongoid
69
70
  association.inverse_class.tap do |klass|
70
71
  klass.re_define_method("create_#{association.name}") do |*args|
71
72
  attributes, _options = parse_args(*args)
72
- document = Factory.build(association.relation_class, attributes)
73
+ document = Factory.execute_build(association.relation_class, attributes, execute_callbacks: false)
73
74
  doc = _assigning do
74
75
  send("#{association.name}=", document)
75
76
  end
77
+ doc.run_pending_callbacks
76
78
  doc.save
77
79
  save if new_record? && association.stores_foreign_key?
78
80
  doc
@@ -5,7 +5,6 @@ module Mongoid
5
5
 
6
6
  # Used for converting foreign key values to the correct type based on the
7
7
  # types of ids that the document stores.
8
- #
9
8
  module Constrainable
10
9
 
11
10
  # Convert the supplied object to the appropriate type to set as the
@@ -20,13 +20,35 @@ module Mongoid
20
20
  end
21
21
  end
22
22
 
23
- def preload(relations, docs)
24
- relations.group_by(&:inverse_class_name)
25
- .values
26
- .each do |associations|
27
- associations.group_by(&:relation)
28
- .each do |relation, association|
29
- relation.eager_loader(association, docs).run
23
+ # Load the associations for the given documents. This will be done
24
+ # recursively to load the associations of the given documents'
25
+ # subdocuments.
26
+ #
27
+ # @param [ Array<Association> ] associations The associations to load.
28
+ # @param [ Array<Document> ] document The documents.
29
+ def preload(associations, docs)
30
+ assoc_map = associations.group_by(&:inverse_class_name)
31
+ docs_map = {}
32
+ queue = [ klass.to_s ]
33
+
34
+ while klass = queue.shift
35
+ if as = assoc_map.delete(klass)
36
+ as.each do |assoc|
37
+ queue << assoc.class_name
38
+
39
+ # If this class is nested in the inclusion tree, only load documents
40
+ # for the association above it. If there is no parent association,
41
+ # we will include documents from the documents passed to this method.
42
+ ds = docs
43
+ if assoc.parent_inclusions.length > 0
44
+ ds = assoc.parent_inclusions.map{ |p| docs_map[p].to_a }.flatten
45
+ end
46
+
47
+ res = assoc.relation.eager_loader([assoc], ds).run
48
+
49
+ docs_map[assoc.name] ||= [].to_set
50
+ docs_map[assoc.name].merge(res)
51
+ end
30
52
  end
31
53
  end
32
54
  end