mongoid 6.4.8 → 7.0.0

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 (320) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/Rakefile +0 -26
  4. data/lib/config/locales/en.yml +17 -0
  5. data/lib/mongoid/association/accessors.rb +339 -0
  6. data/lib/mongoid/{relations/binding.rb → association/bindable.rb} +32 -52
  7. data/lib/mongoid/association/builders.rb +92 -0
  8. data/lib/mongoid/{relations/constraint.rb → association/constrainable.rb} +11 -22
  9. data/lib/mongoid/association/depending.rb +116 -0
  10. data/lib/mongoid/{relations/eager.rb → association/eager_loadable.rb} +11 -11
  11. data/lib/mongoid/{relations → association}/embedded/batchable.rb +21 -21
  12. data/lib/mongoid/association/embedded/cyclic.rb +109 -0
  13. data/lib/mongoid/association/embedded/embedded_in/binding.rb +56 -0
  14. data/lib/mongoid/{relations/builders/embedded/in.rb → association/embedded/embedded_in/buildable.rb} +12 -6
  15. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +121 -0
  16. data/lib/mongoid/association/embedded/embedded_in.rb +154 -0
  17. data/lib/mongoid/{relations/bindings/embedded/many.rb → association/embedded/embeds_many/binding.rb} +11 -9
  18. data/lib/mongoid/{relations/builders/embedded/many.rb → association/embedded/embeds_many/buildable.rb} +13 -7
  19. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +529 -0
  20. data/lib/mongoid/association/embedded/embeds_many.rb +210 -0
  21. data/lib/mongoid/{relations/bindings/embedded/one.rb → association/embedded/embeds_one/binding.rb} +12 -10
  22. data/lib/mongoid/{relations/builders/embedded/one.rb → association/embedded/embeds_one/buildable.rb} +13 -7
  23. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +130 -0
  24. data/lib/mongoid/association/embedded/embeds_one.rb +173 -0
  25. data/lib/mongoid/association/embedded.rb +4 -0
  26. data/lib/mongoid/association/macros.rb +204 -0
  27. data/lib/mongoid/{relations → association}/many.rb +20 -50
  28. data/lib/mongoid/{relations → association}/marshalable.rb +6 -4
  29. data/lib/mongoid/association/nested/many.rb +200 -0
  30. data/lib/mongoid/association/nested/nested_buildable.rb +72 -0
  31. data/lib/mongoid/association/nested/one.rb +127 -0
  32. data/lib/mongoid/association/nested.rb +15 -0
  33. data/lib/mongoid/{relations → association}/one.rb +6 -6
  34. data/lib/mongoid/association/options.rb +152 -0
  35. data/lib/mongoid/{relations → association}/proxy.rb +31 -58
  36. data/lib/mongoid/association/referenced/auto_save.rb +79 -0
  37. data/lib/mongoid/association/referenced/belongs_to/binding.rb +87 -0
  38. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +46 -0
  39. data/lib/mongoid/association/referenced/belongs_to/eager.rb +36 -0
  40. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +136 -0
  41. data/lib/mongoid/association/referenced/belongs_to.rb +248 -0
  42. data/lib/mongoid/association/referenced/counter_cache.rb +163 -0
  43. data/lib/mongoid/association/referenced/eager.rb +159 -0
  44. data/lib/mongoid/association/referenced/has_and_belongs_to_many/binding.rb +71 -0
  45. data/lib/mongoid/association/referenced/has_and_belongs_to_many/buildable.rb +40 -0
  46. data/lib/mongoid/association/referenced/has_and_belongs_to_many/eager.rb +52 -0
  47. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +310 -0
  48. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +290 -0
  49. data/lib/mongoid/{relations/bindings/referenced/many.rb → association/referenced/has_many/binding.rb} +6 -5
  50. data/lib/mongoid/association/referenced/has_many/buildable.rb +38 -0
  51. data/lib/mongoid/association/referenced/has_many/eager.rb +43 -0
  52. data/lib/mongoid/association/referenced/has_many/enumerable.rb +510 -0
  53. data/lib/mongoid/association/referenced/has_many/proxy.rb +578 -0
  54. data/lib/mongoid/association/referenced/has_many.rb +275 -0
  55. data/lib/mongoid/{relations/bindings/referenced/one.rb → association/referenced/has_one/binding.rb} +11 -8
  56. data/lib/mongoid/association/referenced/has_one/buildable.rb +60 -0
  57. data/lib/mongoid/association/referenced/has_one/eager.rb +35 -0
  58. data/lib/mongoid/{relations/builders/nested_attributes/one.rb → association/referenced/has_one/nested_builder.rb} +9 -9
  59. data/lib/mongoid/association/referenced/has_one/proxy.rb +113 -0
  60. data/lib/mongoid/association/referenced/has_one.rb +204 -0
  61. data/lib/mongoid/association/referenced/syncable.rb +170 -0
  62. data/lib/mongoid/association/referenced.rb +7 -0
  63. data/lib/mongoid/{relations → association}/reflections.rb +21 -17
  64. data/lib/mongoid/association/relatable.rb +415 -0
  65. data/lib/mongoid/association/touchable.rb +97 -0
  66. data/lib/mongoid/association.rb +150 -0
  67. data/lib/mongoid/atomic/paths/embedded/many.rb +1 -1
  68. data/lib/mongoid/atomic/paths/embedded/one.rb +1 -1
  69. data/lib/mongoid/atomic.rb +4 -4
  70. data/lib/mongoid/attributes/dynamic.rb +2 -2
  71. data/lib/mongoid/attributes/nested.rb +10 -10
  72. data/lib/mongoid/attributes/processing.rb +2 -2
  73. data/lib/mongoid/attributes/readonly.rb +2 -4
  74. data/lib/mongoid/attributes.rb +22 -13
  75. data/lib/mongoid/changeable.rb +1 -1
  76. data/lib/mongoid/clients/options.rb +1 -1
  77. data/lib/mongoid/clients/sessions.rb +2 -2
  78. data/lib/mongoid/composable.rb +4 -4
  79. data/lib/mongoid/config.rb +1 -0
  80. data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
  81. data/lib/mongoid/contextual/atomic.rb +1 -1
  82. data/lib/mongoid/contextual/geo_near.rb +1 -1
  83. data/lib/mongoid/contextual/map_reduce.rb +4 -4
  84. data/lib/mongoid/contextual/memory.rb +25 -7
  85. data/lib/mongoid/contextual/mongo.rb +13 -11
  86. data/lib/mongoid/copyable.rb +6 -6
  87. data/lib/mongoid/criteria/includable.rb +14 -14
  88. data/lib/mongoid/criteria/modifiable.rb +8 -14
  89. data/lib/mongoid/criteria/queryable/extensions/string.rb +1 -1
  90. data/lib/mongoid/criteria/queryable/pipeline.rb +10 -5
  91. data/lib/mongoid/criteria/queryable/selectable.rb +10 -34
  92. data/lib/mongoid/criteria.rb +2 -2
  93. data/lib/mongoid/document.rb +6 -6
  94. data/lib/mongoid/errors/invalid_dependent_strategy.rb +32 -0
  95. data/lib/mongoid/errors/invalid_relation_option.rb +29 -0
  96. data/lib/mongoid/errors/unknown_model.rb +25 -0
  97. data/lib/mongoid/errors.rb +3 -0
  98. data/lib/mongoid/extensions/array.rb +5 -5
  99. data/lib/mongoid/extensions/big_decimal.rb +1 -1
  100. data/lib/mongoid/extensions/hash.rb +5 -2
  101. data/lib/mongoid/extensions/object.rb +4 -4
  102. data/lib/mongoid/extensions/range.rb +1 -0
  103. data/lib/mongoid/extensions/regexp.rb +0 -1
  104. data/lib/mongoid/extensions/string.rb +1 -3
  105. data/lib/mongoid/extensions.rb +0 -4
  106. data/lib/mongoid/factory.rb +13 -3
  107. data/lib/mongoid/fields/foreign_key.rb +5 -5
  108. data/lib/mongoid/fields/standard.rb +2 -14
  109. data/lib/mongoid/fields/validators/macro.rb +1 -1
  110. data/lib/mongoid/fields.rb +3 -3
  111. data/lib/mongoid/indexable.rb +8 -5
  112. data/lib/mongoid/interceptable.rb +5 -5
  113. data/lib/mongoid/matchable/and.rb +1 -1
  114. data/lib/mongoid/matchable/elem_match.rb +9 -3
  115. data/lib/mongoid/matchable.rb +0 -3
  116. data/lib/mongoid/persistable/creatable.rb +2 -2
  117. data/lib/mongoid/persistable/deletable.rb +9 -8
  118. data/lib/mongoid/persistable/incrementable.rb +1 -1
  119. data/lib/mongoid/persistable/logical.rb +1 -1
  120. data/lib/mongoid/persistable/settable.rb +5 -5
  121. data/lib/mongoid/persistable/updatable.rb +2 -2
  122. data/lib/mongoid/persistable/upsertable.rb +1 -1
  123. data/lib/mongoid/persistable.rb +5 -6
  124. data/lib/mongoid/persistence_context.rb +1 -5
  125. data/lib/mongoid/query_cache.rb +19 -64
  126. data/lib/mongoid/railtie.rb +0 -17
  127. data/lib/mongoid/reloadable.rb +1 -1
  128. data/lib/mongoid/scopable.rb +3 -3
  129. data/lib/mongoid/serializable.rb +4 -4
  130. data/lib/mongoid/shardable.rb +1 -1
  131. data/lib/mongoid/tasks/database.rb +2 -2
  132. data/lib/mongoid/threaded.rb +0 -36
  133. data/lib/mongoid/traversable.rb +3 -3
  134. data/lib/mongoid/validatable/presence.rb +2 -2
  135. data/lib/mongoid/validatable/uniqueness.rb +4 -4
  136. data/lib/mongoid/validatable.rb +8 -8
  137. data/lib/mongoid/version.rb +1 -1
  138. data/lib/mongoid.rb +1 -1
  139. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +3 -0
  140. data/spec/app/models/animal.rb +2 -1
  141. data/spec/app/models/bomb.rb +1 -1
  142. data/spec/app/models/message.rb +1 -1
  143. data/spec/app/models/person.rb +5 -2
  144. data/spec/app/models/shipment_address.rb +1 -0
  145. data/spec/app/models/vertex.rb +6 -0
  146. data/spec/app/models/wiki_page.rb +1 -1
  147. data/spec/config/mongoid.yml +1 -0
  148. data/spec/mongoid/{relations → association}/accessors_spec.rb +1 -1
  149. data/spec/mongoid/{relations → association}/auto_save_spec.rb +60 -12
  150. data/spec/mongoid/{relations → association}/builders_spec.rb +1 -1
  151. data/spec/mongoid/association/constrainable_spec.rb +115 -0
  152. data/spec/mongoid/{relations → association}/counter_cache_spec.rb +1 -1
  153. data/spec/mongoid/association/depending_spec.rb +613 -0
  154. data/spec/mongoid/{relations → association}/eager_spec.rb +12 -12
  155. data/spec/mongoid/{relations → association/embedded}/cyclic_spec.rb +1 -1
  156. data/spec/mongoid/{relations/bindings/embedded/in_spec.rb → association/embedded/embedded_in/binding_spec.rb} +13 -13
  157. data/spec/mongoid/{relations/builders/embedded/in_spec.rb → association/embedded/embedded_in/buildable_spec.rb} +9 -9
  158. data/spec/mongoid/{relations/embedded/in_spec.rb → association/embedded/embedded_in/proxy_spec.rb} +5 -77
  159. data/spec/mongoid/association/embedded/embedded_in_spec.rb +843 -0
  160. data/spec/mongoid/{relations/bindings/embedded/many_spec.rb → association/embedded/embeds_many/binding_spec.rb} +3 -3
  161. data/spec/mongoid/{relations/builders/embedded/many_spec.rb → association/embedded/embeds_many/buildable_spec.rb} +17 -45
  162. data/spec/mongoid/{relations/embedded/many_spec.rb → association/embedded/embeds_many/proxy_spec.rb} +140 -428
  163. data/spec/mongoid/association/embedded/embeds_many_spec.rb +852 -0
  164. data/spec/mongoid/{relations/bindings/embedded/one_spec.rb → association/embedded/embeds_one/binding_spec.rb} +4 -4
  165. data/spec/mongoid/{relations/builders/embedded/one_spec.rb → association/embedded/embeds_one/buildable_spec.rb} +14 -34
  166. data/spec/mongoid/{relations/embedded/one_spec.rb → association/embedded/embeds_one/proxy_spec.rb} +39 -84
  167. data/spec/mongoid/association/embedded/embeds_one_spec.rb +908 -0
  168. data/spec/mongoid/{relations → association}/macros_spec.rb +148 -73
  169. data/spec/mongoid/{relations/builders/nested_attributes → association/nested}/many_spec.rb +16 -19
  170. data/spec/mongoid/{relations/builders/nested_attributes → association/nested}/one_spec.rb +17 -20
  171. data/spec/mongoid/association/options_spec.rb +1321 -0
  172. data/spec/mongoid/{relations → association}/polymorphic_spec.rb +7 -34
  173. data/spec/mongoid/{relations/bindings/referenced/in_spec.rb → association/referenced/belongs_to/binding_spec.rb} +7 -7
  174. data/spec/mongoid/{relations/builders/referenced/in_spec.rb → association/referenced/belongs_to/buildable_spec.rb} +46 -79
  175. data/spec/mongoid/{relations/eager/belongs_to_spec.rb → association/referenced/belongs_to/eager_spec.rb} +9 -9
  176. data/spec/mongoid/{relations/referenced/in_spec.rb → association/referenced/belongs_to/proxy_spec.rb} +57 -91
  177. data/spec/mongoid/association/referenced/belongs_to_spec.rb +1963 -0
  178. data/spec/mongoid/{relations/bindings/referenced/many_to_many_spec.rb → association/referenced/has_and_belongs_to_many/binding_spec.rb} +5 -5
  179. data/spec/mongoid/association/referenced/has_and_belongs_to_many/buildable_spec.rb +121 -0
  180. data/spec/mongoid/{relations/eager/has_and_belongs_to_many_spec.rb → association/referenced/has_and_belongs_to_many/eager_spec.rb} +5 -5
  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_spec.rb +1027 -0
  183. data/spec/mongoid/{relations/bindings/referenced/many_spec.rb → association/referenced/has_many/binding_spec.rb} +5 -5
  184. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +119 -0
  185. data/spec/mongoid/{relations/eager/has_many_spec.rb → association/referenced/has_many/eager_spec.rb} +26 -11
  186. data/spec/mongoid/{relations/targets → association/referenced/has_many}/enumerable_spec.rb +122 -1
  187. data/spec/mongoid/{relations/referenced/many_spec.rb → association/referenced/has_many/proxy_spec.rb} +28 -93
  188. data/spec/mongoid/association/referenced/has_many_spec.rb +1225 -0
  189. data/spec/mongoid/{relations/bindings/referenced/one_spec.rb → association/referenced/has_one/binding_spec.rb} +4 -4
  190. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +113 -0
  191. data/spec/mongoid/{relations/eager/has_one_spec.rb → association/referenced/has_one/eager_spec.rb} +10 -10
  192. data/spec/mongoid/{relations/referenced/one_spec.rb → association/referenced/has_one/proxy_spec.rb} +9 -109
  193. data/spec/mongoid/association/referenced/has_one_spec.rb +1244 -0
  194. data/spec/mongoid/{relations → association}/reflections_spec.rb +1 -12
  195. data/spec/mongoid/{relations/synchronization_spec.rb → association/syncable_spec.rb} +4 -2
  196. data/spec/mongoid/{relations → association}/touchable_spec.rb +19 -1
  197. data/spec/mongoid/{relations_spec.rb → association_spec.rb} +1 -1
  198. data/spec/mongoid/atomic/modifiers_spec.rb +2 -2
  199. data/spec/mongoid/atomic_spec.rb +4 -4
  200. data/spec/mongoid/attributes/nested_spec.rb +14 -12
  201. data/spec/mongoid/attributes/readonly_spec.rb +80 -125
  202. data/spec/mongoid/attributes_spec.rb +38 -2
  203. data/spec/mongoid/clients/factory_spec.rb +28 -52
  204. data/spec/mongoid/clients/options_spec.rb +65 -69
  205. data/spec/mongoid/clients/sessions_spec.rb +4 -13
  206. data/spec/mongoid/config_spec.rb +24 -0
  207. data/spec/mongoid/contextual/geo_near_spec.rb +0 -1
  208. data/spec/mongoid/contextual/memory_spec.rb +19 -0
  209. data/spec/mongoid/contextual/mongo_spec.rb +30 -5
  210. data/spec/mongoid/copyable_spec.rb +34 -0
  211. data/spec/mongoid/criteria/modifiable_spec.rb +183 -60
  212. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +3 -3
  213. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +43 -0
  214. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +12 -0
  215. data/spec/mongoid/criteria/queryable/selectable_spec.rb +3 -42
  216. data/spec/mongoid/criteria/queryable/selector_spec.rb +2 -2
  217. data/spec/mongoid/criteria/scopable_spec.rb +0 -81
  218. data/spec/mongoid/criteria_spec.rb +16 -19
  219. data/spec/mongoid/document_spec.rb +2 -56
  220. data/spec/mongoid/extensions/array_spec.rb +11 -15
  221. data/spec/mongoid/extensions/big_decimal_spec.rb +9 -9
  222. data/spec/mongoid/extensions/hash_spec.rb +18 -1
  223. data/spec/mongoid/extensions/object_spec.rb +7 -11
  224. data/spec/mongoid/extensions/range_spec.rb +7 -0
  225. data/spec/mongoid/extensions/regexp_spec.rb +0 -23
  226. data/spec/mongoid/extensions/string_spec.rb +7 -35
  227. data/spec/mongoid/factory_spec.rb +19 -1
  228. data/spec/mongoid/fields/foreign_key_spec.rb +24 -32
  229. data/spec/mongoid/fields_spec.rb +2 -2
  230. data/spec/mongoid/findable_spec.rb +1 -1
  231. data/spec/mongoid/indexable_spec.rb +18 -8
  232. data/spec/mongoid/interceptable_spec.rb +22 -1
  233. data/spec/mongoid/matchable/elem_match_spec.rb +20 -0
  234. data/spec/mongoid/matchable_spec.rb +1 -26
  235. data/spec/mongoid/persistable/incrementable_spec.rb +6 -6
  236. data/spec/mongoid/persistable/savable_spec.rb +2 -2
  237. data/spec/mongoid/persistable/settable_spec.rb +1 -35
  238. data/spec/mongoid/persistable_spec.rb +21 -6
  239. data/spec/mongoid/query_cache_spec.rb +16 -99
  240. data/spec/mongoid/relations/proxy_spec.rb +124 -124
  241. data/spec/mongoid/scopable_spec.rb +0 -13
  242. data/spec/mongoid/shardable_spec.rb +32 -12
  243. data/spec/mongoid/threaded_spec.rb +0 -68
  244. data/spec/mongoid/validatable/associated_spec.rb +1 -1
  245. data/spec/mongoid/validatable/presence_spec.rb +7 -6
  246. data/spec/mongoid/validatable_spec.rb +1 -1
  247. data/spec/spec_helper.rb +12 -14
  248. data.tar.gz.sig +1 -1
  249. metadata +192 -207
  250. metadata.gz.sig +0 -0
  251. data/lib/mongoid/matchable/nor.rb +0 -37
  252. data/lib/mongoid/railties/controller_runtime.rb +0 -86
  253. data/lib/mongoid/relations/accessors.rb +0 -267
  254. data/lib/mongoid/relations/auto_save.rb +0 -94
  255. data/lib/mongoid/relations/bindings/embedded/in.rb +0 -59
  256. data/lib/mongoid/relations/bindings/referenced/in.rb +0 -65
  257. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +0 -70
  258. data/lib/mongoid/relations/bindings.rb +0 -9
  259. data/lib/mongoid/relations/builder.rb +0 -57
  260. data/lib/mongoid/relations/builders/nested_attributes/many.rb +0 -199
  261. data/lib/mongoid/relations/builders/referenced/in.rb +0 -26
  262. data/lib/mongoid/relations/builders/referenced/many.rb +0 -26
  263. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +0 -39
  264. data/lib/mongoid/relations/builders/referenced/one.rb +0 -26
  265. data/lib/mongoid/relations/builders.rb +0 -106
  266. data/lib/mongoid/relations/cascading/delete.rb +0 -44
  267. data/lib/mongoid/relations/cascading/destroy.rb +0 -43
  268. data/lib/mongoid/relations/cascading/nullify.rb +0 -35
  269. data/lib/mongoid/relations/cascading/restrict.rb +0 -39
  270. data/lib/mongoid/relations/cascading.rb +0 -56
  271. data/lib/mongoid/relations/conversions.rb +0 -34
  272. data/lib/mongoid/relations/counter_cache.rb +0 -160
  273. data/lib/mongoid/relations/cyclic.rb +0 -107
  274. data/lib/mongoid/relations/eager/base.rb +0 -153
  275. data/lib/mongoid/relations/eager/belongs_to.rb +0 -31
  276. data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +0 -47
  277. data/lib/mongoid/relations/eager/has_many.rb +0 -38
  278. data/lib/mongoid/relations/eager/has_one.rb +0 -30
  279. data/lib/mongoid/relations/embedded/in.rb +0 -241
  280. data/lib/mongoid/relations/embedded/many.rb +0 -683
  281. data/lib/mongoid/relations/embedded/one.rb +0 -235
  282. data/lib/mongoid/relations/macros.rb +0 -367
  283. data/lib/mongoid/relations/metadata.rb +0 -1179
  284. data/lib/mongoid/relations/nested_builder.rb +0 -74
  285. data/lib/mongoid/relations/options.rb +0 -49
  286. data/lib/mongoid/relations/polymorphic.rb +0 -39
  287. data/lib/mongoid/relations/referenced/in.rb +0 -304
  288. data/lib/mongoid/relations/referenced/many.rb +0 -812
  289. data/lib/mongoid/relations/referenced/many_to_many.rb +0 -479
  290. data/lib/mongoid/relations/referenced/one.rb +0 -290
  291. data/lib/mongoid/relations/synchronization.rb +0 -169
  292. data/lib/mongoid/relations/targets/enumerable.rb +0 -493
  293. data/lib/mongoid/relations/targets.rb +0 -2
  294. data/lib/mongoid/relations/touchable.rb +0 -97
  295. data/lib/mongoid/relations.rb +0 -148
  296. data/spec/app/models/array_field.rb +0 -7
  297. data/spec/app/models/delegating_patient.rb +0 -16
  298. data/spec/integration/document_spec.rb +0 -22
  299. data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +0 -184
  300. data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +0 -201
  301. data/spec/mongoid/matchable/nor_spec.rb +0 -209
  302. data/spec/mongoid/relations/builders/referenced/many_spec.rb +0 -137
  303. data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +0 -178
  304. data/spec/mongoid/relations/builders/referenced/one_spec.rb +0 -111
  305. data/spec/mongoid/relations/cascading/delete_spec.rb +0 -101
  306. data/spec/mongoid/relations/cascading/destroy_spec.rb +0 -47
  307. data/spec/mongoid/relations/cascading/nullify_spec.rb +0 -32
  308. data/spec/mongoid/relations/cascading/restrict_spec.rb +0 -68
  309. data/spec/mongoid/relations/cascading_spec.rb +0 -355
  310. data/spec/mongoid/relations/constraint_spec.rb +0 -75
  311. data/spec/mongoid/relations/conversions_spec.rb +0 -128
  312. data/spec/mongoid/relations/metadata_spec.rb +0 -1985
  313. data/spec/mongoid/relations/options_spec.rb +0 -35
  314. data/spec/rails/controller_extension/controller_runtime_spec.rb +0 -110
  315. data/spec/support/cluster_config.rb +0 -158
  316. data/spec/support/constraints.rb +0 -101
  317. data/spec/support/macros.rb +0 -20
  318. data/spec/support/session_registry.rb +0 -50
  319. data/spec/support/spec_config.rb +0 -42
  320. /data/spec/mongoid/{relations → association}/embedded/dirty_spec.rb +0 -0
