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
@@ -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
@@ -0,0 +1,479 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Association
4
+ module Referenced
5
+ class HasMany
6
+ module Targets
7
+
8
+ # This class is the wrapper for all relational associations that have a
9
+ # target that can be a criteria or array of _loaded documents. This
10
+ # handles both cases or a combination of the two.
11
+ class Enumerable
12
+ include ::Enumerable
13
+
14
+ # The three main instance variables are collections of documents.
15
+ #
16
+ # @attribute [rw] _added Documents that have been appended.
17
+ # @attribute [rw] _loaded Persisted documents that have been _loaded.
18
+ # @attribute [rw] _unloaded A criteria representing persisted docs.
19
+ attr_accessor :_added, :_loaded, :_unloaded
20
+
21
+ delegate :is_a?, :kind_of?, to: []
22
+
23
+ # Check if the enumerable is equal to the other object.
24
+ #
25
+ # @example Check equality.
26
+ # enumerable == []
27
+ #
28
+ # @param [ Enumerable ] other The other enumerable.
29
+ #
30
+ # @return [ true, false ] If the objects are equal.
31
+ #
32
+ # @since 2.1.0
33
+ def ==(other)
34
+ return false unless other.respond_to?(:entries)
35
+ entries == other.entries
36
+ end
37
+
38
+ # Check equality of the enumerable against the provided object for case
39
+ # statements.
40
+ #
41
+ # @example Check case equality.
42
+ # enumerable === Array
43
+ #
44
+ # @param [ Object ] other The object to check.
45
+ #
46
+ # @return [ true, false ] If the objects are equal in a case.
47
+ #
48
+ # @since 3.1.4
49
+ def ===(other)
50
+ other.class == Class ? (Array == other || Enumerable == other) : self == other
51
+ end
52
+
53
+ # Append a document to the enumerable.
54
+ #
55
+ # @example Append the document.
56
+ # enumerable << document
57
+ #
58
+ # @param [ Document ] document The document to append.
59
+ #
60
+ # @return [ Document ] The document.
61
+ #
62
+ # @since 2.1.0
63
+ def <<(document)
64
+ _added[document._id] = document
65
+ self
66
+ end
67
+
68
+ alias :push :<<
69
+
70
+ # Clears out all the documents in this enumerable. If passed a block it
71
+ # will yield to each document that is in memory.
72
+ #
73
+ # @example Clear out the enumerable.
74
+ # enumerable.clear
75
+ #
76
+ # @example Clear out the enumerable with a block.
77
+ # enumerable.clear do |doc|
78
+ # doc.unbind
79
+ # end
80
+ #
81
+ # @return [ Array<Document> ] The cleared out _added docs.
82
+ #
83
+ # @since 2.1.0
84
+ def clear
85
+ if block_given?
86
+ in_memory { |doc| yield(doc) }
87
+ end
88
+ _loaded.clear and _added.clear
89
+ end
90
+
91
+ # Clones each document in the enumerable.
92
+ #
93
+ # @note This loads all documents into memory.
94
+ #
95
+ # @example Clone the enumerable.
96
+ # enumerable.clone
97
+ #
98
+ # @return [ Array<Document> ] An array clone of the enumerable.
99
+ #
100
+ # @since 2.1.6
101
+ def clone
102
+ collect { |doc| doc.clone }
103
+ end
104
+
105
+ # Delete the supplied document from the enumerable.
106
+ #
107
+ # @example Delete the document.
108
+ # enumerable.delete(document)
109
+ #
110
+ # @param [ Document ] document The document to delete.
111
+ #
112
+ # @return [ Document ] The deleted document.
113
+ #
114
+ # @since 2.1.0
115
+ def delete(document)
116
+ doc = (_loaded.delete(document._id) || _added.delete(document._id))
117
+ unless doc
118
+ if _unloaded && _unloaded.where(_id: document._id).exists?
119
+ yield(document) if block_given?
120
+ return document
121
+ end
122
+ end
123
+ yield(doc) if block_given?
124
+ doc
125
+ end
126
+
127
+ # Deletes every document in the enumerable for where the block returns
128
+ # true.
129
+ #
130
+ # @note This operation loads all documents from the database.
131
+ #
132
+ # @example Delete all matching documents.
133
+ # enumerable.delete_if do |doc|
134
+ # dod._id == _id
135
+ # end
136
+ #
137
+ # @return [ Array<Document> ] The remaining docs.
138
+ #
139
+ # @since 2.1.0
140
+ def delete_if(&block)
141
+ load_all!
142
+ deleted = in_memory.select(&block)
143
+ deleted.each do |doc|
144
+ _loaded.delete(doc._id)
145
+ _added.delete(doc._id)
146
+ end
147
+ self
148
+ end
149
+
150
+ # Iterating over this enumerable has to handle a few different
151
+ # scenarios.
152
+ #
153
+ # If the enumerable has its criteria _loaded into memory then it yields
154
+ # to all the _loaded docs and all the _added docs.
155
+ #
156
+ # If the enumerable has not _loaded the criteria then it iterates over
157
+ # the cursor while loading the documents and then iterates over the
158
+ # _added docs.
159
+ #
160
+ # If no block is passed then it returns an enumerator containing all
161
+ # docs.
162
+ #
163
+ # @example Iterate over the enumerable.
164
+ # enumerable.each do |doc|
165
+ # puts doc
166
+ # end
167
+ #
168
+ # @example return an enumerator containing all the docs
169
+ #
170
+ # a = enumerable.each
171
+ #
172
+ # @return [ true ] That the enumerable is now _loaded.
173
+ #
174
+ # @since 2.1.0
175
+ def each
176
+ unless block_given?
177
+ return to_enum
178
+ end
179
+ if _loaded?
180
+ _loaded.each_pair do |id, doc|
181
+ document = _added.delete(doc._id) || doc
182
+ yield(document)
183
+ end
184
+ else
185
+ unloaded_documents.each do |doc|
186
+ document = _added.delete(doc._id) || _loaded.delete(doc._id) || doc
187
+ _loaded[document._id] = document
188
+ yield(document)
189
+ end
190
+ end
191
+ _added.each_pair do |id, doc|
192
+ yield(doc)
193
+ end
194
+ @executed = true
195
+ end
196
+
197
+ # Is the enumerable empty? Will determine if the count is zero based on
198
+ # whether or not it is _loaded.
199
+ #
200
+ # @example Is the enumerable empty?
201
+ # enumerable.empty?
202
+ #
203
+ # @return [ true, false ] If the enumerable is empty.
204
+ #
205
+ # @since 2.1.0
206
+ def empty?
207
+ if _loaded?
208
+ in_memory.count == 0
209
+ else
210
+ _unloaded.count + _added.count == 0
211
+ end
212
+ end
213
+
214
+ # Get the first document in the enumerable. Will check the persisted
215
+ # documents first. Does not load the entire enumerable.
216
+ #
217
+ # @example Get the first document.
218
+ # enumerable.first
219
+ #
220
+ # @return [ Document ] The first document found.
221
+ #
222
+ # @since 2.1.0
223
+ def first
224
+ _loaded.try(:values).try(:first) ||
225
+ _added[(ul = _unloaded.try(:first)).try(:id)] ||
226
+ ul ||
227
+ _added.values.try(:first)
228
+ end
229
+
230
+ # Initialize the new enumerable either with a criteria or an array.
231
+ #
232
+ # @example Initialize the enumerable with a criteria.
233
+ # Enumberable.new(Post.where(:person_id => id))
234
+ #
235
+ # @example Initialize the enumerable with an array.
236
+ # Enumerable.new([ post ])
237
+ #
238
+ # @param [ Criteria, Array<Document> ] target The wrapped object.
239
+ #
240
+ # @since 2.1.0
241
+ def initialize(target)
242
+ if target.is_a?(Criteria)
243
+ @_added, @executed, @_loaded, @_unloaded = {}, false, {}, target
244
+ else
245
+ @_added, @executed = {}, true
246
+ @_loaded = target.inject({}) do |_target, doc|
247
+ _target[doc._id] = doc if doc
248
+ _target
249
+ end
250
+ end
251
+ end
252
+
253
+ # Does the target include the provided document?
254
+ #
255
+ # @example Does the target include the document?
256
+ # enumerable.include?(document)
257
+ #
258
+ # @param [ Document ] doc The document to check.
259
+ #
260
+ # @return [ true, false ] If the document is in the target.
261
+ #
262
+ # @since 3.0.0
263
+ def include?(doc)
264
+ return super unless _unloaded
265
+ _unloaded.where(_id: doc._id).exists? || _added.has_key?(doc._id)
266
+ end
267
+
268
+ # Inspection will just inspect the entries for nice array-style
269
+ # printing.
270
+ #
271
+ # @example Inspect the enumerable.
272
+ # enumerable.inspect
273
+ #
274
+ # @return [ String ] The inspected enum.
275
+ #
276
+ # @since 2.1.0
277
+ def inspect
278
+ entries.inspect
279
+ end
280
+
281
+ # Return all the documents in the enumerable that have been _loaded or
282
+ # _added.
283
+ #
284
+ # @note When passed a block it yields to each document.
285
+ #
286
+ # @example Get the in memory docs.
287
+ # enumerable.in_memory
288
+ #
289
+ # @return [ Array<Document> ] The in memory docs.
290
+ #
291
+ # @since 2.1.0
292
+ def in_memory
293
+ docs = (_loaded.values + _added.values)
294
+ docs.each { |doc| yield(doc) } if block_given?
295
+ docs
296
+ end
297
+
298
+ # Get the last document in the enumerable. Will check the new
299
+ # documents first. Does not load the entire enumerable.
300
+ #
301
+ # @example Get the last document.
302
+ # enumerable.last
303
+ #
304
+ # @return [ Document ] The last document found.
305
+ #
306
+ # @since 2.1.0
307
+ def last
308
+ _added.values.try(:last) ||
309
+ _loaded.try(:values).try(:last) ||
310
+ _added[(ul = _unloaded.try(:last)).try(:id)] ||
311
+ ul
312
+ end
313
+
314
+ # Loads all the documents in the enumerable from the database.
315
+ #
316
+ # @example Load all the documents.
317
+ # enumerable.load_all!
318
+ #
319
+ # @return [ true ] That the enumerable is _loaded.
320
+ #
321
+ # @since 2.1.0
322
+ alias :load_all! :entries
323
+
324
+ # Has the enumerable been _loaded? This will be true if the criteria has
325
+ # been executed or we manually load the entire thing.
326
+ #
327
+ # @example Is the enumerable _loaded?
328
+ # enumerable._loaded?
329
+ #
330
+ # @return [ true, false ] If the enumerable has been _loaded.
331
+ #
332
+ # @since 2.1.0
333
+ def _loaded?
334
+ !!@executed
335
+ end
336
+
337
+ # Provides the data needed to Marshal.dump an enumerable proxy.
338
+ #
339
+ # @example Dump the proxy.
340
+ # Marshal.dump(proxy)
341
+ #
342
+ # @return [ Array<Object> ] The dumped data.
343
+ #
344
+ # @since 3.0.15
345
+ def marshal_dump
346
+ [_added, _loaded, _unloaded, @executed]
347
+ end
348
+
349
+ # Loads the data needed to Marshal.load an enumerable proxy.
350
+ #
351
+ # @example Load the proxy.
352
+ # Marshal.load(proxy)
353
+ #
354
+ # @return [ Array<Object> ] The dumped data.
355
+ #
356
+ # @since 3.0.15
357
+ def marshal_load(data)
358
+ @_added, @_loaded, @_unloaded, @executed = data
359
+ end
360
+
361
+ # Reset the enumerable back to its persisted state.
362
+ #
363
+ # @example Reset the enumerable.
364
+ # enumerable.reset
365
+ #
366
+ # @return [ false ] Always false.
367
+ #
368
+ # @since 2.1.0
369
+ def reset
370
+ _loaded.clear and _added.clear
371
+ @executed = false
372
+ end
373
+
374
+ # Resets the underlying unloaded criteria object with a new one. Used
375
+ # my HABTM relations to keep the underlying array in sync.
376
+ #
377
+ # @example Reset the unloaded documents.
378
+ # enumerable.reset_unloaded(criteria)
379
+ #
380
+ # @param [ Criteria ] criteria The criteria to replace with.
381
+ #
382
+ # @since 3.0.14
383
+ def reset_unloaded(criteria)
384
+ @_unloaded = criteria if _unloaded.is_a?(Criteria)
385
+ end
386
+
387
+ # Does this enumerable respond to the provided method?
388
+ #
389
+ # @example Does the enumerable respond to the method?
390
+ # enumerable.respond_to?(:sum)
391
+ #
392
+ # @param [ String, Symbol ] name The name of the method.
393
+ # @param [ true, false ] include_private Whether to include private
394
+ # methods.
395
+ #
396
+ # @return [ true, false ] Whether the enumerable responds.
397
+ #
398
+ # @since 2.1.0
399
+ def respond_to?(name, include_private = false)
400
+ [].respond_to?(name, include_private) || super
401
+ end
402
+
403
+ # Gets the total size of this enumerable. This is a combination of all
404
+ # the persisted and unpersisted documents.
405
+ #
406
+ # @example Get the size.
407
+ # enumerable.size
408
+ #
409
+ # @return [ Integer ] The size of the enumerable.
410
+ #
411
+ # @since 2.1.0
412
+ def size
413
+ count = (_unloaded ? _unloaded.count : _loaded.count)
414
+ if count.zero?
415
+ count + _added.count
416
+ else
417
+ count + _added.values.count { |d| d.new_record? }
418
+ end
419
+ end
420
+
421
+ alias :length :size
422
+
423
+ # Send #to_json to the entries.
424
+ #
425
+ # @example Get the enumerable as json.
426
+ # enumerable.to_json
427
+ #
428
+ # @param [ Hash ] options Optional parameters.
429
+ #
430
+ # @return [ String ] The entries all _loaded as a string.
431
+ #
432
+ # @since 2.2.0
433
+ def to_json(options = {})
434
+ entries.to_json(options)
435
+ end
436
+
437
+ # Send #as_json to the entries, without encoding.
438
+ #
439
+ # @example Get the enumerable as json.
440
+ # enumerable.as_json
441
+ #
442
+ # @param [ Hash ] options Optional parameters.
443
+ #
444
+ # @return [ Hash ] The entries all _loaded as a hash.
445
+ #
446
+ # @since 2.2.0
447
+ def as_json(options = {})
448
+ entries.as_json(options)
449
+ end
450
+
451
+ # Return all the unique documents in the enumerable.
452
+ #
453
+ # @note This operation loads all documents from the database.
454
+ #
455
+ # @example Get all the unique documents.
456
+ # enumerable.uniq
457
+ #
458
+ # @return [ Array<Document> ] The unique documents.
459
+ #
460
+ # @since 2.1.0
461
+ def uniq
462
+ entries.uniq
463
+ end
464
+
465
+ private
466
+
467
+ def method_missing(name, *args, &block)
468
+ entries.send(name, *args, &block)
469
+ end
470
+
471
+ def unloaded_documents
472
+ _unloaded.selector.values.any?(&:blank_criteria?) ? [] : _unloaded
473
+ end
474
+ end
475
+ end
476
+ end
477
+ end
478
+ end
479
+ end