mongoid 6.4.2 → 7.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (318) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/config/locales/en.yml +17 -0
  4. data/lib/mongoid/association/accessors.rb +339 -0
  5. data/lib/mongoid/{relations/binding.rb → association/bindable.rb} +32 -52
  6. data/lib/mongoid/association/builders.rb +92 -0
  7. data/lib/mongoid/{relations/constraint.rb → association/constrainable.rb} +11 -22
  8. data/lib/mongoid/association/depending.rb +137 -0
  9. data/lib/mongoid/{relations/eager.rb → association/eager_loadable.rb} +11 -11
  10. data/lib/mongoid/{relations → association}/embedded/batchable.rb +19 -19
  11. data/lib/mongoid/association/embedded/cyclic.rb +109 -0
  12. data/lib/mongoid/association/embedded/embedded_in/binding.rb +56 -0
  13. data/lib/mongoid/{relations/builders/embedded/in.rb → association/embedded/embedded_in/buildable.rb} +12 -6
  14. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +121 -0
  15. data/lib/mongoid/association/embedded/embedded_in.rb +154 -0
  16. data/lib/mongoid/{relations/bindings/embedded/many.rb → association/embedded/embeds_many/binding.rb} +11 -9
  17. data/lib/mongoid/{relations/builders/embedded/many.rb → association/embedded/embeds_many/buildable.rb} +13 -7
  18. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +552 -0
  19. data/lib/mongoid/association/embedded/embeds_many.rb +210 -0
  20. data/lib/mongoid/{relations/bindings/embedded/one.rb → association/embedded/embeds_one/binding.rb} +12 -10
  21. data/lib/mongoid/{relations/builders/embedded/one.rb → association/embedded/embeds_one/buildable.rb} +13 -7
  22. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +130 -0
  23. data/lib/mongoid/association/embedded/embeds_one.rb +173 -0
  24. data/lib/mongoid/association/embedded.rb +4 -0
  25. data/lib/mongoid/association/macros.rb +204 -0
  26. data/lib/mongoid/{relations → association}/many.rb +19 -49
  27. data/lib/mongoid/{relations → association}/marshalable.rb +6 -4
  28. data/lib/mongoid/association/nested/many.rb +200 -0
  29. data/lib/mongoid/association/nested/nested_buildable.rb +72 -0
  30. data/lib/mongoid/association/nested/one.rb +127 -0
  31. data/lib/mongoid/association/nested.rb +15 -0
  32. data/lib/mongoid/{relations → association}/one.rb +6 -6
  33. data/lib/mongoid/association/options.rb +152 -0
  34. data/lib/mongoid/{relations → association}/proxy.rb +31 -58
  35. data/lib/mongoid/association/referenced/auto_save.rb +79 -0
  36. data/lib/mongoid/association/referenced/belongs_to/binding.rb +87 -0
  37. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +46 -0
  38. data/lib/mongoid/association/referenced/belongs_to/eager.rb +36 -0
  39. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +136 -0
  40. data/lib/mongoid/association/referenced/belongs_to.rb +248 -0
  41. data/lib/mongoid/association/referenced/counter_cache.rb +163 -0
  42. data/lib/mongoid/association/referenced/eager.rb +162 -0
  43. data/lib/mongoid/association/referenced/has_and_belongs_to_many/binding.rb +71 -0
  44. data/lib/mongoid/association/referenced/has_and_belongs_to_many/buildable.rb +40 -0
  45. data/lib/mongoid/association/referenced/has_and_belongs_to_many/eager.rb +52 -0
  46. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +312 -0
  47. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +290 -0
  48. data/lib/mongoid/{relations/bindings/referenced/many.rb → association/referenced/has_many/binding.rb} +6 -5
  49. data/lib/mongoid/association/referenced/has_many/buildable.rb +38 -0
  50. data/lib/mongoid/association/referenced/has_many/eager.rb +43 -0
  51. data/lib/mongoid/association/referenced/has_many/enumerable.rb +510 -0
  52. data/lib/mongoid/association/referenced/has_many/proxy.rb +578 -0
  53. data/lib/mongoid/association/referenced/has_many.rb +275 -0
  54. data/lib/mongoid/{relations/bindings/referenced/one.rb → association/referenced/has_one/binding.rb} +11 -8
  55. data/lib/mongoid/association/referenced/has_one/buildable.rb +60 -0
  56. data/lib/mongoid/association/referenced/has_one/eager.rb +35 -0
  57. data/lib/mongoid/{relations/builders/nested_attributes/one.rb → association/referenced/has_one/nested_builder.rb} +9 -9
  58. data/lib/mongoid/association/referenced/has_one/proxy.rb +113 -0
  59. data/lib/mongoid/association/referenced/has_one.rb +204 -0
  60. data/lib/mongoid/association/referenced/syncable.rb +170 -0
  61. data/lib/mongoid/association/referenced.rb +7 -0
  62. data/lib/mongoid/{relations → association}/reflections.rb +21 -17
  63. data/lib/mongoid/association/relatable.rb +509 -0
  64. data/lib/mongoid/{relations.rb → association.rb} +57 -56
  65. data/lib/mongoid/atomic/paths/embedded/many.rb +1 -1
  66. data/lib/mongoid/atomic/paths/embedded/one.rb +1 -1
  67. data/lib/mongoid/atomic.rb +4 -4
  68. data/lib/mongoid/attributes/dynamic.rb +2 -2
  69. data/lib/mongoid/attributes/nested.rb +22 -11
  70. data/lib/mongoid/attributes/processing.rb +2 -2
  71. data/lib/mongoid/attributes/readonly.rb +2 -4
  72. data/lib/mongoid/attributes.rb +22 -13
  73. data/lib/mongoid/changeable.rb +1 -1
  74. data/lib/mongoid/clients/options.rb +7 -5
  75. data/lib/mongoid/composable.rb +4 -4
  76. data/lib/mongoid/config.rb +1 -0
  77. data/lib/mongoid/contextual/atomic.rb +1 -1
  78. data/lib/mongoid/contextual/geo_near.rb +1 -1
  79. data/lib/mongoid/contextual/memory.rb +21 -3
  80. data/lib/mongoid/contextual/mongo.rb +10 -8
  81. data/lib/mongoid/copyable.rb +7 -6
  82. data/lib/mongoid/criteria/includable.rb +14 -14
  83. data/lib/mongoid/criteria/modifiable.rb +8 -14
  84. data/lib/mongoid/criteria/options.rb +2 -2
  85. data/lib/mongoid/criteria/queryable/extensions/string.rb +1 -1
  86. data/lib/mongoid/criteria/queryable/pipeline.rb +10 -5
  87. data/lib/mongoid/criteria/queryable/selectable.rb +37 -7
  88. data/lib/mongoid/criteria.rb +2 -2
  89. data/lib/mongoid/document.rb +15 -6
  90. data/lib/mongoid/errors/invalid_dependent_strategy.rb +32 -0
  91. data/lib/mongoid/errors/invalid_relation_option.rb +29 -0
  92. data/lib/mongoid/errors/unknown_model.rb +25 -0
  93. data/lib/mongoid/errors.rb +3 -0
  94. data/lib/mongoid/extensions/array.rb +5 -5
  95. data/lib/mongoid/extensions/big_decimal.rb +1 -1
  96. data/lib/mongoid/extensions/hash.rb +5 -2
  97. data/lib/mongoid/extensions/object.rb +4 -4
  98. data/lib/mongoid/extensions/range.rb +1 -0
  99. data/lib/mongoid/extensions/regexp.rb +1 -0
  100. data/lib/mongoid/extensions.rb +0 -4
  101. data/lib/mongoid/factory.rb +13 -3
  102. data/lib/mongoid/fields/foreign_key.rb +5 -5
  103. data/lib/mongoid/fields/standard.rb +2 -14
  104. data/lib/mongoid/fields/validators/macro.rb +1 -1
  105. data/lib/mongoid/fields.rb +3 -3
  106. data/lib/mongoid/indexable.rb +4 -1
  107. data/lib/mongoid/interceptable.rb +5 -5
  108. data/lib/mongoid/matchable/and.rb +1 -1
  109. data/lib/mongoid/matchable/elem_match.rb +9 -3
  110. data/lib/mongoid/matchable/eq.rb +22 -0
  111. data/lib/mongoid/matchable/ne.rb +1 -1
  112. data/lib/mongoid/matchable.rb +3 -1
  113. data/lib/mongoid/persistable/deletable.rb +7 -6
  114. data/lib/mongoid/persistable/incrementable.rb +1 -1
  115. data/lib/mongoid/persistable/logical.rb +1 -1
  116. data/lib/mongoid/persistable/settable.rb +57 -12
  117. data/lib/mongoid/persistable.rb +4 -5
  118. data/lib/mongoid/persistence_context.rb +20 -5
  119. data/lib/mongoid/query_cache.rb +8 -4
  120. data/lib/mongoid/railtie.rb +17 -0
  121. data/lib/mongoid/railties/controller_runtime.rb +86 -0
  122. data/lib/mongoid/scopable.rb +3 -3
  123. data/lib/mongoid/serializable.rb +4 -4
  124. data/lib/mongoid/shardable.rb +1 -1
  125. data/lib/mongoid/threaded.rb +36 -0
  126. data/lib/mongoid/touchable.rb +102 -0
  127. data/lib/mongoid/traversable.rb +3 -3
  128. data/lib/mongoid/validatable/presence.rb +2 -2
  129. data/lib/mongoid/validatable/uniqueness.rb +4 -4
  130. data/lib/mongoid/validatable.rb +8 -8
  131. data/lib/mongoid/version.rb +1 -1
  132. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +3 -0
  133. data/spec/app/models/animal.rb +2 -1
  134. data/spec/app/models/bomb.rb +1 -1
  135. data/spec/app/models/message.rb +1 -1
  136. data/spec/app/models/minim.rb +7 -0
  137. data/spec/app/models/person.rb +5 -2
  138. data/spec/app/models/shipment_address.rb +1 -0
  139. data/spec/app/models/store_as_dup_test3.rb +7 -0
  140. data/spec/app/models/store_as_dup_test4.rb +7 -0
  141. data/spec/app/models/updatable.rb +7 -0
  142. data/spec/app/models/vertex.rb +6 -0
  143. data/spec/app/models/wiki_page.rb +1 -1
  144. data/spec/config/mongoid.yml +13 -3
  145. data/spec/integration/associations/belongs_to_spec.rb +13 -0
  146. data/spec/lite_spec_helper.rb +56 -0
  147. data/spec/mongoid/{relations → association}/accessors_spec.rb +40 -1
  148. data/spec/mongoid/{relations → association}/auto_save_spec.rb +60 -12
  149. data/spec/mongoid/{relations → association}/builders_spec.rb +1 -1
  150. data/spec/mongoid/association/constrainable_spec.rb +115 -0
  151. data/spec/mongoid/{relations → association}/counter_cache_spec.rb +1 -1
  152. data/spec/mongoid/association/depending_spec.rb +866 -0
  153. data/spec/mongoid/{relations → association}/eager_spec.rb +12 -12
  154. data/spec/mongoid/{relations → association/embedded}/cyclic_spec.rb +1 -1
  155. data/spec/mongoid/{relations/bindings/embedded/in_spec.rb → association/embedded/embedded_in/binding_spec.rb} +13 -13
  156. data/spec/mongoid/{relations/builders/embedded/in_spec.rb → association/embedded/embedded_in/buildable_spec.rb} +9 -9
  157. data/spec/mongoid/{relations/embedded/in_spec.rb → association/embedded/embedded_in/proxy_spec.rb} +5 -77
  158. data/spec/mongoid/association/embedded/embedded_in_spec.rb +843 -0
  159. data/spec/mongoid/{relations/bindings/embedded/many_spec.rb → association/embedded/embeds_many/binding_spec.rb} +3 -3
  160. data/spec/mongoid/{relations/builders/embedded/many_spec.rb → association/embedded/embeds_many/buildable_spec.rb} +17 -45
  161. data/spec/mongoid/{relations/embedded/many_spec.rb → association/embedded/embeds_many/proxy_spec.rb} +124 -182
  162. data/spec/mongoid/association/embedded/embeds_many_spec.rb +852 -0
  163. data/spec/mongoid/{relations/bindings/embedded/one_spec.rb → association/embedded/embeds_one/binding_spec.rb} +4 -4
  164. data/spec/mongoid/{relations/builders/embedded/one_spec.rb → association/embedded/embeds_one/buildable_spec.rb} +14 -34
  165. data/spec/mongoid/{relations/embedded/one_spec.rb → association/embedded/embeds_one/proxy_spec.rb} +39 -84
  166. data/spec/mongoid/association/embedded/embeds_one_spec.rb +908 -0
  167. data/spec/mongoid/{relations → association}/macros_spec.rb +148 -73
  168. data/spec/mongoid/{relations/builders/nested_attributes → association/nested}/many_spec.rb +16 -19
  169. data/spec/mongoid/{relations/builders/nested_attributes → association/nested}/one_spec.rb +17 -20
  170. data/spec/mongoid/association/options_spec.rb +1321 -0
  171. data/spec/mongoid/{relations → association}/polymorphic_spec.rb +66 -34
  172. data/spec/mongoid/{relations/bindings/referenced/in_spec.rb → association/referenced/belongs_to/binding_spec.rb} +7 -7
  173. data/spec/mongoid/{relations/builders/referenced/in_spec.rb → association/referenced/belongs_to/buildable_spec.rb} +46 -79
  174. data/spec/mongoid/{relations/eager/belongs_to_spec.rb → association/referenced/belongs_to/eager_spec.rb} +33 -14
  175. data/spec/mongoid/{relations/referenced/in_spec.rb → association/referenced/belongs_to/proxy_spec.rb} +57 -91
  176. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2006 -0
  177. data/spec/mongoid/{relations/bindings/referenced/many_to_many_spec.rb → association/referenced/has_and_belongs_to_many/binding_spec.rb} +5 -5
  178. data/spec/mongoid/association/referenced/has_and_belongs_to_many/buildable_spec.rb +121 -0
  179. data/spec/mongoid/{relations/eager/has_and_belongs_to_many_spec.rb → association/referenced/has_and_belongs_to_many/eager_spec.rb} +26 -7
  180. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_persistence_spec.rb +56 -0
  181. data/spec/mongoid/{relations/referenced/many_to_many_spec.rb → association/referenced/has_and_belongs_to_many/proxy_spec.rb} +107 -98
  182. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +26 -0
  183. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +1027 -0
  184. data/spec/mongoid/{relations/bindings/referenced/many_spec.rb → association/referenced/has_many/binding_spec.rb} +5 -5
  185. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +119 -0
  186. data/spec/mongoid/{relations/eager/has_many_spec.rb → association/referenced/has_many/eager_spec.rb} +26 -11
  187. data/spec/mongoid/{relations/targets → association/referenced/has_many}/enumerable_spec.rb +122 -1
  188. data/spec/mongoid/association/referenced/has_many/proxy_query_spec.rb +23 -0
  189. data/spec/mongoid/{relations/referenced/many_spec.rb → association/referenced/has_many/proxy_spec.rb} +28 -93
  190. data/spec/mongoid/association/referenced/has_many_models.rb +37 -0
  191. data/spec/mongoid/association/referenced/has_many_spec.rb +1225 -0
  192. data/spec/mongoid/{relations/bindings/referenced/one_spec.rb → association/referenced/has_one/binding_spec.rb} +4 -4
  193. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +113 -0
  194. data/spec/mongoid/{relations/eager/has_one_spec.rb → association/referenced/has_one/eager_spec.rb} +10 -10
  195. data/spec/mongoid/{relations/referenced/one_spec.rb → association/referenced/has_one/proxy_spec.rb} +9 -109
  196. data/spec/mongoid/association/referenced/has_one_models.rb +48 -0
  197. data/spec/mongoid/association/referenced/has_one_spec.rb +1350 -0
  198. data/spec/mongoid/{relations → association}/reflections_spec.rb +1 -12
  199. data/spec/mongoid/{relations/synchronization_spec.rb → association/syncable_spec.rb} +4 -2
  200. data/spec/mongoid/{relations_spec.rb → association_spec.rb} +1 -1
  201. data/spec/mongoid/atomic/modifiers_spec.rb +2 -2
  202. data/spec/mongoid/atomic_spec.rb +4 -4
  203. data/spec/mongoid/attributes/nested_spec.rb +29 -11
  204. data/spec/mongoid/attributes/readonly_spec.rb +80 -125
  205. data/spec/mongoid/attributes_spec.rb +38 -2
  206. data/spec/mongoid/clients/factory_spec.rb +24 -18
  207. data/spec/mongoid/clients/options_spec.rb +58 -44
  208. data/spec/mongoid/clients/sessions_spec.rb +1 -1
  209. data/spec/mongoid/clients/transactions_spec.rb +369 -0
  210. data/spec/mongoid/clients_spec.rb +68 -8
  211. data/spec/mongoid/config_spec.rb +27 -1
  212. data/spec/mongoid/contextual/memory_spec.rb +19 -0
  213. data/spec/mongoid/contextual/mongo_spec.rb +33 -5
  214. data/spec/mongoid/copyable_spec.rb +90 -6
  215. data/spec/mongoid/copyable_spec_models.rb +17 -0
  216. data/spec/mongoid/criteria/modifiable_spec.rb +183 -60
  217. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +3 -3
  218. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +43 -0
  219. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +12 -0
  220. data/spec/mongoid/criteria/queryable/selectable_spec.rb +42 -3
  221. data/spec/mongoid/criteria/queryable/selector_spec.rb +2 -2
  222. data/spec/mongoid/criteria/scopable_spec.rb +81 -0
  223. data/spec/mongoid/criteria_spec.rb +33 -18
  224. data/spec/mongoid/document_spec.rb +83 -4
  225. data/spec/mongoid/extensions/array_spec.rb +11 -15
  226. data/spec/mongoid/extensions/big_decimal_spec.rb +9 -9
  227. data/spec/mongoid/extensions/hash_spec.rb +18 -1
  228. data/spec/mongoid/extensions/object_spec.rb +7 -11
  229. data/spec/mongoid/extensions/range_spec.rb +7 -0
  230. data/spec/mongoid/extensions/regexp_spec.rb +23 -0
  231. data/spec/mongoid/factory_spec.rb +19 -1
  232. data/spec/mongoid/fields/foreign_key_spec.rb +24 -32
  233. data/spec/mongoid/fields_spec.rb +2 -2
  234. data/spec/mongoid/findable_spec.rb +1 -1
  235. data/spec/mongoid/indexable_spec.rb +18 -8
  236. data/spec/mongoid/interceptable_spec.rb +22 -1
  237. data/spec/mongoid/matchable/elem_match_spec.rb +20 -0
  238. data/spec/mongoid/matchable/eq_spec.rb +48 -0
  239. data/spec/mongoid/persistable/incrementable_spec.rb +6 -6
  240. data/spec/mongoid/persistable/savable_spec.rb +2 -2
  241. data/spec/mongoid/persistable/settable_spec.rb +95 -10
  242. data/spec/mongoid/persistable_spec.rb +21 -6
  243. data/spec/mongoid/persistence_context_spec.rb +1 -1
  244. data/spec/mongoid/query_cache_spec.rb +61 -22
  245. data/spec/mongoid/relations/proxy_spec.rb +124 -124
  246. data/spec/mongoid/scopable_spec.rb +13 -0
  247. data/spec/mongoid/shardable_spec.rb +32 -12
  248. data/spec/mongoid/threaded_spec.rb +68 -0
  249. data/spec/mongoid/{relations/touchable_spec.rb → touchable_spec.rb} +40 -1
  250. data/spec/mongoid/validatable/associated_spec.rb +1 -1
  251. data/spec/mongoid/validatable/presence_spec.rb +7 -6
  252. data/spec/mongoid/validatable_spec.rb +1 -1
  253. data/spec/rails/controller_extension/controller_runtime_spec.rb +110 -0
  254. data/spec/spec_helper.rb +51 -25
  255. data/spec/support/constraints.rb +101 -0
  256. data/spec/support/macros.rb +20 -0
  257. data/spec/support/spec_config.rb +39 -0
  258. metadata +602 -582
  259. checksums.yaml.gz.sig +0 -2
  260. data/lib/mongoid/relations/accessors.rb +0 -267
  261. data/lib/mongoid/relations/auto_save.rb +0 -94
  262. data/lib/mongoid/relations/bindings/embedded/in.rb +0 -59
  263. data/lib/mongoid/relations/bindings/referenced/in.rb +0 -65
  264. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +0 -70
  265. data/lib/mongoid/relations/bindings.rb +0 -9
  266. data/lib/mongoid/relations/builder.rb +0 -57
  267. data/lib/mongoid/relations/builders/nested_attributes/many.rb +0 -199
  268. data/lib/mongoid/relations/builders/referenced/in.rb +0 -26
  269. data/lib/mongoid/relations/builders/referenced/many.rb +0 -26
  270. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +0 -39
  271. data/lib/mongoid/relations/builders/referenced/one.rb +0 -26
  272. data/lib/mongoid/relations/builders.rb +0 -106
  273. data/lib/mongoid/relations/cascading/delete.rb +0 -44
  274. data/lib/mongoid/relations/cascading/destroy.rb +0 -43
  275. data/lib/mongoid/relations/cascading/nullify.rb +0 -35
  276. data/lib/mongoid/relations/cascading/restrict.rb +0 -39
  277. data/lib/mongoid/relations/cascading.rb +0 -56
  278. data/lib/mongoid/relations/conversions.rb +0 -34
  279. data/lib/mongoid/relations/counter_cache.rb +0 -160
  280. data/lib/mongoid/relations/cyclic.rb +0 -107
  281. data/lib/mongoid/relations/eager/base.rb +0 -153
  282. data/lib/mongoid/relations/eager/belongs_to.rb +0 -31
  283. data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +0 -47
  284. data/lib/mongoid/relations/eager/has_many.rb +0 -38
  285. data/lib/mongoid/relations/eager/has_one.rb +0 -30
  286. data/lib/mongoid/relations/embedded/in.rb +0 -241
  287. data/lib/mongoid/relations/embedded/many.rb +0 -683
  288. data/lib/mongoid/relations/embedded/one.rb +0 -235
  289. data/lib/mongoid/relations/macros.rb +0 -367
  290. data/lib/mongoid/relations/metadata.rb +0 -1179
  291. data/lib/mongoid/relations/nested_builder.rb +0 -74
  292. data/lib/mongoid/relations/options.rb +0 -49
  293. data/lib/mongoid/relations/polymorphic.rb +0 -39
  294. data/lib/mongoid/relations/referenced/in.rb +0 -304
  295. data/lib/mongoid/relations/referenced/many.rb +0 -812
  296. data/lib/mongoid/relations/referenced/many_to_many.rb +0 -479
  297. data/lib/mongoid/relations/referenced/one.rb +0 -290
  298. data/lib/mongoid/relations/synchronization.rb +0 -169
  299. data/lib/mongoid/relations/targets/enumerable.rb +0 -493
  300. data/lib/mongoid/relations/targets.rb +0 -2
  301. data/lib/mongoid/relations/touchable.rb +0 -97
  302. data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +0 -184
  303. data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +0 -201
  304. data/spec/mongoid/relations/builders/referenced/many_spec.rb +0 -137
  305. data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +0 -178
  306. data/spec/mongoid/relations/builders/referenced/one_spec.rb +0 -111
  307. data/spec/mongoid/relations/cascading/delete_spec.rb +0 -101
  308. data/spec/mongoid/relations/cascading/destroy_spec.rb +0 -47
  309. data/spec/mongoid/relations/cascading/nullify_spec.rb +0 -32
  310. data/spec/mongoid/relations/cascading/restrict_spec.rb +0 -68
  311. data/spec/mongoid/relations/cascading_spec.rb +0 -355
  312. data/spec/mongoid/relations/constraint_spec.rb +0 -75
  313. data/spec/mongoid/relations/conversions_spec.rb +0 -128
  314. data/spec/mongoid/relations/metadata_spec.rb +0 -1985
  315. data/spec/mongoid/relations/options_spec.rb +0 -35
  316. data.tar.gz.sig +0 -0
  317. metadata.gz.sig +0 -0
  318. /data/spec/mongoid/{relations → association}/embedded/dirty_spec.rb +0 -0