@@ -0,0 +1,310 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Association
4
+ module Referenced
5
+ class HasAndBelongsToMany
6
+
7
+ # This class defines the behaviour for all relations that are a
8
+ # many-to-many between documents in different collections.
9
+ class Proxy < Referenced::HasMany::Proxy
10
+
11
+ # Appends a document or array of documents to the relation. Will set
12
+ # the parent and update the index in the process.
13
+ #
14
+ # @example Append a document.
15
+ # person.posts << post
16
+ #
17
+ # @example Push a document.
18
+ # person.posts.push(post)
19
+ #
20
+ # @example Concat with other documents.
21
+ # person.posts.concat([ post_one, post_two ])
22
+ #
23
+ # @param [ Document, Array<Document> ] args Any number of documents.
24
+ #
25
+ # @return [ Array<Document> ] The loaded docs.
26
+ #
27
+ # @since 2.0.0.beta.1
28
+ def <<(*args)
29
+ docs = args.flatten
30
+ return concat(docs) if docs.size > 1
31
+ if doc = docs.first
32
+ append(doc)
33
+ _base.add_to_set(foreign_key => doc.send(_association.primary_key))
34
+ if child_persistable?(doc)
35
+ doc.save
36
+ end
37
+ end
38
+ unsynced(_base, foreign_key) and self
39
+ end
40
+
41
+ alias :push :<<
42
+
43
+ # Appends an array of documents to the relation. Performs a batch
44
+ # insert of the documents instead of persisting one at a time.
45
+ #
46
+ # @example Concat with other documents.
47
+ # person.posts.concat([ post_one, post_two ])
48
+ #
49
+ # @param [ Array<Document> ] documents The docs to add.
50
+ #
51
+ # @return [ Array<Document> ] The documents.
52
+ #
53
+ # @since 2.4.0
54
+ def concat(documents)
55
+ ids, docs, inserts = {}, [], []
56
+ documents.each do |doc|
57
+ next unless doc
58
+ append(doc)
59
+ if persistable? || _creating?
60
+ ids[doc._id] = true
61
+ save_or_delay(doc, docs, inserts)
62
+ else
63
+ existing = _base.send(foreign_key)
64
+ unless existing.include?(doc._id)
65
+ existing.push(doc._id) and unsynced(_base, foreign_key)
66
+ end
67
+ end
68
+ end
69
+ if persistable? || _creating?
70
+ _base.push(foreign_key => ids.keys)
71
+ end
72
+ persist_delayed(docs, inserts)
73
+ self
74
+ end
75
+
76
+ # Build a new document from the attributes and append it to this
77
+ # relation without saving.
78
+ #
79
+ # @example Build a new document on the relation.
80
+ # person.posts.build(:title => "A new post")
81
+ #
82
+ # @param [ Hash ] attributes The attributes of the new document.
83
+ # @param [ Class ] type The optional subclass to build.
84
+ #
85
+ # @return [ Document ] The new document.
86
+ #
87
+ # @since 2.0.0.beta.1
88
+ def build(attributes = {}, type = nil)
89
+ doc = Factory.build(type || klass, attributes)
90
+ _base.send(foreign_key).push(doc._id)
91
+ append(doc)
92
+ doc.apply_post_processed_defaults
93
+ unsynced(doc, inverse_foreign_key)
94
+ yield(doc) if block_given?
95
+ doc
96
+ end
97
+
98
+ alias :new :build
99
+
100
+ # Delete the document from the relation. This will set the foreign key
101
+ # on the document to nil. If the dependent options on the relation are
102
+ # :delete or :destroy the appropriate removal will occur.
103
+ #
104
+ # @example Delete the document.
105
+ # person.posts.delete(post)
106
+ #
107
+ # @param [ Document ] document The document to remove.
108
+ #
109
+ # @return [ Document ] The matching document.
110
+ #
111
+ # @since 2.1.0
112
+ def delete(document)
113
+ doc = super
114
+ if doc && persistable?
115
+ _base.pull(foreign_key => doc.send(_association.primary_key))
116
+ _target._unloaded = criteria
117
+ unsynced(_base, foreign_key)
118
+ end
119
+ doc
120
+ end
121
+
122
+ # Removes all associations between the base document and the target
123
+ # documents by deleting the foreign keys and the references, orphaning
124
+ # the target documents in the process.
125
+ #
126
+ # @example Nullify the relation.
127
+ # person.preferences.nullify
128
+ #
129
+ # @param [ Array<Document> ] replacement The replacement documents.
130
+ #
131
+ # @since 2.0.0.rc.1
132
+ def nullify(replacement = [])
133
+ _target.each do |doc|
134
+ execute_callback :before_remove, doc
135
+ end
136
+ unless _association.forced_nil_inverse?
137
+ if replacement
138
+ objects_to_clear = _base.send(foreign_key) - replacement.collect(&:id)
139
+ criteria(objects_to_clear).pull(inverse_foreign_key => _base._id)
140
+ else
141
+ criteria.pull(inverse_foreign_key => _base._id)
142
+ end
143
+ end
144
+ if persistable?
145
+ _base.set(foreign_key => _base.send(foreign_key).clear)
146
+ end
147
+ after_remove_error = nil
148
+ many_to_many = _target.clear do |doc|
149
+ unbind_one(doc)
150
+ unless _association.forced_nil_inverse?
151
+ doc.changed_attributes.delete(inverse_foreign_key)
152
+ end
153
+ begin
154
+ execute_callback :after_remove, doc
155
+ rescue => e
156
+ after_remove_error = e
157
+ end
158
+ end
159
+ raise after_remove_error if after_remove_error
160
+ many_to_many
161
+ end
162
+
163
+ alias :nullify_all :nullify
164
+ alias :clear :nullify
165
+ alias :purge :nullify
166
+
167
+ # Substitutes the supplied target documents for the existing documents
168
+ # in the relation. If the new target is nil, perform the necessary
169
+ # deletion.
170
+ #
171
+ # @example Replace the relation.
172
+ # person.preferences.substitute([ new_post ])
173
+ #
174
+ # @param [ Array<Document> ] replacement The replacement target.
175
+ #
176
+ # @return [ Many ] The relation.
177
+ #
178
+ # @since 2.0.0.rc.1
179
+ def substitute(replacement)
180
+ purge(replacement)
181
+ unless replacement.blank?
182
+ push(replacement.compact.uniq)
183
+ else
184
+ reset_unloaded
185
+ end
186
+ self
187
+ end
188
+
189
+ # Get a criteria for the documents without the default scoping
190
+ # applied.
191
+ #
192
+ # @example Get the unscoped criteria.
193
+ # person.preferences.unscoped
194
+ #
195
+ # @return [ Criteria ] The unscoped criteria.
196
+ #
197
+ # @since 2.4.0
198
+ def unscoped
199
+ klass.unscoped.any_in(_id: _base.send(foreign_key))
200
+ end
201
+
202
+ private
203
+
204
+ # Appends the document to the target array, updating the index on the
205
+ # document at the same time.
206
+ #
207
+ # @example Append the document to the relation.
208
+ # relation.append(document)
209
+ #
210
+ # @param [ Document ] document The document to append to the target.
211
+ #
212
+ # @since 2.0.0.rc.1
213
+ def append(document)
214
+ execute_callback :before_add, document
215
+ _target.push(document)
216
+ characterize_one(document)
217
+ bind_one(document)
218
+ execute_callback :after_add, document
219
+ end
220
+
221
+ # Instantiate the binding associated with this relation.
222
+ #
223
+ # @example Get the binding.
224
+ # relation.binding([ address ])
225
+ #
226
+ # @return [ Binding ] The binding.
227
+ #
228
+ # @since 2.0.0.rc.1
229
+ def binding
230
+ HasAndBelongsToMany::Binding.new(_base, _target, _association)
231
+ end
232
+
233
+ # Determine if the child document should be persisted.
234
+ #
235
+ # @api private
236
+ #
237
+ # @example Is the child persistable?
238
+ # relation.child_persistable?(doc)
239
+ #
240
+ # @param [ Document ] doc The document.
241
+ #
242
+ # @return [ true, false ] If the document can be persisted.
243
+ #
244
+ # @since 3.0.20
245
+ def child_persistable?(doc)
246
+ (persistable? || _creating?) &&
247
+ !(doc.persisted? && _association.forced_nil_inverse?)
248
+ end
249
+
250
+ # Returns the criteria object for the target class with its documents set
251
+ # to target.
252
+ #
253
+ # @example Get a criteria for the relation.
254
+ # relation.criteria
255
+ #
256
+ # @return [ Criteria ] A new criteria.
257
+ def criteria(id_list = nil)
258
+ _association.criteria(_base, id_list)
259
+ end
260
+
261
+ # Flag the base as unsynced with respect to the foreign key.
262
+ #
263
+ # @api private
264
+ #
265
+ # @example Flag as unsynced.
266
+ # relation.unsynced(doc, :preference_ids)
267
+ #
268
+ # @param [ Document ] doc The document to flag.
269
+ # @param [ Symbol ] key The key to flag on the document.
270
+ #
271
+ # @return [ true ] true.
272
+ #
273
+ # @since 3.0.0
274
+ def unsynced(doc, key)
275
+ doc._synced[key] = false
276
+ true
277
+ end
278
+
279
+ class << self
280
+
281
+ # Get the Eager object for this type of association.
282
+ #
283
+ # @example Get the eager loader object
284
+ #
285
+ # @param [ Association ] association The association object.
286
+ # @param [ Array<Document> ] docs The array of documents.
287
+ #
288
+ # @since 7.0
289
+ def eager_loader(association, docs)
290
+ Eager.new(association, docs)
291
+ end
292
+
293
+ # Returns true if the relation is an embedded one. In this case
294
+ # always false.
295
+ #
296
+ # @example Is this relation embedded?
297
+ # Referenced::ManyToMany.embedded?
298
+ #
299
+ # @return [ false ] Always false.
300
+ #
301
+ # @since 2.0.0.rc.1
302
+ def embedded?
303
+ false
304
+ end
305
+ end
306
+ end
307
+ end
308
+ end
309
+ end
310
+ end
@@ -0,0 +1,290 @@
1
+ require 'mongoid/association/referenced/has_and_belongs_to_many/binding'
2
+ require 'mongoid/association/referenced/has_and_belongs_to_many/buildable'
3
+ require 'mongoid/association/referenced/has_and_belongs_to_many/proxy'
4
+ require 'mongoid/association/referenced/has_and_belongs_to_many/eager'
5
+
6
+ module Mongoid
7
+ module Association
8
+ module Referenced
9
+
10
+ # The HasAndBelongsToMany type association.
11
+ #
12
+ # @since 7.0
13
+ class HasAndBelongsToMany
14
+ include Relatable
15
+ include Buildable
16
+
17
+ # The options available for this type of association, in addition to the
18
+ # common ones.
19
+ #
20
+ # @return [ Array<Symbol> ] The extra valid options.
21
+ #
22
+ # @since 7.0
23
+ ASSOCIATION_OPTIONS = [
24
+ :after_add,
25
+ :after_remove,
26
+ :autosave,
27
+ :before_add,
28
+ :before_remove,
29
+ :counter_cache,
30
+ :dependent,
31
+ :foreign_key,
32
+ :index,
33
+ :order,
34
+ :primary_key
35
+ ].freeze
36
+
37
+ # The complete list of valid options for this association, including
38
+ # the shared ones.
39
+ #
40
+ # @return [ Array<Symbol> ] The valid options.
41
+ #
42
+ # @since 7.0
43
+ VALID_OPTIONS = (ASSOCIATION_OPTIONS + SHARED_OPTIONS).freeze
44
+
45
+ # The type of the field holding the foreign key.
46
+ #
47
+ # @return [ Array ]
48
+ #
49
+ # @since 7.0
50
+ FOREIGN_KEY_FIELD_TYPE = Array
51
+
52
+ # The default foreign key suffix.
53
+ #
54
+ # @return [ String ] '_ids'
55
+ #
56
+ # @since 7.0
57
+ FOREIGN_KEY_SUFFIX = '_ids'.freeze
58
+
59
+ # The list of association complements.
60
+ #
61
+ # @return [ Array<Association> ] The association complements.
62
+ #
63
+ # @since 7.0
64
+ def relation_complements
65
+ @relation_complements ||= [ self.class ].freeze
66
+ end
67
+
68
+ # Setup the instance methods, fields, etc. on the association owning class.
69
+ #
70
+ # @return [ self ]
71
+ #
72
+ # @since 7.0
73
+ def setup!
74
+ setup_instance_methods!
75
+ self
76
+ end
77
+
78
+ # Is this association type embedded?
79
+ #
80
+ # @return [ false ] Always false.
81
+ #
82
+ # @since 7.0
83
+ def embedded?; false; end
84
+
85
+ # The default for validation the association object.
86
+ #
87
+ # @return [ false ] Always false.
88
+ #
89
+ # @since 7.0
90
+ def validation_default; true; end
91
+
92
+ # Are ids only saved on this side of the relation?
93
+ #
94
+ # @return [ true, false ] Whether this association has a forced nil inverse.
95
+ #
96
+ # @since 7.0
97
+ def forced_nil_inverse?
98
+ @forced_nil_inverse ||= @options.key?(:inverse_of) && !@options[:inverse_of]
99
+ end
100
+
101
+ # Does this association type store the foreign key?
102
+ #
103
+ # @return [ true ] Always true.
104
+ #
105
+ # @since 7.0
106
+ def stores_foreign_key?; true; end
107
+
108
+ # Get the relation proxy class for this association type.
109
+ #
110
+ # @return [ Association::HasAndBelongsToMany::Proxy ] The proxy class.
111
+ #
112
+ # @since 7.0
113
+ def relation
114
+ Proxy
115
+ end
116
+
117
+ # Get the foreign key field for saving the association reference.
118
+ #
119
+ # @return [ String ] The foreign key field for saving the association reference.
120
+ #
121
+ # @since 7.0
122
+ def foreign_key
123
+ @foreign_key ||= @options[:foreign_key] ? @options[:foreign_key].to_s :
124
+ default_foreign_key_field
125
+ end
126
+
127
+ # The criteria used for querying this relation.
128
+ #
129
+ # @return [ Mongoid::Criteria ] The criteria used for querying this relation.
130
+ #
131
+ # @since 7.0
132
+ def criteria(base, id_list = nil)
133
+ query_criteria(id_list || base.send(foreign_key))
134
+ end
135
+
136
+ # Get the foreign key field on the inverse.
137
+ #
138
+ # @return [ String ] The foreign key field for saving the association reference
139
+ # on the inverse side.
140
+ #
141
+ # @since 7.0
142
+ def inverse_foreign_key
143
+ if @options.key?(:inverse_of)
144
+ inverse_of ? "#{inverse_of.to_s.singularize}#{FOREIGN_KEY_SUFFIX}" : nil
145
+ else
146
+ "#{inverse_class_name.demodulize.underscore}#{FOREIGN_KEY_SUFFIX}"
147
+ end
148
+ end
149
+
150
+ # Whether trying to bind an object using this association should raise
151
+ # an error.
152
+ #
153
+ # @param [ Document ] doc The document to be bound.
154
+ #
155
+ # @return [ true, false ] Whether the document can be bound.
156
+ def bindable?(doc)
157
+ forced_nil_inverse? || (!!inverse && doc.fields.keys.include?(foreign_key))
158
+ end
159
+
160
+ # Get the foreign key setter on the inverse.
161
+ #
162
+ # @return [ String ] The foreign key setter for saving the association reference
163
+ # on the inverse side.
164
+ #
165
+ # @since 7.0
166
+ def inverse_foreign_key_setter
167
+ @inverse_foreign_key_setter ||= "#{inverse_foreign_key}=" if inverse_foreign_key
168
+ end
169
+
170
+ # The nested builder object.
171
+ #
172
+ # @param [ Hash ] attributes The attributes to use to build the association object.
173
+ # @param [ Hash ] options The options for the association.
174
+ #
175
+ # @return [ Association::Nested::One ] The Nested Builder object.
176
+ #
177
+ # @since 7.0
178
+ def nested_builder(attributes, options)
179
+ Nested::Many.new(self, attributes, options)
180
+ end
181
+
182
+ # Get the path calculator for the supplied document.
183
+ #
184
+ # @example Get the path calculator.
185
+ # association.path(document)
186
+ #
187
+ # @param [ Document ] document The document to calculate on.
188
+ #
189
+ # @return [ Root ] The root atomic path calculator.
190
+ #
191
+ # @since 2.1.0
192
+ def path(document)
193
+ Mongoid::Atomic::Paths::Root.new(document)
194
+ end
195
+
196
+ private
197
+
198
+ def setup_instance_methods!
199
+ define_getter!
200
+ define_setter!
201
+ define_dependency!
202
+ define_existence_check!
203
+ define_autosaver!
204
+ define_counter_cache_callbacks!
205
+ create_foreign_key_field!
206
+ setup_index!
207
+ setup_syncing!
208
+ @owner_class.validates_associated(name) if validate?
209
+ self
210
+ end
211
+
212
+ def index_spec
213
+ { key => 1 }
214
+ end
215
+
216
+ def default_primary_key
217
+ PRIMARY_KEY_DEFAULT
218
+ end
219
+
220
+ def default_foreign_key_field
221
+ @default_foreign_key_field ||= "#{name.to_s.singularize}#{FOREIGN_KEY_SUFFIX}"
222
+ end
223
+
224
+ def setup_syncing!
225
+ unless forced_nil_inverse?
226
+ synced_save
227
+ synced_destroy
228
+ end
229
+ end
230
+
231
+ def synced_destroy
232
+ assoc = self
233
+ inverse_class.set_callback(
234
+ :destroy,
235
+ :after
236
+ ) do |doc|
237
+ doc.remove_inverse_keys(assoc)
238
+ end
239
+ end
240
+
241
+ def synced_save
242
+ assoc = self
243
+ inverse_class.set_callback(
244
+ :save,
245
+ :after,
246
+ if: ->(doc){ doc._syncable?(assoc) }
247
+ ) do |doc|
248
+ doc.update_inverse_keys(assoc)
249
+ end
250
+ end
251
+
252
+ def create_foreign_key_field!
253
+ @owner_class.field(
254
+ foreign_key,
255
+ type: FOREIGN_KEY_FIELD_TYPE,
256
+ identity: true,
257
+ overwrite: true,
258
+ association: self,
259
+ default: nil
260
+ )
261
+ end
262
+
263
+ def determine_inverses(other)
264
+ matches = (other || relation_class).relations.values.select do |rel|
265
+ relation_complements.include?(rel.class) &&
266
+ rel.relation_class_name == inverse_class_name
267
+
268
+ end
269
+ if matches.size > 1
270
+ raise Errors::AmbiguousRelationship.new(relation_class, @owner_class, name, matches)
271
+ end
272
+ matches.collect { |m| m.name } unless matches.blank?
273
+ end
274
+
275
+ def with_ordering(criteria)
276
+ if order
277
+ criteria.order_by(order)
278
+ else
279
+ criteria
280
+ end
281
+ end
282
+
283
+ def query_criteria(id_list)
284
+ crit = relation_class.all_of(primary_key => {"$in" => id_list || []})
285
+ with_ordering(crit)
286
+ end
287
+ end
288
+ end
289
+ end
290
+ end
@@ -1,11 +1,12 @@
1
1
  # encoding: utf-8
