mongoid 6.4.8 → 7.0.0.beta

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 (315) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Rakefile +0 -26
  5. data/lib/config/locales/en.yml +17 -21
  6. data/lib/mongoid.rb +2 -2
  7. data/lib/mongoid/association.rb +150 -0
  8. data/lib/mongoid/association/accessors.rb +339 -0
  9. data/lib/mongoid/{relations/binding.rb → association/bindable.rb} +32 -52
  10. data/lib/mongoid/association/builders.rb +92 -0
  11. data/lib/mongoid/{relations/constraint.rb → association/constrainable.rb} +11 -22
  12. data/lib/mongoid/association/depending.rb +116 -0
  13. data/lib/mongoid/{relations/eager.rb → association/eager_loadable.rb} +11 -11
  14. data/lib/mongoid/association/embedded.rb +4 -0
  15. data/lib/mongoid/{relations → association}/embedded/batchable.rb +27 -53
  16. data/lib/mongoid/association/embedded/cyclic.rb +109 -0
  17. data/lib/mongoid/association/embedded/embedded_in.rb +154 -0
  18. data/lib/mongoid/association/embedded/embedded_in/binding.rb +56 -0
  19. data/lib/mongoid/{relations/builders/embedded/in.rb → association/embedded/embedded_in/buildable.rb} +12 -6
  20. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +121 -0
  21. data/lib/mongoid/association/embedded/embeds_many.rb +210 -0
  22. data/lib/mongoid/{relations/bindings/embedded/many.rb → association/embedded/embeds_many/binding.rb} +11 -9
  23. data/lib/mongoid/{relations/builders/embedded/many.rb → association/embedded/embeds_many/buildable.rb} +13 -7
  24. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +529 -0
  25. data/lib/mongoid/association/embedded/embeds_one.rb +173 -0
  26. data/lib/mongoid/{relations/bindings/embedded/one.rb → association/embedded/embeds_one/binding.rb} +12 -10
  27. data/lib/mongoid/{relations/builders/embedded/one.rb → association/embedded/embeds_one/buildable.rb} +13 -7
  28. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +130 -0
  29. data/lib/mongoid/association/macros.rb +204 -0
  30. data/lib/mongoid/{relations → association}/many.rb +18 -52
  31. data/lib/mongoid/{relations → association}/marshalable.rb +6 -4
  32. data/lib/mongoid/association/nested.rb +15 -0
  33. data/lib/mongoid/association/nested/many.rb +200 -0
  34. data/lib/mongoid/association/nested/nested_buildable.rb +72 -0
  35. data/lib/mongoid/association/nested/one.rb +127 -0
  36. data/lib/mongoid/{relations → association}/one.rb +6 -6
  37. data/lib/mongoid/association/options.rb +152 -0
  38. data/lib/mongoid/{relations → association}/proxy.rb +31 -58
  39. data/lib/mongoid/association/referenced.rb +7 -0
  40. data/lib/mongoid/association/referenced/auto_save.rb +79 -0
  41. data/lib/mongoid/association/referenced/belongs_to.rb +248 -0
  42. data/lib/mongoid/association/referenced/belongs_to/binding.rb +87 -0
  43. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +46 -0
  44. data/lib/mongoid/association/referenced/belongs_to/eager.rb +36 -0
  45. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +136 -0
  46. data/lib/mongoid/association/referenced/counter_cache.rb +163 -0
  47. data/lib/mongoid/association/referenced/eager.rb +159 -0
  48. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +290 -0
  49. data/lib/mongoid/association/referenced/has_and_belongs_to_many/binding.rb +71 -0
  50. data/lib/mongoid/association/referenced/has_and_belongs_to_many/buildable.rb +40 -0
  51. data/lib/mongoid/association/referenced/has_and_belongs_to_many/eager.rb +52 -0
  52. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +310 -0
  53. data/lib/mongoid/association/referenced/has_many.rb +273 -0
  54. data/lib/mongoid/{relations/bindings/referenced/many.rb → association/referenced/has_many/binding.rb} +6 -5
  55. data/lib/mongoid/association/referenced/has_many/buildable.rb +38 -0
  56. data/lib/mongoid/association/referenced/has_many/eager.rb +43 -0
  57. data/lib/mongoid/association/referenced/has_many/enumerable.rb +479 -0
  58. data/lib/mongoid/association/referenced/has_many/proxy.rb +577 -0
  59. data/lib/mongoid/association/referenced/has_one.rb +204 -0
  60. data/lib/mongoid/{relations/bindings/referenced/one.rb → association/referenced/has_one/binding.rb} +11 -8
  61. data/lib/mongoid/association/referenced/has_one/buildable.rb +60 -0
  62. data/lib/mongoid/association/referenced/has_one/eager.rb +35 -0
  63. data/lib/mongoid/{relations/builders/nested_attributes/one.rb → association/referenced/has_one/nested_builder.rb} +9 -9
  64. data/lib/mongoid/association/referenced/has_one/proxy.rb +113 -0
  65. data/lib/mongoid/association/referenced/syncable.rb +170 -0
  66. data/lib/mongoid/{relations → association}/reflections.rb +21 -17
  67. data/lib/mongoid/association/relatable.rb +415 -0
  68. data/lib/mongoid/association/touchable.rb +97 -0
  69. data/lib/mongoid/atomic.rb +6 -6
  70. data/lib/mongoid/atomic/modifiers.rb +8 -12
  71. data/lib/mongoid/atomic/paths/embedded/many.rb +1 -1
  72. data/lib/mongoid/atomic/paths/embedded/one.rb +1 -1
  73. data/lib/mongoid/attributes.rb +2 -1
  74. data/lib/mongoid/attributes/nested.rb +10 -10
  75. data/lib/mongoid/attributes/processing.rb +2 -2
  76. data/lib/mongoid/attributes/readonly.rb +2 -4
  77. data/lib/mongoid/clients.rb +0 -2
  78. data/lib/mongoid/clients/options.rb +1 -1
  79. data/lib/mongoid/clients/storage_options.rb +0 -1
  80. data/lib/mongoid/composable.rb +3 -4
  81. data/lib/mongoid/config.rb +1 -0
  82. data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
  83. data/lib/mongoid/contextual/atomic.rb +3 -6
  84. data/lib/mongoid/contextual/map_reduce.rb +3 -7
  85. data/lib/mongoid/contextual/memory.rb +5 -10
  86. data/lib/mongoid/contextual/mongo.rb +10 -27
  87. data/lib/mongoid/copyable.rb +6 -6
  88. data/lib/mongoid/criteria.rb +1 -2
  89. data/lib/mongoid/criteria/includable.rb +14 -14
  90. data/lib/mongoid/criteria/modifiable.rb +8 -14
  91. data/lib/mongoid/criteria/queryable/mergeable.rb +1 -3
  92. data/lib/mongoid/criteria/queryable/pipeline.rb +10 -5
  93. data/lib/mongoid/criteria/queryable/selectable.rb +10 -34
  94. data/lib/mongoid/document.rb +6 -6
  95. data/lib/mongoid/errors.rb +3 -1
  96. data/lib/mongoid/errors/invalid_dependent_strategy.rb +32 -0
  97. data/lib/mongoid/errors/invalid_relation_option.rb +29 -0
  98. data/lib/mongoid/errors/unknown_model.rb +25 -0
  99. data/lib/mongoid/extensions/array.rb +5 -5
  100. data/lib/mongoid/extensions/big_decimal.rb +1 -1
  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/factory.rb +4 -3
  106. data/lib/mongoid/fields.rb +1 -1
  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/indexable.rb +8 -5
  111. data/lib/mongoid/interceptable.rb +5 -5
  112. data/lib/mongoid/matchable.rb +0 -3
  113. data/lib/mongoid/persistable.rb +4 -5
  114. data/lib/mongoid/persistable/creatable.rb +2 -4
  115. data/lib/mongoid/persistable/deletable.rb +9 -10
  116. data/lib/mongoid/persistable/destroyable.rb +5 -1
  117. data/lib/mongoid/persistable/incrementable.rb +1 -1
  118. data/lib/mongoid/persistable/logical.rb +1 -1
  119. data/lib/mongoid/persistable/settable.rb +5 -5
  120. data/lib/mongoid/persistable/updatable.rb +2 -2
  121. data/lib/mongoid/persistable/upsertable.rb +1 -2
  122. data/lib/mongoid/persistence_context.rb +4 -9
  123. data/lib/mongoid/query_cache.rb +18 -65
  124. data/lib/mongoid/railtie.rb +0 -17
  125. data/lib/mongoid/reloadable.rb +1 -1
  126. data/lib/mongoid/scopable.rb +3 -3
  127. data/lib/mongoid/serializable.rb +3 -3
  128. data/lib/mongoid/tasks/database.rb +2 -3
  129. data/lib/mongoid/threaded.rb +0 -74
  130. data/lib/mongoid/traversable.rb +2 -2
  131. data/lib/mongoid/validatable.rb +8 -8
  132. data/lib/mongoid/validatable/presence.rb +2 -2
  133. data/lib/mongoid/validatable/uniqueness.rb +4 -4
  134. data/lib/mongoid/version.rb +1 -1
  135. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +3 -4
  136. data/spec/app/models/animal.rb +2 -1
  137. data/spec/app/models/band.rb +0 -1
  138. data/spec/app/models/bomb.rb +1 -1
  139. data/spec/app/models/message.rb +1 -1
  140. data/spec/app/models/person.rb +5 -2
  141. data/spec/app/models/vertex.rb +6 -0
  142. data/spec/app/models/wiki_page.rb +1 -1
  143. data/spec/config/mongoid.yml +1 -0
  144. data/spec/mongoid/{relations → association}/accessors_spec.rb +1 -1
  145. data/spec/mongoid/{relations → association}/auto_save_spec.rb +60 -12
  146. data/spec/mongoid/{relations → association}/builders_spec.rb +1 -1
  147. data/spec/mongoid/association/constrainable_spec.rb +115 -0
  148. data/spec/mongoid/{relations → association}/counter_cache_spec.rb +1 -1
  149. data/spec/mongoid/association/depending_spec.rb +613 -0
  150. data/spec/mongoid/{relations → association}/eager_spec.rb +12 -12
  151. data/spec/mongoid/{relations → association/embedded}/cyclic_spec.rb +1 -1
  152. data/spec/mongoid/{relations → association}/embedded/dirty_spec.rb +0 -0
  153. data/spec/mongoid/{relations/bindings/embedded/in_spec.rb → association/embedded/embedded_in/binding_spec.rb} +13 -13
  154. data/spec/mongoid/{relations/builders/embedded/in_spec.rb → association/embedded/embedded_in/buildable_spec.rb} +9 -9
  155. data/spec/mongoid/{relations/embedded/in_spec.rb → association/embedded/embedded_in/proxy_spec.rb} +5 -77
  156. data/spec/mongoid/association/embedded/embedded_in_spec.rb +843 -0
  157. data/spec/mongoid/{relations/bindings/embedded/many_spec.rb → association/embedded/embeds_many/binding_spec.rb} +3 -3
  158. data/spec/mongoid/{relations/builders/embedded/many_spec.rb → association/embedded/embeds_many/buildable_spec.rb} +17 -45
  159. data/spec/mongoid/{relations/embedded/many_spec.rb → association/embedded/embeds_many/proxy_spec.rb} +140 -428
  160. data/spec/mongoid/association/embedded/embeds_many_spec.rb +852 -0
  161. data/spec/mongoid/{relations/bindings/embedded/one_spec.rb → association/embedded/embeds_one/binding_spec.rb} +4 -4
  162. data/spec/mongoid/{relations/builders/embedded/one_spec.rb → association/embedded/embeds_one/buildable_spec.rb} +14 -34
  163. data/spec/mongoid/{relations/embedded/one_spec.rb → association/embedded/embeds_one/proxy_spec.rb} +39 -84
  164. data/spec/mongoid/association/embedded/embeds_one_spec.rb +908 -0
  165. data/spec/mongoid/{relations → association}/macros_spec.rb +148 -93
  166. data/spec/mongoid/{relations/builders/nested_attributes → association/nested}/many_spec.rb +16 -19
  167. data/spec/mongoid/{relations/builders/nested_attributes → association/nested}/one_spec.rb +17 -20
  168. data/spec/mongoid/association/options_spec.rb +1321 -0
  169. data/spec/mongoid/{relations → association}/polymorphic_spec.rb +7 -34
  170. data/spec/mongoid/{relations/bindings/referenced/in_spec.rb → association/referenced/belongs_to/binding_spec.rb} +7 -7
  171. data/spec/mongoid/{relations/builders/referenced/in_spec.rb → association/referenced/belongs_to/buildable_spec.rb} +46 -79
  172. data/spec/mongoid/{relations/eager/belongs_to_spec.rb → association/referenced/belongs_to/eager_spec.rb} +9 -9
  173. data/spec/mongoid/{relations/referenced/in_spec.rb → association/referenced/belongs_to/proxy_spec.rb} +57 -91
  174. data/spec/mongoid/association/referenced/belongs_to_spec.rb +1963 -0
  175. data/spec/mongoid/{relations/bindings/referenced/many_to_many_spec.rb → association/referenced/has_and_belongs_to_many/binding_spec.rb} +5 -5
  176. data/spec/mongoid/association/referenced/has_and_belongs_to_many/buildable_spec.rb +121 -0
  177. data/spec/mongoid/{relations/eager/has_and_belongs_to_many_spec.rb → association/referenced/has_and_belongs_to_many/eager_spec.rb} +5 -5
  178. data/spec/mongoid/{relations/referenced/many_to_many_spec.rb → association/referenced/has_and_belongs_to_many/proxy_spec.rb} +107 -98
  179. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +1027 -0
  180. data/spec/mongoid/{relations/bindings/referenced/many_spec.rb → association/referenced/has_many/binding_spec.rb} +5 -5
  181. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +119 -0
  182. data/spec/mongoid/{relations/eager/has_many_spec.rb → association/referenced/has_many/eager_spec.rb} +11 -11
  183. data/spec/mongoid/{relations/targets → association/referenced/has_many}/enumerable_spec.rb +1 -109
  184. data/spec/mongoid/{relations/referenced/many_spec.rb → association/referenced/has_many/proxy_spec.rb} +28 -93
  185. data/spec/mongoid/association/referenced/has_many_spec.rb +1225 -0
  186. data/spec/mongoid/{relations/bindings/referenced/one_spec.rb → association/referenced/has_one/binding_spec.rb} +4 -4
  187. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +113 -0
  188. data/spec/mongoid/{relations/eager/has_one_spec.rb → association/referenced/has_one/eager_spec.rb} +10 -10
  189. data/spec/mongoid/{relations/referenced/one_spec.rb → association/referenced/has_one/proxy_spec.rb} +9 -109
  190. data/spec/mongoid/association/referenced/has_one_spec.rb +1244 -0
  191. data/spec/mongoid/{relations → association}/reflections_spec.rb +1 -12
  192. data/spec/mongoid/{relations/synchronization_spec.rb → association/syncable_spec.rb} +4 -2
  193. data/spec/mongoid/{relations → association}/touchable_spec.rb +19 -1
  194. data/spec/mongoid/{relations_spec.rb → association_spec.rb} +1 -1
  195. data/spec/mongoid/atomic/modifiers_spec.rb +17 -17
  196. data/spec/mongoid/atomic_spec.rb +17 -17
  197. data/spec/mongoid/attributes/nested_spec.rb +14 -12
  198. data/spec/mongoid/attributes/readonly_spec.rb +80 -125
  199. data/spec/mongoid/clients/factory_spec.rb +28 -52
  200. data/spec/mongoid/clients/options_spec.rb +65 -69
  201. data/spec/mongoid/config_spec.rb +24 -0
  202. data/spec/mongoid/contextual/geo_near_spec.rb +0 -1
  203. data/spec/mongoid/contextual/mongo_spec.rb +4 -112
  204. data/spec/mongoid/criteria/modifiable_spec.rb +183 -60
  205. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +3 -3
  206. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +12 -0
  207. data/spec/mongoid/criteria/queryable/selectable_spec.rb +6 -74
  208. data/spec/mongoid/criteria/queryable/selector_spec.rb +2 -2
  209. data/spec/mongoid/criteria/scopable_spec.rb +0 -81
  210. data/spec/mongoid/criteria_spec.rb +16 -19
  211. data/spec/mongoid/document_spec.rb +2 -56
  212. data/spec/mongoid/extensions/array_spec.rb +11 -15
  213. data/spec/mongoid/extensions/big_decimal_spec.rb +9 -9
  214. data/spec/mongoid/extensions/object_spec.rb +7 -11
  215. data/spec/mongoid/extensions/range_spec.rb +7 -0
  216. data/spec/mongoid/extensions/regexp_spec.rb +0 -23
  217. data/spec/mongoid/extensions/string_spec.rb +7 -35
  218. data/spec/mongoid/factory_spec.rb +18 -11
  219. data/spec/mongoid/fields/foreign_key_spec.rb +24 -32
  220. data/spec/mongoid/fields_spec.rb +2 -2
  221. data/spec/mongoid/findable_spec.rb +1 -1
  222. data/spec/mongoid/indexable_spec.rb +18 -8
  223. data/spec/mongoid/interceptable_spec.rb +21 -2
  224. data/spec/mongoid/matchable_spec.rb +1 -26
  225. data/spec/mongoid/persistable/deletable_spec.rb +0 -19
  226. data/spec/mongoid/persistable/destroyable_spec.rb +0 -19
  227. data/spec/mongoid/persistable/incrementable_spec.rb +6 -6
  228. data/spec/mongoid/persistable/savable_spec.rb +3 -3
  229. data/spec/mongoid/persistable/settable_spec.rb +1 -35
  230. data/spec/mongoid/persistable/updatable_spec.rb +2 -2
  231. data/spec/mongoid/persistable_spec.rb +16 -16
  232. data/spec/mongoid/persistence_context_spec.rb +0 -14
  233. data/spec/mongoid/positional_spec.rb +10 -10
  234. data/spec/mongoid/query_cache_spec.rb +18 -87
  235. data/spec/mongoid/relations/proxy_spec.rb +124 -124
  236. data/spec/mongoid/scopable_spec.rb +0 -13
  237. data/spec/mongoid/threaded_spec.rb +0 -68
  238. data/spec/mongoid/validatable/associated_spec.rb +1 -1
  239. data/spec/mongoid/validatable/presence_spec.rb +7 -6
  240. data/spec/mongoid/validatable_spec.rb +1 -1
  241. data/spec/spec_helper.rb +7 -83
  242. metadata +586 -611
  243. metadata.gz.sig +2 -5
  244. data/lib/mongoid/clients/sessions.rb +0 -113
  245. data/lib/mongoid/errors/invalid_session_use.rb +0 -24
  246. data/lib/mongoid/matchable/nor.rb +0 -37
  247. data/lib/mongoid/railties/controller_runtime.rb +0 -86
  248. data/lib/mongoid/relations.rb +0 -148
  249. data/lib/mongoid/relations/accessors.rb +0 -267
  250. data/lib/mongoid/relations/auto_save.rb +0 -94
  251. data/lib/mongoid/relations/bindings.rb +0 -9
  252. data/lib/mongoid/relations/bindings/embedded/in.rb +0 -59
  253. data/lib/mongoid/relations/bindings/referenced/in.rb +0 -65
  254. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +0 -70
  255. data/lib/mongoid/relations/builder.rb +0 -57
  256. data/lib/mongoid/relations/builders.rb +0 -106
  257. data/lib/mongoid/relations/builders/nested_attributes/many.rb +0 -199
  258. data/lib/mongoid/relations/builders/referenced/in.rb +0 -26
  259. data/lib/mongoid/relations/builders/referenced/many.rb +0 -26
  260. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +0 -39
  261. data/lib/mongoid/relations/builders/referenced/one.rb +0 -26
  262. data/lib/mongoid/relations/cascading.rb +0 -56
  263. data/lib/mongoid/relations/cascading/delete.rb +0 -44
  264. data/lib/mongoid/relations/cascading/destroy.rb +0 -43
  265. data/lib/mongoid/relations/cascading/nullify.rb +0 -35
  266. data/lib/mongoid/relations/cascading/restrict.rb +0 -39
  267. data/lib/mongoid/relations/conversions.rb +0 -34
  268. data/lib/mongoid/relations/counter_cache.rb +0 -160
  269. data/lib/mongoid/relations/cyclic.rb +0 -107
  270. data/lib/mongoid/relations/eager/base.rb +0 -153
  271. data/lib/mongoid/relations/eager/belongs_to.rb +0 -31
  272. data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +0 -47
  273. data/lib/mongoid/relations/eager/has_many.rb +0 -38
  274. data/lib/mongoid/relations/eager/has_one.rb +0 -30
  275. data/lib/mongoid/relations/embedded/in.rb +0 -241
  276. data/lib/mongoid/relations/embedded/many.rb +0 -683
  277. data/lib/mongoid/relations/embedded/one.rb +0 -235
  278. data/lib/mongoid/relations/macros.rb +0 -367
  279. data/lib/mongoid/relations/metadata.rb +0 -1179
  280. data/lib/mongoid/relations/nested_builder.rb +0 -74
  281. data/lib/mongoid/relations/options.rb +0 -49
  282. data/lib/mongoid/relations/polymorphic.rb +0 -39
  283. data/lib/mongoid/relations/referenced/in.rb +0 -304
  284. data/lib/mongoid/relations/referenced/many.rb +0 -812
  285. data/lib/mongoid/relations/referenced/many_to_many.rb +0 -479
  286. data/lib/mongoid/relations/referenced/one.rb +0 -290
  287. data/lib/mongoid/relations/synchronization.rb +0 -169
  288. data/lib/mongoid/relations/targets.rb +0 -2
  289. data/lib/mongoid/relations/targets/enumerable.rb +0 -493
  290. data/lib/mongoid/relations/touchable.rb +0 -97
  291. data/spec/app/models/array_field.rb +0 -7
  292. data/spec/app/models/delegating_patient.rb +0 -16
  293. data/spec/integration/document_spec.rb +0 -22
  294. data/spec/mongoid/clients/sessions_spec.rb +0 -334
  295. data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +0 -184
  296. data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +0 -201
  297. data/spec/mongoid/matchable/nor_spec.rb +0 -209
  298. data/spec/mongoid/relations/builders/referenced/many_spec.rb +0 -137
  299. data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +0 -178
  300. data/spec/mongoid/relations/builders/referenced/one_spec.rb +0 -111
  301. data/spec/mongoid/relations/cascading/delete_spec.rb +0 -101
  302. data/spec/mongoid/relations/cascading/destroy_spec.rb +0 -47
  303. data/spec/mongoid/relations/cascading/nullify_spec.rb +0 -32
  304. data/spec/mongoid/relations/cascading/restrict_spec.rb +0 -68
  305. data/spec/mongoid/relations/cascading_spec.rb +0 -355
  306. data/spec/mongoid/relations/constraint_spec.rb +0 -75
  307. data/spec/mongoid/relations/conversions_spec.rb +0 -128
  308. data/spec/mongoid/relations/metadata_spec.rb +0 -1985
  309. data/spec/mongoid/relations/options_spec.rb +0 -35
  310. data/spec/rails/controller_extension/controller_runtime_spec.rb +0 -110
  311. data/spec/support/cluster_config.rb +0 -158
  312. data/spec/support/constraints.rb +0 -101
  313. data/spec/support/macros.rb +0 -20
  314. data/spec/support/session_registry.rb +0 -50
  315. data/spec/support/spec_config.rb +0 -42