@@ -2,6 +2,7 @@
2
2
  require "mongoid/matchable/default"
3
3
  require "mongoid/matchable/all"
4
4
  require "mongoid/matchable/and"
5
+ require "mongoid/matchable/eq"
5
6
  require "mongoid/matchable/exists"
6
7
  require "mongoid/matchable/gt"
7
8
  require "mongoid/matchable/gte"
@@ -32,6 +33,7 @@ module Mongoid
32
33
  "$all" => All,
33
34
  "$elemMatch" => ElemMatch,
34
35
  "$and" => And,
36
+ "$eq" => Eq,
35
37
  "$exists" => Exists,
36
38
  "$gt" => Gt,
37
39
  "$gte" => Gte,
@@ -42,7 +44,7 @@ module Mongoid
42
44
  "$nin" => Nin,
43
45
  "$or" => Or,
44
46
  "$nor" => Nor,
45
- "$size" => Size
47
+ "$size" => Size,
46
48
  }.with_indifferent_access.freeze
47
49
 
48
50
  # Determines if this document has the attributes to match the supplied
@@ -21,10 +21,12 @@ module Mongoid
21
21
  def delete(options = {})
22
22
  raise Errors::ReadonlyDocument.new(self.class) if readonly?
23
23
  prepare_delete do