2
2
  module Mongoid
3
- module Relations
4
- module Bindings
5
- module Referenced
3
+ module Association
4
+ module Referenced
5
+ class HasMany
6
6
 
7
- # Binding class for references_many relations.
8
- class Many < Binding
7
+ # Binding class for has_many associations.
8
+ class Binding
9
+ include Bindable
9
10
 
10
11
  # Binds a single document with the inverse relation. Used
11
12
  # specifically when appending to the proxy.
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Association
4
+ module Referenced
5
+ class HasMany
6
+
7
+ # The Builder behavior for has_many associations.
8
+ #
9
+ # @since 7.0
10
+ module Buildable
11
+
12
+ # This method either takes an _id or an object and queries for the
13
+ # inverse side using the id or sets the object.
14
+ #
15
+ # @example Build the document.
16
+ # relation.build(meta, attrs)
17
+ #
18
+ # @param [ Object ] base The base object.
19
+ # @param [ Object ] object The object to use to build the relation.
20
+ # @param [ String ] type The type of document to query for.
21
+ #
22
+ # @return [ Document ] A single document.
23
+ def build(base, object, type = nil)
24
+ return (object || []) unless query?(object)
25
+ return [] if object.is_a?(Array)
26
+ query_criteria(object, base)
27
+ end
28
+
29
+ private
30
+
31
+ def query?(object)
32
+ object && Array(object).all? { |d| !d.is_a?(Mongoid::Document) }
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Association
4
+ module Referenced
5
+ class HasMany
6
+
7
+ # Eager class for has_many associations.
8
+ class Eager < Association::Referenced::Eager::Base
9
+
10
+ private
11
+
12
+ def preload
13
+ @docs.each do |d|
14
+ set_relation(d, [])
15
+ end
16
+
17
+ entries = Hash.new { |hash, key| hash[key] = [] }
18
+ each_loaded_document do |doc|
19
+ fk = doc.send(key)
20
+ entries[fk] << doc
21
+ end
22
+
23
+ entries.each do |id, docs|
24
+ set_on_parent(id, docs)
25
+ end
26
+ end
27
+
28
+ def set_relation(doc, element)
29
+ doc.__build__(@association.name, element, @association) unless doc.blank?
30
+ end
31
+
32
+ def group_by_key
33
+ @association.primary_key
34
+ end
35
+
36
+ def key
37
+ @association.foreign_key
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end