@@ -0,0 +1,577 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Association
4
+ module Referenced
5
+ class HasMany
6
+
7
+ # This class defines the behaviour for all relations that are a
8
+ # one-to-many between documents in different collections.
9
+ class Proxy < Association::Many
10
+
11
+ delegate :count, to: :criteria
12
+ delegate :first, :in_memory, :last, :reset, :uniq, to: :_target
13
+
14
+ # Appends a document or array of documents to the relation. Will set
15
+ # the parent and update the index in the process.
16
+ #
17
+ # @example Append a document.
18
+ # person.posts << post
19
+ #
20
+ # @example Push a document.
21
+ # person.posts.push(post)
22
+ #
23
+ # @example Concat with other documents.
24
+ # person.posts.concat([ post_one, post_two ])
25
+ #
26
+ # @param [ Document, Array<Document> ] args Any number of documents.
27
+ #
28
+ # @return [ Array<Document> ] The loaded docs.
29
+ #
30
+ # @since 2.0.0.beta.1
31
+ def <<(*args)
32
+ docs = args.flatten
33
+ return concat(docs) if docs.size > 1
34
+ if doc = docs.first
35
+ append(doc)
36
+ doc.save if persistable? && !_assigning? && !doc.validated?
37
+ end
38
+ 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
+ docs, inserts = [], []
56
+ documents.each do |doc|
57
+ next unless doc
58
+ append(doc)
59
+ save_or_delay(doc, docs, inserts) if persistable?
60
+ end
61
+ persist_delayed(docs, inserts)
62
+ self
63
+ end
64
+
65
+ # Build a new document from the attributes and append it to this
66
+ # relation without saving.
67
+ #
68
+ # @example Build a new document on the relation.
69
+ # person.posts.build(:title => "A new post")
70
+ #
71
+ # @param [ Hash ] attributes The attributes of the new document.
72
+ # @param [ Class ] type The optional subclass to build.
73
+ #
74
+ # @return [ Document ] The new document.
75
+ #
76
+ # @since 2.0.0.beta.1
77
+ def build(attributes = {}, type = nil)
78
+ doc = Factory.build(type || klass, attributes)
79
+ append(doc)
80
+ doc.apply_post_processed_defaults
81
+ yield(doc) if block_given?
82
+ doc.run_callbacks(:build) { doc }
83
+ doc
84
+ end
85
+
86
+ alias :new :build
87
+
88
+ # Delete the document from the relation. This will set the foreign key
89
+ # on the document to nil. If the dependent options on the relation are
90
+ # :delete or :destroy the appropriate removal will occur.
91
+ #
92
+ # @example Delete the document.
93
+ # person.posts.delete(post)
94
+ #
95
+ # @param [ Document ] document The document to remove.
96
+ #
97
+ # @return [ Document ] The matching document.
98
+ #
99
+ # @since 2.1.0
100
+ def delete(document)
101
+ execute_callback :before_remove, document
102
+ _target.delete(document) do |doc|
103
+ if doc
104
+ unbind_one(doc)
105
+ cascade!(doc) if !_assigning?
106
+ end
107
+ execute_callback :after_remove, doc
108
+ end
109
+ end
110
+
111
+ # Deletes all related documents from the database given the supplied
112
+ # conditions.
113
+ #
114
+ # @example Delete all documents in the relation.
115
+ # person.posts.delete_all
116
+ #
117
+ # @example Conditonally delete all documents in the relation.
118
+ # person.posts.delete_all({ :title => "Testing" })
119
+ #
120
+ # @param [ Hash ] conditions Optional conditions to delete with.
121
+ #
122
+ # @return [ Integer ] The number of documents deleted.
123
+ #
124
+ # @since 2.0.0.beta.1
125
+ def delete_all(conditions = nil)
126
+ remove_all(conditions, :delete_all)
127
+ end
128
+
129
+ # Destroys all related documents from the database given the supplied
130
+ # conditions.
131
+ #
132
+ # @example Destroy all documents in the relation.
133
+ # person.posts.destroy_all
134
+ #
135
+ # @example Conditonally destroy all documents in the relation.
136
+ # person.posts.destroy_all({ :title => "Testing" })
137
+ #
138
+ # @param [ Hash ] conditions Optional conditions to destroy with.
139
+ #
140
+ # @return [ Integer ] The number of documents destroyd.
141
+ #
142
+ # @since 2.0.0.beta.1
143
+ def destroy_all(conditions = nil)
144
+ remove_all(conditions, :destroy_all)
145
+ end
146
+
147
+ # Iterate over each document in the relation and yield to the provided
148
+ # block.
149
+ #
150
+ # @note This will load the entire relation into memory.
151
+ #
152
+ # @example Iterate over the documents.
153
+ # person.posts.each do |post|
154
+ # post.save
155
+ # end
156
+ #
157
+ # @return [ Array<Document> ] The loaded docs.
158
+ #
159
+ # @since 2.1.0
160
+ def each
161
+ if block_given?
162
+ _target.each { |doc| yield(doc) }
163
+ else
164
+ to_enum
165
+ end
166
+ end
167
+
168
+ # Determine if any documents in this relation exist in the database.
169
+ #
170
+ # @example Are there persisted documents?
171
+ # person.posts.exists?
172
+ #
173
+ # @return [ true, false ] True is persisted documents exist, false if not.
174
+ def exists?
175
+ criteria.exists?
176
+ end
177
+
178
+ # Find the matchind document on the association, either based on id or
179
+ # conditions.
180
+ #
181
+ # @example Find by an id.
182
+ # person.posts.find(BSON::ObjectId.new)
183
+ #
184
+ # @example Find by multiple ids.
185
+ # person.posts.find([ BSON::ObjectId.new, BSON::ObjectId.new ])
186
+ #
187
+ # @note This will keep matching documents in memory for iteration
188
+ # later.
189
+ #
190
+ # @param [ BSON::ObjectId, Array<BSON::ObjectId> ] args The ids.
191
+ #
192
+ # @return [ Document, Criteria ] The matching document(s).
193
+ #
194
+ # @since 2.0.0.beta.1
195
+ def find(*args)
196
+ matching = criteria.find(*args)
197
+ Array(matching).each { |doc| _target.push(doc) }
198
+ matching
199
+ end
200
+
201
+ # Instantiate a new references_many relation. Will set the foreign key
202
+ # and the base on the inverse object.
203
+ #
204
+ # @example Create the new relation.
205
+ # Referenced::Many.new(base, target, association)
206
+ #
207
+ # @param [ Document ] base The document this relation hangs off of.
208
+ # @param [ Array<Document> ] target The target of the relation.
209
+ # @param [ Association ] association The association metadata.
210
+ #
211
+ # @since 2.0.0.beta.1
212
+ def initialize(base, target, association)
213
+ init(base, HasMany::Targets::Enumerable.new(target), association) do
214
+ raise_mixed if klass.embedded? && !klass.cyclic?
215
+ end
216
+ end
217
+
218
+ # Removes all associations between the base document and the target
219
+ # documents by deleting the foreign keys and the references, orphaning
220
+ # the target documents in the process.
221
+ #
222
+ # @example Nullify the relation.
223
+ # person.posts.nullify
224
+ #
225
+ # @since 2.0.0.rc.1
226
+ def nullify
227
+ criteria.update_all(foreign_key => nil)
228
+ _target.clear do |doc|
229
+ unbind_one(doc)
230
+ doc.changed_attributes.delete(foreign_key)
231
+ end
232
+ end
233
+
234
+ alias :nullify_all :nullify
235
+
236
+ # Clear the relation. Will delete the documents from the db if they are
237
+ # already persisted.
238
+ #
239
+ # @example Clear the relation.
240
+ # person.posts.clear
241
+ #
242
+ # @return [ Many ] The relation emptied.
243
+ #
244
+ # @since 2.0.0.beta.1
245
+ def purge
246
+ unless _association.destructive?
247
+ nullify
248
+ else
249
+ after_remove_error = nil
250
+ criteria.delete_all
251
+ many = _target.clear do |doc|
252
+ execute_callback :before_remove, doc
253
+ unbind_one(doc)
254
+ doc.destroyed = true
255
+ begin
256
+ execute_callback :after_remove, doc
257
+ rescue => e
258
+ after_remove_error = e
259
+ end
260
+ end
261
+ raise after_remove_error if after_remove_error
262
+ many
263
+ end
264
+ end
265
+
266
+ alias :clear :purge
267
+
268
+ # Substitutes the supplied target documents for the existing documents
269
+ # in the relation. If the new target is nil, perform the necessary
270
+ # deletion.
271
+ #
272
+ # @example Replace the relation.
273
+ # person.posts.substitute([ new_post ])
274
+ #
275
+ # @param [ Array<Document> ] replacement The replacement target.
276
+ #
277
+ # @return [ Many ] The relation.
278
+ #
279
+ # @since 2.0.0.rc.1
280
+ def substitute(replacement)
281
+ if replacement
282
+ new_docs, docs = replacement.compact, []
283
+ new_ids = new_docs.map { |doc| doc._id }
284
+ remove_not_in(new_ids)
285
+ new_docs.each do |doc|
286
+ docs.push(doc) if doc.send(foreign_key) != _base._id
287
+ end
288
+ concat(docs)
289
+ else
290
+ purge
291
+ end
292
+ self
293
+ end
294
+
295
+ # Get a criteria for the documents without the default scoping
296
+ # applied.
297
+ #
298
+ # @example Get the unscoped criteria.
299
+ # person.posts.unscoped
300
+ #
301
+ # @return [ Criteria ] The unscoped criteria.
302
+ #
303
+ # @since 2.4.0
304
+ def unscoped
305
+ klass.unscoped.where(foreign_key => _base._id)
306
+ end
307
+
308
+ private
309
+
310
+ # Appends the document to the target array, updating the index on the
311
+ # document at the same time.
312
+ #
313
+ # @example Append the document to the relation.
314
+ # relation.append(document)
315
+ #
316
+ # @param [ Document ] document The document to append to the target.
317
+ #
318
+ # @since 2.0.0.rc.1
319
+ def append(document)
320
+ with_add_callbacks(document, already_related?(document)) do
321
+ _target.push(document)
322
+ characterize_one(document)
323
+ bind_one(document)
324
+ end
325
+ end
326
+
327
+ # Execute before/after add callbacks around the block unless the objects
328
+ # already have a persisted relation.
329
+ #
330
+ # @example Execute before/after add callbacks around the block.
331
+ # relation.with_add_callbacks(document, false)
332
+ #
333
+ # @param [ Document ] document The document to append to the target.
334
+ # @param [ true, false ] already_related Whether the document is already related
335
+ # to the target.
336
+ #
337
+ # @since 5.1.0
338
+ def with_add_callbacks(document, already_related)
339
+ execute_callback :before_add, document unless already_related
340
+ yield
341
+ execute_callback :after_add, document unless already_related
342
+ end
343
+
344
+ # Whether the document and the base already have a persisted relation.
345
+ #
346
+ # @example Is the document already related to the base.
347
+ # relation.already_related?(document)
348
+ #
349
+ # @param [ Document ] document The document to possibly append to the target.
350
+ #
351
+ # @return [ true, false ] Whether the document is already related to the base and the
352
+ # relation is persisted.
353
+ #
354
+ # @since 5.1.0
355
+ def already_related?(document)
356
+ document.persisted? &&
357
+ document._association &&
358
+ document.respond_to?(document._association.foreign_key) &&
359
+ document.__send__(document._association.foreign_key) == _base.id
360
+ end
361
+
362
+ # Instantiate the binding associated with this relation.
363
+ #
364
+ # @example Get the binding.
365
+ # relation.binding([ address ])
366
+ #
367
+ # @return [ Binding ] The binding.
368
+ #
369
+ # @since 2.0.0.rc.1
370
+ def binding
371
+ HasMany::Binding.new(_base, _target, _association)
372
+ end
373
+
374
+ # Get the collection of the relation in question.
375
+ #
376
+ # @example Get the collection of the relation.
377
+ # relation.collection
378
+ #
379
+ # @return [ Collection ] The collection of the relation.
380
+ #
381
+ # @since 2.0.2
382
+ def collection
383
+ klass.collection
384
+ end
385
+
386
+ # Returns the criteria object for the target class with its documents set
387
+ # to target.
388
+ #
389
+ # @example Get a criteria for the relation.
390
+ # relation.criteria
391
+ #
392
+ # @return [ Criteria ] A new criteria.
393
+ #
394
+ # @since 2.0.0.beta.1
395
+ def criteria
396
+ @criteria ||= _association.criteria(_base)
397
+ end
398
+
399
+ # Perform the necessary cascade operations for documents that just got
400
+ # deleted or nullified.
401
+ #
402
+ # @example Cascade the change.
403
+ # relation.cascade!(document)
404
+ #
405
+ # @param [ Document ] document The document to cascade on.
406
+ #
407
+ # @return [ true, false ] If the association is destructive.
408
+ #
409
+ # @since 2.1.0
410
+ def cascade!(document)
411
+ if persistable?
412
+ case _association.dependent
413
+ when :delete_all
414
+ document.delete
415
+ when :destroy
416
+ document.destroy
417
+ else
418
+ document.save
419
+ end
420
+ end
421
+ end
422
+
423
+ # If the target array does not respond to the supplied method then try to
424
+ # find a named scope or criteria on the class and send the call there.
425
+ #
426
+ # If the method exists on the array, use the default proxy behavior.
427
+ #
428
+ # @param [ Symbol, String ] name The name of the method.
429
+ # @param [ Array ] args The method args
430
+ # @param [ Proc ] block Optional block to pass.
431
+ #
432
+ # @return [ Criteria, Object ] A Criteria or return value from the target.
433
+ #
434
+ # @since 2.0.0.beta.1
435
+ def method_missing(name, *args, &block)
436
+ if _target.respond_to?(name)
437
+ _target.send(name, *args, &block)
438
+ else
439
+ klass.send(:with_scope, criteria) do
440
+ criteria.public_send(name, *args, &block)
441
+ end
442
+ end
443
+ end
444
+
445
+ # Persist all the delayed batch inserts.
446
+ #
447
+ # @api private
448
+ #
449
+ # @example Persist the delayed batch inserts.
450
+ # relation.persist_delayed([ doc ])
451
+ #
452
+ # @param [ Array<Document> ] docs The delayed inserts.
453
+ # @param [ Array<Hash> ] inserts The raw insert document.
454
+ #
455
+ # @since 3.0.0
456
+ def persist_delayed(docs, inserts)
457
+ unless docs.empty?
458
+ collection.insert_many(inserts)
459
+ docs.each do |doc|
460
+ doc.new_record = false
461
+ doc.run_after_callbacks(:create, :save)
462
+ doc.post_persist
463
+ end
464
+ end
465
+ end
466
+
467
+ # Are we able to persist this relation?
468
+ #
469
+ # @example Can we persist the relation?
470
+ # relation.persistable?
471
+ #
472
+ # @return [ true, false ] If the relation is persistable.
473
+ #
474
+ # @since 2.1.0
475
+ def persistable?
476
+ !_binding? && (_creating? || _base.persisted? && !_building?)
477
+ end
478
+
479
+ # Deletes all related documents from the database given the supplied
480
+ # conditions.
481
+ #
482
+ # @example Delete all documents in the relation.
483
+ # person.posts.delete_all
484
+ #
485
+ # @example Conditonally delete all documents in the relation.
486
+ # person.posts.delete_all({ :title => "Testing" })
487
+ #
488
+ # @param [ Hash ] conditions Optional conditions to delete with.
489
+ # @param [ Symbol ] method The deletion method to call.
490
+ #
491
+ # @return [ Integer ] The number of documents deleted.
492
+ #
493
+ # @since 2.1.0
494
+ def remove_all(conditions = nil, method = :delete_all)
495
+ selector = conditions || {}
496
+ removed = klass.send(method, selector.merge!(criteria.selector))
497
+ _target.delete_if do |doc|
498
+ if doc._matches?(selector)
499
+ unbind_one(doc) and true
500
+ end
501
+ end
502
+ removed
503
+ end
504
+
505
+ # Remove all the documents in the proxy that do not have the provided
506
+ # ids.
507
+ #
508
+ # @example Remove all documents without the ids.
509
+ # proxy.remove_not_in([ id ])
510
+ #
511
+ # @param [ Array<Object> ] ids The ids.
512
+ #
513
+ # @since 2.4.0
514
+ def remove_not_in(ids)
515
+ removed = criteria.not_in(_id: ids)
516
+ if _association.destructive?
517
+ removed.delete_all
518
+ else
519
+ removed.update_all(foreign_key => nil)
520
+ end
521
+ in_memory.each do |doc|
522
+ if !ids.include?(doc._id)
523
+ unbind_one(doc)
524
+ _target.delete(doc)
525
+ if _association.destructive?
526
+ doc.destroyed = true
527
+ end
528
+ end
529
+ end
530
+ end
531
+
532
+ # Save a persisted document immediately or delay a new document for
533
+ # batch insert.
534
+ #
535
+ # @api private
536
+ #
537
+ # @example Save or delay the document.
538
+ # relation.save_or_delay(doc, [])
539
+ #
540
+ # @param [ Document ] doc The document.
541
+ # @param [ Array<Document> ] inserts The inserts.
542
+ #
543
+ # @since 3.0.0
544
+ def save_or_delay(doc, docs, inserts)
545
+ if doc.new_record? && doc.valid?(:create)
546
+ doc.run_before_callbacks(:save, :create)
547
+ docs.push(doc)
548
+ inserts.push(doc.send(:as_attributes))
549
+ else
550
+ doc.save
551
+ end
552
+ end
553
+
554
+ class << self
555
+
556
+ def eager_loader(association, docs)
557
+ Eager.new(association, docs)
558
+ end
559
+
560
+ # Returns true if the relation is an embedded one. In this case
561
+ # always false.
562
+ #
563
+ # @example Is this relation embedded?
564
+ # Referenced::Many.embedded?
565
+ #
566
+ # @return [ false ] Always false.
567
+ #
568
+ # @since 2.0.0.rc.1
569
+ def embedded?
570
+ false
571
+ end
572
+ end
573
+ end
574
+ end
575
+ end
576
+ end
577
+ end