24
- if embedded?
25
- delete_as_embedded(options)
26
- else
27
- delete_as_root
24
+ unless options[:persist] == false
25
+ if embedded?
26
+ delete_as_embedded(options)
27
+ else
28
+ delete_as_root
29
+ end
28
30
  end
29
31
  end
30
32
  end
@@ -113,11 +115,10 @@ module Mongoid
113
115
  #
114
116
  # @since 4.0.0
115
117
  def prepare_delete
116
- cascade!
118
+ return false unless catch(:abort) { apply_delete_dependencies! }
117
119
  yield(self)
118
120
  freeze
119
121
  self.destroyed = true
120
- true
121
122
  end
122
123
 
123
124
  module ClassMethods
@@ -28,7 +28,7 @@ module Mongoid
28
28
  attributes[field] = (current || 0) + increment
29
29
  ops[atomic_attribute_name(field)] = increment
30
30
  end
31
- { "$inc" => ops }
31
+ { "$inc" => ops } unless ops.empty?
32
32
  end
33
33
  end
34
34
  end
@@ -30,7 +30,7 @@ module Mongoid
30
30
  attributes[field] = value
31
31
  ops[atomic_attribute_name(field)] = values
32
32
  end
33
- { "$bit" => ops }
33
+ { "$bit" => ops } unless ops.empty?
34
34
  end
35
35
  end
36
36
  end
@@ -14,6 +14,34 @@ module Mongoid
14
14
  # @example Set the values.
15
15
  # document.set(title: "sir", dob: Date.new(1970, 1, 1))
16
16
  #
17
+ # The key can be a dotted sequence of keys, in which case the
18
+ # top level field is treated as a nested hash and any missing keys
19
+ # are created automatically:
20
+ #
21
+ # @example Set the values using nested hash semantics.
22
+ # document.set('author.title' => 'Sir')
23
+ # # => document.author == {'title' => 'Sir'}
24
+ #
25
+ # Performing a nested set like this merges values of intermediate keys:
26
+ #
27
+ # @example Nested hash value merging.
28
+ # document.set('author.title' => 'Sir')
29
+ # document.set('author.name' => 'Linus Torvalds')
30
+ # # => document.author == {'title' => 'Sir', 'name' => 'Linus Torvalds'}
31
+ #
32
+ # If the top level field was not a hash, its original value is discarded
33
+ # and the field is replaced with a hash.
34
+ #
35
+ # @example Nested hash overwriting a non-hash value.
36
+ # document.set('author' => 'John Doe')
37
+ # document.set('author.title' => 'Sir')
38
+ # # => document.author == {'title' => 'Sir'}
39
+ #
40
+ # Note that unlike MongoDB's $set, Mongoid's set writes out the entire
41
+ # field even when setting a subset of the field via the nested hash
42
+ # semantics. This means performing a $set with nested hash semantics
43
+ # can overwrite other hash keys within the top level field in the database.
44
+ #
17
45
  # @param [ Hash ] setters The field/value pairs to set.
18
46
  #
19
47
  # @return [ Document ] The document.
@@ -23,16 +51,38 @@ module Mongoid
23
51
  prepare_atomic_operation do |ops|
24
52
  process_atomic_operations(setters) do |field, value|
25
53
 
26
- field_and_value_hash = hasherizer(field.split('.'), value)
27
- field = field_and_value_hash.keys.first.to_s
28
- value = field_and_value_hash[field]
54
+ field_seq = field.to_s.split('.')
55
+ field = field_seq.shift
56
+ if field_seq.length > 0
57
+ # nested hash path
58
+ old_value = attributes[field]
59
+
60
+ # if the old value is not a hash, clobber it
61
+ unless Hash === old_value
62
+ old_value = {}
63
+ end
64
+
65
+ # descend into the hash, creating intermediate keys as needed
66
+ cur_value = old_value
67
+ while field_seq.length > 1
68
+ cur_key = field_seq.shift
69
+ # clobber on each level if type is not a hash
70
+ unless Hash === cur_value[cur_key]
71
+ cur_value[cur_key] = {}
72
+ end
73
+ cur_value = cur_value[cur_key]
74
+ end
29
75
 
30
- if fields[field] && fields[field].type == Hash && attributes.key?(field) && Hash === value && !value.empty?
31
- merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
32
- value = (attributes[field] || {}).merge(value, &merger)
76
+ # now we are on the leaf level, perform the set
77
+ # and overwrite whatever was on this level before
78
+ cur_value[field_seq.shift] = value
79
+
80
+ # and set value to the value of the top level field
81
+ # because this is what we pass to $set
82
+ value = old_value
33
83
  end
34
84
 
35
- process_attribute(field.to_s, value)
85
+ process_attribute(field, value)
36
86
 
37
87
  unless relations.include?(field.to_s)
38
88
  ops[atomic_attribute_name(field)] = attributes[field]
@@ -42,10 +92,5 @@ module Mongoid
42
92
  end
43
93
  end
44
94
  end
45
-
46
- def hasherizer(keys, value)
47
- return value if keys.empty?
48
- {}.tap { |hash| hash[keys.shift] = hasherizer(keys, value) }
49
- end
50
95
  end
51
96
  end
@@ -162,10 +162,9 @@ module Mongoid
162
162
  # @since 4.0.0
163
163
  def process_atomic_operations(operations)
164
164
  operations.each do |field, value|
165
- as_writable_attribute!(field, value) do |access|
166
- yield(access, value)
167
- remove_change(access)
168
- end
165
+ access = database_field_name(field)
166
+ yield(access, value)
167
+ remove_change(access)
169
168
  end
170
169
  end
171
170
 
@@ -202,7 +201,7 @@ module Mongoid
202
201
  #
203
202
  # @since 4.0.0
204
203
  def persist_atomic_operations(operations)
205
- if persisted? && operations
204
+ if persisted? && operations && !operations.empty?
206
205
  selector = atomic_selector
207
206
  _root.collection.find(selector).update_one(positionally(selector, operations), session: _session)
208
207
  end
@@ -169,6 +169,9 @@ module Mongoid
169
169
 
170
170
  # Set the persistence context for a particular class or model instance.
171
171
  #
172
+ # If there already is a persistence context set, options in the existing
173
+ # context are combined with options given to the set call.
174
+ #
172
175
  # @example Set the persistence context for a class or model instance.
173
176
  # PersistenceContext.set(model)
174
177
  #
@@ -180,9 +183,19 @@ module Mongoid
180
183
  #
181
184
  # @since 6.0.0
182
185
  def set(object, options_or_context)
183
- context = PersistenceContext.new(object, options_or_context.is_a?(PersistenceContext) ?
184
- options_or_context.options : options_or_context)
185
- Thread.current["[mongoid][#{object.object_id}]:context"] = context
186
+ key = "[mongoid][#{object.object_id}]:context"
187
+ existing_context = Thread.current[key]
188
+ existing_options = if existing_context
189
+ existing_context.options
190
+ else
191
+ {}
192
+ end
193
+ if options_or_context.is_a?(PersistenceContext)
194
+ options_or_context = options_or_context.options
195
+ end
196
+ new_options = existing_options.merge(options_or_context)
197
+ context = PersistenceContext.new(object, new_options)
198
+ Thread.current[key] = context
186
199
  end
187
200
 
188
201
  # Get the persistence context for a particular class or model instance.
@@ -206,14 +219,16 @@ module Mongoid
206
219
  #
207
220
  # @param [ Class, Object ] object The class or model instance.
208
221
  # @param [ Mongo::Cluster ] cluster The original cluster before this context was used.
222
+ # @param [ Mongoid::PersistenceContext ] original_context The original persistence
223
+ # context that was set before this context was used.
209
224
  #
210
225
  # @since 6.0.0
211
- def clear(object, cluster = nil)
226
+ def clear(object, cluster = nil, original_context = nil)
212
227
  if context = get(object)
213
228
  context.client.close unless (context.cluster.equal?(cluster) || cluster.nil?)
214
229
  end
215
230
  ensure
216
- Thread.current["[mongoid][#{object.object_id}]:context"] = nil
231
+ Thread.current["[mongoid][#{object.object_id}]:context"] = original_context
217
232
  end
218
233
  end
219
234
  end
@@ -138,7 +138,9 @@ module Mongoid
138
138
  # @since 5.0.0
139
139
  def each
140
140
  if @cached_documents
141
- @cached_documents.each{ |doc| yield doc }
141
+ @cached_documents.each do |doc|
142
+ yield doc
143
+ end
142
144
  else
143
145
  super
144
146
  end
@@ -163,7 +165,10 @@ module Mongoid
163
165
  @cursor_id = result.cursor_id
164
166
  @coll_name ||= result.namespace.sub("#{database.name}.", '') if result.namespace
165
167
  documents = result.documents
166
- (@cached_documents ||= []).concat(documents)
168
+ if @cursor_id.zero? && !@after_first_batch
169
+ (@cached_documents ||= []).concat(documents)
170
+ end
171
+ @after_first_batch = true
167
172
  documents
168
173
  end
169
174
  end
@@ -242,8 +247,7 @@ module Mongoid
242
247
  key = [ collection.namespace, selector, nil, skip, sort, projection, collation ]
243
248
  cursor = QueryCache.cache_table[key]
244
249
  if cursor
245
- limited_docs = cursor.to_a[0...limit.abs]
246
- cursor.instance_variable_set(:@cached_documents, limited_docs)
250
+ cursor.to_a[0...limit.abs]
247
251
  end
248
252
  end
249
253
  cursor || QueryCache.cache_table[cache_key]
@@ -102,6 +102,23 @@ module Rails
102
102
  puts "There is a configuration error with the current mongoid.yml."
103
103
  puts e.message
104
104
  end
105
+
106
+ # Include Controller extension that measures Mongoid runtime
107
+ # during request processing. The value then appears in Rails'
108
+ # instrumentation event `process_action.action_controller`.
109
+ #
110
+ # The measurement is made via internal Mongo monitoring subscription
111
+ initializer "mongoid.runtime-metric" do
112
+ require "mongoid/railties/controller_runtime"
113
+
114
+ ActiveSupport.on_load :action_controller do
115
+ include ::Mongoid::Railties::ControllerRuntime::ControllerExtension
116
+ end
117
+
118
+ Mongo::Monitoring::Global.subscribe Mongo::Monitoring::COMMAND,
119
+ ::Mongoid::Railties::ControllerRuntime::Collector.new
120
+ end
121
+
105
122
  end
106
123
  end
107
124
  end
@@ -0,0 +1,86 @@
1
+ module Mongoid
2
+ module Railties
3
+ module ControllerRuntime
4
+
5
+ # This extension mimics the Rails' internal method to
6
+ # measure ActiveRecord runtime during request processing.
7
+ # It appends MongoDB runtime value (`mongoid_runtime`) into payload
8
+ # of instrumentation event `process_action.action_controller`.
9
+ module ControllerExtension
10
+ extend ActiveSupport::Concern
11
+
12
+ protected
13
+
14
+ attr_internal :mongoid_runtime
15
+
16
+ # Reset the runtime before each action.
17
+ def process_action(action, *args)
18
+ Collector.reset_runtime
19
+ super
20
+ end
21
+
22
+ # Override to collect the measurements.
23
+ def cleanup_view_runtime
24
+ mongo_rt_before_render = Collector.reset_runtime
25
+ runtime = super
26
+ mongo_rt_after_render = Collector.reset_runtime
27
+ self.mongoid_runtime = mongo_rt_before_render + mongo_rt_after_render
28
+ runtime - mongo_rt_after_render
29
+ end
30
+
31
+ # Add the measurement to the instrumentation event payload.
32
+ def append_info_to_payload(payload)
33
+ super
34
+ payload[:mongoid_runtime] = (mongoid_runtime || 0) + Collector.reset_runtime
35
+ end
36
+
37
+ module ClassMethods
38
+
39
+ # Append MongoDB runtime information to ActionController runtime
40
+ # log message.
41
+ def log_process_action(payload)
42
+ messages = super
43
+ mongoid_runtime = payload[:mongoid_runtime]
44
+ messages << ("MongoDB: %.1fms" % mongoid_runtime.to_f) if mongoid_runtime
45
+ messages
46
+ end
47
+
48
+ end
49
+
50
+ end
51
+
52
+ # The Collector of MongoDB runtime metric, that subscribes to Mongo
53
+ # driver command monitoring. Stores the value within a thread-local
54
+ # variable to provide correct accounting when an application issues
55
+ # MongoDB operations from background threads.
56
+ class Collector
57
+
58
+ VARIABLE_NAME = "Mongoid.controller_runtime".freeze
59
+
60
+ def started _; end
61
+
62
+ def _completed e
63
+ Collector.runtime += e.duration
64
+ end
65
+ alias :succeeded :_completed
66
+ alias :failed :_completed
67
+
68
+ def self.runtime
69
+ Thread.current[VARIABLE_NAME] ||= 0
70
+ end
71
+
72
+ def self.runtime= value
73
+ Thread.current[VARIABLE_NAME] = value
74
+ end
75
+
76
+ def self.reset_runtime
77
+ to_now = runtime
78
+ self.runtime = 0
79
+ to_now
80
+ end
81
+
82
+ end
83
+
84
+ end
85
+ end
86
+ end
@@ -102,7 +102,7 @@ module Mongoid
102
102
  #
103
103
  # @since 3.0.0
104
104
  def default_scopable?
105
- default_scoping? && !Threaded.executing?(:without_default_scope)
105
+ default_scoping? && !Threaded.without_default_scope?(self)
106
106
  end
107
107
 
108
108
  # Get a queryable, either the last one on the scope stack or a fresh one.
@@ -244,10 +244,10 @@ module Mongoid
244
244
  #
245
245
  # @since 3.0.0
246
246
  def without_default_scope
247
- Threaded.begin_execution("without_default_scope")
247
+ Threaded.begin_without_default_scope(self)
248
248
  yield
249
249
  ensure
250
- Threaded.exit_execution("without_default_scope")
250
+ Threaded.exit_without_default_scope(self)
251
251
  end
252
252
 
253
253
  private
@@ -101,7 +101,7 @@ module Mongoid
101
101
  value = send(name)
102
102
  attrs[name] = value ? value.serializable_hash(options) : nil
103
103
  elsif names.include?(name) && !fields.key?(name)
104
- attrs[name] = read_attribute(name)
104
+ attrs[name] = read_raw_attribute(name)
105
105
  elsif !attribute_missing?(name)
106
106
  attrs[name] = send(name)
107
107
  end
@@ -124,9 +124,9 @@ module Mongoid
124
124
  def serialize_relations(attributes = {}, options = {})
125
125
  inclusions = options[:include]
126
126
  relation_names(inclusions).each do |name|
127
- metadata = relations[name.to_s]
128
- if metadata && relation = send(metadata.name)
129
- attributes[metadata.name.to_s] =
127
+ association = relations[name.to_s]
128
+ if association && relation = send(association.name)
129
+ attributes[association.name.to_s] =
130
130
  relation.serializable_hash(relation_options(inclusions, options, name))
131
131
  end
132
132
  end
@@ -37,7 +37,7 @@ module Mongoid
37
37
  def shard_key_selector
38
38
  selector = {}
39
39
  shard_key_fields.each do |field|
40
- selector[field.to_s] = send(field)
40
+ selector[field.to_s] = new_record? ? send(field) : attribute_was(field)
41
41
  end
42
42
  selector
43
43
  end
@@ -163,6 +163,30 @@ module Mongoid
163
163
  validations_for(document.class).delete_one(document._id)
164
164
  end
165
165
 
166
+ # Begin suppressing default scopes for given model on the current thread.
167
+ #
168
+ # @example Begin without default scope stack.
169
+ # Threaded.begin_without_default_scope(klass)
170
+ #
171
+ # @param [ Class ] klass The model to suppress default scoping on.
172
+ #
173
+ # @api private
174
+ def begin_without_default_scope(klass)
175
+ stack(:without_default_scope).push(klass)
176
+ end
177
+
178
+ # Exit suppressing default scopes for given model on the current thread.
179
+ #
180
+ # @example Exit without default scope stack.
181
+ # Threaded.exit_without_default_scope(klass)
182
+ #
183
+ # @param [ Class ] klass The model to unsuppress default scoping on.
184
+ #
185
+ # @api private
186
+ def exit_without_default_scope(klass)
187
+ stack(:without_default_scope).delete(klass)
188
+ end
189
+
166
190
  # Get the global client override.
167
191
  #
168
192
  # @example Get the global client override.
@@ -247,6 +271,18 @@ module Mongoid
247
271
  end
248
272
  end
249
273
 
274
+ # Is the given klass' default scope suppressed on the current thread?
275
+ #
276
+ # @example Is the given klass' default scope suppressed?
277
+ # Threaded.without_default_scope?(klass)
278
+ #
279
+ # @param [ Class ] klass The model to check for default scope suppression.
280
+ #
281
+ # @api private
282
+ def without_default_scope?(klass)
283
+ stack(:without_default_scope).include?(klass)
284
+ end
285
+
250
286
  # Is the document autosaved on the current thread?
251
287
  #
252
288
  # @example Is the document autosaved?
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+ module Mongoid
4
+ module Touchable
5
+
6
+ module InstanceMethods
7
+
8
+ # Touch the document, in effect updating its updated_at timestamp and
9
+ # optionally the provided field to the current time. If any belongs_to
10
+ # relations exist with a touch option, they will be updated as well.
11
+ #
12
+ # @example Update the updated_at timestamp.
13
+ # document.touch
14
+ #
15
+ # @example Update the updated_at and provided timestamps.
16
+ # document.touch(:audited)
17
+ #
18
+ # @note This will not autobuild relations if those options are set.
19
+ #
20
+ # @param [ Symbol ] field The name of an additional field to update.
21
+ #
22
+ # @return [ true/false ] false if record is new_record otherwise true.
23
+ #
24
+ # @since 3.0.0
25
+ def touch(field = nil)
26
+ return false if _root.new_record?
27
+ current = Time.now
28
+ field = database_field_name(field)
29
+ write_attribute(:updated_at, current) if respond_to?("updated_at=")
30
+ write_attribute(field, current) if field
31
+
32
+ touches = touch_atomic_updates(field)
33
+ unless touches["$set"].blank?
34
+ selector = atomic_selector
35
+ _root.collection.find(selector).update_one(positionally(selector, touches), session: _session)
36
+ end
37
+ run_callbacks(:touch)
38
+ true
39
+ end
40
+ end
41
+
42
+ extend self
43
+
44
+ # Add the association to the touchable relations if the touch option was
45
+ # provided.
46
+ #
47
+ # @example Add the touchable.
48
+ # Model.define_touchable!(assoc)
49
+ #
50
+ # @param [ Association ] association The association metadata.
51
+ #
52
+ # @return [ Class ] The model class.
53
+ #
54
+ # @since 3.0.0
55
+ def define_touchable!(association)
56
+ name = association.name
57
+ method_name = define_relation_touch_method(name, association)
58
+ association.inverse_class.tap do |klass|
59
+ klass.after_save method_name
60
+ klass.after_destroy method_name
61
+ klass.after_touch method_name
62
+ end
63
+ end
64
+
65
+ private
66
+
67
+ # Define the method that will get called for touching belongs_to
68
+ # relations.
69
+ #
70
+ # @api private
71
+ #
72
+ # @example Define the touch relation.
73
+ # Model.define_relation_touch_method(:band)
74
+ # Model.define_relation_touch_method(:band, :band_updated_at)
75
+ #
76
+ # @param [ Symbol ] name The name of the relation.
77
+ # @param [ Association ] association The association metadata.
78
+ #
79
+ # @since 3.1.0
80
+ #
81
+ # @return [ Symbol ] The method name.
82
+ def define_relation_touch_method(name, association)
83
+ relation_classes = if association.polymorphic?
84
+ association.send(:inverse_association_classes)
85
+ else
86
+ [ association.relation_class ]
87
+ end
88
+
89
+ relation_classes.each { |c| c.send(:include, InstanceMethods) }
90
+ method_name = "touch_#{name}_after_create_or_destroy"
91
+ association.inverse_class.class_eval <<-TOUCH, __FILE__, __LINE__ + 1
92
+ def #{method_name}
93
+ without_autobuild do
94
+ relation = __send__(:#{name})
95
+ relation.touch #{":#{association.touch_field}" if association.touch_field} if relation
96
+ end
97
+ end
98
+ TOUCH
99
+ method_name.to_sym
100
+ end
101
+ end
102
+ end
@@ -8,7 +8,7 @@ module Mongoid
8
8
  extend ActiveSupport::Concern
9
9
 
10
10
  def _parent
11
- @__parent
11
+ @__parent ||= nil
12
12
  end
13
13
 
14
14
  def _parent=(p)
@@ -40,7 +40,7 @@ module Mongoid
40
40
  # @since 2.4.0
41
41
  def collect_children
42
42
  children = []
43
- embedded_relations.each_pair do |name, metadata|
43
+ embedded_relations.each_pair do |name, association|
44
44
  without_autobuild do
45
45
  child = send(name)
46
46
  Array.wrap(child).each do |doc|
@@ -101,7 +101,7 @@ module Mongoid
101
101
  #
102
102
  # @since 2.0.0.beta.1
103
103
  def remove_child(child)
104
- name = child.metadata_name
104
+ name = child.association_name
105
105
  if child.embedded_one?
106
106
  remove_ivar(name)
107
107
  else
@@ -62,8 +62,8 @@ module Mongoid
62
62
  # @since 3.0.0
63
63
  def relation_or_fk_missing?(doc, attr, value)
64
64
  return true if value.blank? && doc.send(attr).blank?
65
- metadata = doc.relations[attr.to_s]
66
- metadata.stores_foreign_key? && doc.send(metadata.foreign_key).blank?
65
+ association = doc.relations[attr.to_s]
66
+ association.stores_foreign_key? && doc.send(association.foreign_key).blank?
67
67
  end
68
68
 
69
69
  # For guarding against false values.
@@ -224,9 +224,9 @@ module Mongoid
224
224
  #
225
225
  # @since 2.4.4
226
226
  def to_validate(document, attribute, value)
227
- metadata = document.relations[attribute.to_s]
228
- if metadata && metadata.stores_foreign_key?
229
- [ metadata.foreign_key, value && value._id ]
227
+ association = document.relations[attribute.to_s]
228
+ if association && association.stores_foreign_key?
229
+ [ association.foreign_key, value && value._id ]
230
230
  else
231
231
  [ attribute, value ]
232
232
  end
@@ -246,7 +246,7 @@ module Mongoid
246
246
  # @since 2.4.10
247
247
  def validate_embedded(document, attribute, value)
248
248
  return if skip_validation?(document)
249
- relation = document._parent.send(document.metadata_name)
249
+ relation = document._parent.send(document.association_name)
250
250
  criteria = create_criteria(relation, document, attribute, value)
251
251
  criteria = criteria.merge(options[:conditions].call) if options[:conditions]
252
252
  add_error(document, attribute, value) if criteria.count > 1