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,1963 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Association::Referenced::BelongsTo do
4
+
5
+ before do
6
+ class OwnerObject; include Mongoid::Document; end
7
+ class BelongingObject; include Mongoid::Document; end
8
+ end
9
+
10
+ after do
11
+ Object.send(:remove_const, :BelongingObject)
12
+ Object.send(:remove_const, :OwnerObject)
13
+ end
14
+
15
+ let(:belonging_class) do
16
+ BelongingObject
17
+ end
18
+
19
+ let(:name) do
20
+ :owner_object
21
+ end
22
+
23
+ let(:association) do
24
+ belonging_class.belongs_to name, options
25
+ end
26
+
27
+ let(:options) do
28
+ { }
29
+ end
30
+
31
+ describe '#relation_complements' do
32
+
33
+ let(:expected_complements) do
34
+ [
35
+ Mongoid::Association::Referenced::HasMany,
36
+ Mongoid::Association::Referenced::HasOne
37
+ ]
38
+ end
39
+
40
+ it 'returns the relation complements' do
41
+ expect(association.relation_complements).to eq(expected_complements)
42
+ end
43
+ end
44
+
45
+ describe '#setup!' do
46
+
47
+ it 'sets up a getter for the relation' do
48
+ expect(Mongoid::Association::Accessors).to receive(:define_getter!).with(association)
49
+ association.setup!
50
+ end
51
+
52
+ it 'sets up a setter for the relation' do
53
+ expect(Mongoid::Association::Accessors).to receive(:define_setter!).with(association)
54
+ association.setup!
55
+ end
56
+
57
+ it 'sets up an existence check for the relation' do
58
+ expect(Mongoid::Association::Accessors).to receive(:define_existence_check!).with(association)
59
+ association.setup!
60
+ end
61
+
62
+ it 'sets up the builder for the relation' do
63
+ expect(Mongoid::Association::Builders).to receive(:define_builder!).with(association)
64
+ association.setup!
65
+ end
66
+
67
+ it 'sets up the creator for the relation' do
68
+ expect(Mongoid::Association::Builders).to receive(:define_creator!).with(association)
69
+ association.setup!
70
+ end
71
+
72
+ context 'autosave' do
73
+
74
+ context 'when the :autosave option is true' do
75
+
76
+ let(:options) do
77
+ {
78
+ autosave: true
79
+ }
80
+ end
81
+
82
+ let(:association) do
83
+ # Note that it is necessary to create the association directly, otherwise the
84
+ # setup!! method will be called by the :belongs_to macro
85
+ described_class.new(belonging_class, name, options)
86
+ end
87
+
88
+ it 'sets up autosave' do
89
+ expect(Mongoid::Association::Referenced::AutoSave).to receive(:define_autosave!).with(association)
90
+ association.setup!
91
+ end
92
+ end
93
+
94
+ context 'when the :autosave option is false' do
95
+
96
+ let(:options) do
97
+ {
98
+ autosave: false
99
+ }
100
+ end
101
+
102
+ it 'does not set up autosave' do
103
+ expect(Mongoid::Association::Referenced::AutoSave).not_to receive(:define_autosave!)
104
+ association.setup!
105
+ end
106
+ end
107
+
108
+ context 'when the :autosave option is not provided' do
109
+
110
+ let(:association) do
111
+ # Note that it is necessary to create the association directly, otherwise the
112
+ # setup!! method will be called by the :embeds_many macro
113
+ described_class.new(belonging_class, name, options)
114
+ end
115
+
116
+ it 'does not set up autosave' do
117
+ expect(Mongoid::Association::Referenced::AutoSave).not_to receive(:define_autosave!)
118
+ association.setup!
119
+ end
120
+ end
121
+ end
122
+
123
+ context 'counter cache callbacks' do
124
+
125
+ context 'when the :counter_cache option is true' do
126
+
127
+ let(:options) do
128
+ {
129
+ counter_cache: true
130
+ }
131
+ end
132
+
133
+ let(:association) do
134
+ # Note that it is necessary to create the association directly, otherwise the
135
+ # setup! method will be called by the :belongs_to macro
136
+ described_class.new(belonging_class, name, options)
137
+ end
138
+
139
+ it 'sets up counter cache callbacks' do
140
+ expect(Mongoid::Association::Referenced::CounterCache).to receive(:define_callbacks!).with(association)
141
+ association.setup!
142
+ end
143
+ end
144
+
145
+ context 'when the :counter_cache option is a String' do
146
+
147
+ let(:options) do
148
+ {
149
+ counter_cache: 'counts_field'
150
+ }
151
+ end
152
+
153
+ let(:association) do
154
+ # Note that it is necessary to create the association directly, otherwise the
155
+ # setup! method will be called by the :belongs_to macro
156
+ described_class.new(belonging_class, name, options)
157
+ end
158
+
159
+ it 'sets up counter cache callbacks' do
160
+ expect(Mongoid::Association::Referenced::CounterCache).to receive(:define_callbacks!).with(association)
161
+ association.setup!
162
+ end
163
+ end
164
+
165
+ context 'when the :counter_cache option is false' do
166
+
167
+ let(:options) do
168
+ {
169
+ counter_cache: false
170
+ }
171
+ end
172
+
173
+ it 'does not set up counter cache callbacks' do
174
+ expect(Mongoid::Association::Referenced::CounterCache).not_to receive(:define_callbacks!)
175
+ association.setup!
176
+ end
177
+ end
178
+
179
+ context 'when the :counter_cache option is not provided' do
180
+
181
+ let(:association) do
182
+ # Note that it is necessary to create the association directly, otherwise the
183
+ # setup! method will be called by the :embeds_many macro
184
+ described_class.new(belonging_class, name, options)
185
+ end
186
+
187
+ it 'does not set up counter cache callbacks' do
188
+ expect(Mongoid::Association::Referenced::CounterCache).not_to receive(:define_callbacks!)
189
+ association.setup!
190
+ end
191
+ end
192
+ end
193
+
194
+ context 'polymorphic' do
195
+
196
+ context 'when the polymorphic option is provided' do
197
+
198
+ context 'when the polymorphic option is true' do
199
+
200
+ let(:options) do
201
+ {
202
+ polymorphic: true
203
+ }
204
+ end
205
+
206
+ before do
207
+ association
208
+ end
209
+
210
+ it 'set the polymorphic attribute on the owner class' do
211
+ expect(belonging_class.polymorphic).to be(true)
212
+ end
213
+
214
+ it 'sets up a field for the inverse type' do
215
+ expect(belonging_class.fields.keys).to include(association.inverse_type)
216
+ end
217
+ end
218
+
219
+ context 'when the polymorphic option is false' do
220
+
221
+ let(:options) do
222
+ {
223
+ polymorphic: false
224
+ }
225
+ end
226
+
227
+ it 'does not set the polymorphic attribute on the owner class' do
228
+ expect(belonging_class.polymorphic).to be(false)
229
+ end
230
+
231
+ it 'does not set up a field for the inverse type' do
232
+ expect(belonging_class.fields.keys).not_to include(association.inverse_type)
233
+ end
234
+ end
235
+ end
236
+
237
+ context 'when the polymorphic option is not provided' do
238
+
239
+ it 'does not set the polymorphic attribute on the owner class' do
240
+ expect(belonging_class.polymorphic).to be(false)
241
+ end
242
+
243
+ it 'does not set up a field for the inverse type' do
244
+ expect(belonging_class.fields.keys).not_to include(association.inverse_type)
245
+ end
246
+ end
247
+ end
248
+
249
+ context 'dependent' do
250
+
251
+ context 'when the dependent option is provided' do
252
+
253
+ context 'when the dependent option is :delete_all' do
254
+
255
+ let(:options) do
256
+ {
257
+ dependent: :delete_all
258
+ }
259
+ end
260
+
261
+ let(:association) do
262
+ # Note that it is necessary to create the association directly, otherwise the
263
+ # setup! method will be called by the :belongs_to macro
264
+ described_class.new(belonging_class, name, options)
265
+ end
266
+
267
+ it 'sets up the dependency' do
268
+ expect(Mongoid::Association::Depending).to receive(:define_dependency!)
269
+ association.setup!
270
+ end
271
+ end
272
+
273
+ context 'when the dependent option is :destroy' do
274
+
275
+ let(:options) do
276
+ {
277
+ dependent: :destroy
278
+ }
279
+ end
280
+
281
+ let(:association) do
282
+ # Note that it is necessary to create the association directly, otherwise the
283
+ # setup! method will be called by the :belongs_to macro
284
+ described_class.new(belonging_class, name, options)
285
+ end
286
+
287
+ it 'sets up the dependency' do
288
+ expect(Mongoid::Association::Depending).to receive(:define_dependency!)
289
+ association.setup!
290
+ end
291
+ end
292
+
293
+ context 'when the dependent option is :nullify' do
294
+
295
+ let(:options) do
296
+ {
297
+ dependent: :nullify
298
+ }
299
+ end
300
+
301
+ let(:association) do
302
+ # Note that it is necessary to create the association directly, otherwise the
303
+ # setup! method will be called by the :belongs_to macro
304
+ described_class.new(belonging_class, name, options)
305
+ end
306
+
307
+ it 'sets up the dependency' do
308
+ expect(Mongoid::Association::Depending).to receive(:define_dependency!)
309
+ association.setup!
310
+ end
311
+ end
312
+
313
+ context 'when the dependent option is :restrict_with_exception' do
314
+
315
+ let(:options) do
316
+ {
317
+ dependent: :restrict_with_exception
318
+ }
319
+ end
320
+
321
+ let(:association) do
322
+ # Note that it is necessary to create the association directly, otherwise the
323
+ # setup! method will be called by the :belongs_to macro
324
+ described_class.new(belonging_class, name, options)
325
+ end
326
+
327
+ it 'sets up the dependency' do
328
+ expect(Mongoid::Association::Depending).to receive(:define_dependency!)
329
+ association.setup!
330
+ end
331
+ end
332
+
333
+ context 'when the dependent option is :restrict_with_error' do
334
+
335
+ let(:options) do
336
+ {
337
+ dependent: :restrict_with_error
338
+ }
339
+ end
340
+
341
+ let(:association) do
342
+ # Note that it is necessary to create the association directly, otherwise the
343
+ # setup! method will be called by the :belongs_to macro
344
+ described_class.new(belonging_class, name, options)
345
+ end
346
+
347
+ it 'sets up the dependency' do
348
+ expect(Mongoid::Association::Depending).to receive(:define_dependency!)
349
+ association.setup!
350
+ end
351
+ end
352
+ end
353
+
354
+ context 'when the dependent option is not provided' do
355
+
356
+ it 'does not set up the dependency' do
357
+ expect(Mongoid::Association::Depending).not_to receive(:define_dependency!)
358
+ association.setup!
359
+ end
360
+ end
361
+ end
362
+
363
+ context 'foreign key field' do
364
+
365
+ before do
366
+ association
367
+ end
368
+
369
+ it 'sets up the foreign key field' do
370
+ expect(belonging_class.fields.keys).to include(association.foreign_key)
371
+ end
372
+ end
373
+
374
+ context 'index' do
375
+
376
+ before do
377
+ association
378
+ end
379
+
380
+ context 'when index is true' do
381
+
382
+ context 'when polymorphic' do
383
+
384
+ let(:options) do
385
+ {
386
+ polymorphic: true,
387
+ index: true
388
+ }
389
+ end
390
+
391
+ it 'sets up the index with the key and inverse type' do
392
+ expect(belonging_class.index_specifications.first.fields).to match_array([ association.key.to_sym,
393
+ association.inverse_type.to_sym])
394
+ end
395
+ end
396
+
397
+ context 'when not polymorphic' do
398
+
399
+ let(:options) do
400
+ {
401
+ index: true
402
+ }
403
+ end
404
+
405
+ it 'sets up the index with the key' do
406
+ expect(belonging_class.index_specifications.first.fields).to match_array([ association.key.to_sym ])
407
+ end
408
+ end
409
+ end
410
+
411
+ context 'when index is false' do
412
+
413
+ context 'when polymorphic' do
414
+
415
+ let(:options) do
416
+ {
417
+ polymorphic: true
418
+ }
419
+ end
420
+
421
+ it 'does not set up an index' do
422
+ expect(belonging_class.index_specifications).to eq([ ])
423
+ end
424
+ end
425
+
426
+ context 'when not polymorphic' do
427
+
428
+ it 'does not set up an index' do
429
+ expect(belonging_class.index_specifications).to eq([ ])
430
+ end
431
+ end
432
+ end
433
+ end
434
+
435
+ context 'touchable' do
436
+
437
+ context 'when the :touch option is true' do
438
+
439
+ let(:options) do
440
+ {
441
+ touch: true
442
+ }
443
+ end
444
+
445
+ let(:association) do
446
+ # Note that it is necessary to create the association directly, otherwise the
447
+ # setup! method will be called by the :belongs_to macro
448
+ described_class.new(belonging_class, name, options)
449
+ end
450
+
451
+ it 'sets up touch' do
452
+ expect(Mongoid:: Association::Touchable).to receive(:define_touchable!).with(association)
453
+ association.setup!
454
+ end
455
+ end
456
+
457
+ context 'when the :touch option is false' do
458
+
459
+ let(:options) do
460
+ {
461
+ touch: false
462
+ }
463
+ end
464
+
465
+ it 'does not set up touch' do
466
+ expect(Mongoid:: Association::Touchable).not_to receive(:define_touchable!).with(association)
467
+ association.setup!
468
+ end
469
+ end
470
+
471
+ context 'when the :touch option is not provided' do
472
+
473
+ let(:association) do
474
+ # Note that it is necessary to create the association directly, otherwise the
475
+ # setup! method will be called by the :embeds_many macro
476
+ described_class.new(belonging_class, name, options)
477
+ end
478
+
479
+ it 'does not set up touch' do
480
+ expect(Mongoid:: Association::Touchable).not_to receive(:define_touchable!).with(association)
481
+ association.setup!
482
+ end
483
+ end
484
+ end
485
+
486
+ context 'validate' do
487
+
488
+ context 'when the :validate option is true' do
489
+
490
+ let(:options) do
491
+ {
492
+ validate: true
493
+ }
494
+ end
495
+
496
+ let(:association) do
497
+ # Note that it is necessary to create the association directly, otherwise the
498
+ # setup! method will be called by the :belongs_to macro
499
+ described_class.new(belonging_class, name, options)
500
+ end
501
+
502
+ it 'sets up validation' do
503
+ expect(belonging_class).to receive(:validates_associated).with(name).and_call_original
504
+ association.setup!
505
+ end
506
+ end
507
+
508
+ context 'when the :validate option is false' do
509
+
510
+ let(:options) do
511
+ {
512
+ validate: false
513
+ }
514
+ end
515
+
516
+ it 'does not set up validation' do
517
+ expect(belonging_class).not_to receive(:validates_associated)
518
+ association.setup!
519
+ end
520
+ end
521
+
522
+ context 'when the :validate option is not provided' do
523
+
524
+ let(:association) do
525
+ # Note that it is necessary to create the association directly, otherwise the
526
+ # setup! method will be called by the :belongs_to macro
527
+ described_class.new(belonging_class, name, options)
528
+ end
529
+
530
+ it 'does not set up the validation because it uses the validation default (false)' do
531
+ expect(belonging_class).not_to receive(:validates_associated)
532
+ association.setup!
533
+ end
534
+ end
535
+ end
536
+
537
+ context 'presence of validation' do
538
+
539
+ let(:association) do
540
+ # Note that it is necessary to create the association directly, otherwise the
541
+ # setup! method will be called by the :belongs_to macro
542
+ described_class.new(belonging_class, name, options)
543
+ end
544
+
545
+ context 'when the global config option is true' do
546
+
547
+ around(:example) do |example|
548
+ original_config = Mongoid.belongs_to_required_by_default
549
+ Mongoid.belongs_to_required_by_default = true
550
+ example.run
551
+ Mongoid.belongs_to_required_by_default = original_config
552
+ end
553
+
554
+ let!(:original_required_config) do
555
+ Mongoid.belongs_to_required_by_default
556
+ end
557
+
558
+ context 'when the required option is true' do
559
+
560
+ let(:options) do
561
+ {
562
+ required: true
563
+ }
564
+ end
565
+
566
+ it 'sets up the presence of validation' do
567
+ expect(belonging_class).to receive(:validates).with(name, { presence: true }).and_call_original
568
+ association.setup!
569
+ end
570
+
571
+ context 'when the optional option is true' do
572
+
573
+ let(:options) do
574
+ {
575
+ required: true,
576
+ optional: true
577
+ }
578
+ end
579
+
580
+ it 'sets up the presence of validation' do
581
+ expect(belonging_class).to receive(:validates).with(name, { presence: true }).and_call_original
582
+ association.setup!
583
+ end
584
+ end
585
+
586
+ context 'when the optional option is false' do
587
+
588
+ let(:options) do
589
+ {
590
+ required: true,
591
+ optional: false
592
+ }
593
+ end
594
+
595
+ it 'sets up the presence of validation' do
596
+ expect(belonging_class).to receive(:validates).with(name, { presence: true }).and_call_original
597
+ association.setup!
598
+ end
599
+ end
600
+ end
601
+
602
+ context 'when the required option is false' do
603
+
604
+ let(:options) do
605
+ {
606
+ required: false
607
+ }
608
+ end
609
+
610
+ it 'does not set up the presence of validation' do
611
+ expect(belonging_class).not_to receive(:validates)
612
+ association.setup!
613
+ end
614
+
615
+ context 'when the optional option is true' do
616
+
617
+ let(:options) do
618
+ {
619
+ required: false,
620
+ optional: true
621
+ }
622
+ end
623
+
624
+ it 'does not set up the presence of validation' do
625
+ expect(belonging_class).not_to receive(:validates)
626
+ association.setup!
627
+ end
628
+ end
629
+
630
+ context 'when the optional option is false' do
631
+
632
+ let(:options) do
633
+ {
634
+ required: false,
635
+ optional: false
636
+ }
637
+ end
638
+
639
+ it 'does not set up the presence of validation' do
640
+ expect(belonging_class).not_to receive(:validates)
641
+ association.setup!
642
+ end
643
+ end
644
+ end
645
+
646
+ context 'when the required option is not provided' do
647
+
648
+ it 'uses the default and sets up the presence of validation' do
649
+ expect(belonging_class).to receive(:validates).with(name, { presence: true }).and_call_original
650
+ association.setup!
651
+ end
652
+
653
+ context 'when the optional option is true' do
654
+
655
+ let(:options) do
656
+ {
657
+ optional: true
658
+ }
659
+ end
660
+
661
+ it 'does not set up the presence of validation' do
662
+ expect(belonging_class).not_to receive(:validates)
663
+ association.setup!
664
+ end
665
+ end
666
+
667
+ context 'when the optional option is false' do
668
+
669
+ let(:options) do
670
+ {
671
+ optional: false
672
+ }
673
+ end
674
+
675
+ it 'sets up the presence of validation' do
676
+ expect(belonging_class).to receive(:validates).with(name, { presence: true }).and_call_original
677
+ association.setup!
678
+ end
679
+ end
680
+ end
681
+ end
682
+
683
+ context 'when the global config option is false' do
684
+
685
+ around(:example) do |example|
686
+ original_config = Mongoid.belongs_to_required_by_default
687
+ Mongoid.belongs_to_required_by_default = false
688
+ example.run
689
+ Mongoid.belongs_to_required_by_default = original_config
690
+ end
691
+
692
+ context 'when the required option is true' do
693
+
694
+ let(:options) do
695
+ {
696
+ required: true
697
+ }
698
+ end
699
+
700
+ it 'sets up the presence of validation' do
701
+ expect(belonging_class).to receive(:validates).with(name, { presence: true }).and_call_original
702
+ association.setup!
703
+ end
704
+
705
+ context 'when the optional option is true' do
706
+
707
+ let(:options) do
708
+ {
709
+ required: true,
710
+ optional: true
711
+ }
712
+ end
713
+
714
+ it 'sets up the presence of validation' do
715
+ expect(belonging_class).to receive(:validates).with(name, { presence: true }).and_call_original
716
+ association.setup!
717
+ end
718
+ end
719
+
720
+ context 'when the optional option is false' do
721
+
722
+ let(:options) do
723
+ {
724
+ required: true,
725
+ optional: false
726
+ }
727
+ end
728
+
729
+ it 'sets up the presence of validation' do
730
+ expect(belonging_class).to receive(:validates).with(name, { presence: true }).and_call_original
731
+ association.setup!
732
+ end
733
+ end
734
+ end
735
+
736
+ context 'when the required option is false' do
737
+
738
+ let(:options) do
739
+ {
740
+ required: false
741
+ }
742
+ end
743
+
744
+ it 'does not set up the presence of validation' do
745
+ expect(belonging_class).not_to receive(:validates)
746
+ association.setup!
747
+ end
748
+
749
+ context 'when the optional option is true' do
750
+
751
+ let(:options) do
752
+ {
753
+ required: false,
754
+ optional: true
755
+ }
756
+ end
757
+
758
+ it 'does not set up the presence of validation' do
759
+ expect(belonging_class).not_to receive(:validates)
760
+ association.setup!
761
+ end
762
+ end
763
+
764
+ context 'when the optional option is false' do
765
+
766
+ let(:options) do
767
+ {
768
+ required: false,
769
+ optional: false
770
+ }
771
+ end
772
+
773
+ it 'does not set up the presence of validation' do
774
+ expect(belonging_class).not_to receive(:validates)
775
+ association.setup!
776
+ end
777
+ end
778
+ end
779
+
780
+ context 'when the required option is not provided' do
781
+
782
+ it 'uses the default and does not set up the presence of validation' do
783
+ expect(belonging_class).not_to receive(:validates)
784
+ association.setup!
785
+ end
786
+
787
+ context 'when the optional option is true' do
788
+
789
+ let(:options) do
790
+ {
791
+ optional: true
792
+ }
793
+ end
794
+
795
+ it 'does not set up the presence of validation' do
796
+ expect(belonging_class).not_to receive(:validates)
797
+ association.setup!
798
+ end
799
+ end
800
+
801
+ context 'when the optional option is false' do
802
+
803
+ let(:options) do
804
+ {
805
+ optional: false
806
+ }
807
+ end
808
+
809
+ it 'sets up the presence of validation' do
810
+ expect(belonging_class).to receive(:validates).with(name, { presence: true }).and_call_original
811
+ association.setup!
812
+ end
813
+ end
814
+ end
815
+ end
816
+ end
817
+ end
818
+
819
+ describe '#type' do
820
+
821
+ context 'when polymorphic' do
822
+
823
+ let(:options) do
824
+ { polymorphic: true }
825
+ end
826
+
827
+ it 'returns nil' do
828
+ expect(association.type).to be_nil
829
+ end
830
+ end
831
+
832
+ context 'when not polymorphic' do
833
+
834
+ it 'returns nil' do
835
+ expect(association.type).to be_nil
836
+ end
837
+ end
838
+ end
839
+
840
+ describe '#inverse_type' do
841
+
842
+ context 'when polymorphic' do
843
+
844
+ let(:options) do
845
+ { polymorphic: true }
846
+ end
847
+
848
+ it 'returns the name followed by "_type"' do
849
+ expect(association.inverse_type).to eq("#{name}_type")
850
+ end
851
+ end
852
+
853
+ context 'when not polymorphic' do
854
+
855
+ it 'returns nil' do
856
+ expect(association.inverse_type).to be_nil
857
+ end
858
+ end
859
+ end
860
+
861
+ describe '#inverse_type_setter' do
862
+
863
+ context 'when polymorphic' do
864
+
865
+ let(:options) do
866
+ { polymorphic: true }
867
+ end
868
+
869
+ it 'returns the inverse type setter' do
870
+ expect(association.inverse_type_setter).to eq("#{name}_type=")
871
+ end
872
+ end
873
+
874
+ context 'when not polymorphic' do
875
+
876
+ it 'returns nil' do
877
+ expect(association.inverse_type_setter).to be_nil
878
+ end
879
+ end
880
+ end
881
+
882
+ describe '#foreign_key' do
883
+
884
+ context 'when options has foreign_key specified' do
885
+
886
+ let(:options) do
887
+ { foreign_key: :other_object_id }
888
+ end
889
+
890
+ it 'returns the foreign key' do
891
+ expect(association.foreign_key).to eq(options[:foreign_key].to_s)
892
+ end
893
+ end
894
+
895
+ context 'when options does not have foreign_key specified' do
896
+
897
+ it 'returns the ame followed by "_id"' do
898
+ expect(association.foreign_key).to eq("#{name}_id")
899
+ end
900
+ end
901
+ end
902
+
903
+ describe '#embedded?' do
904
+
905
+ it 'returns false' do
906
+ expect(association.embedded?).to be(false)
907
+ end
908
+ end
909
+
910
+ describe '#primary_key' do
911
+
912
+ context 'when the :primary_key option is specified' do
913
+
914
+ context 'when the :primary_key option is true' do
915
+
916
+ let(:options) do
917
+ {
918
+ primary_key: :other_primary_key
919
+ }
920
+ end
921
+
922
+ it 'returns the primary key option as a String' do
923
+ expect(association.primary_key).to eq('other_primary_key')
924
+ end
925
+ end
926
+ end
927
+
928
+ context 'when the :primary_key option is not specified' do
929
+
930
+ it 'returns the default primary key' do
931
+ expect(association.primary_key).to eq(Mongoid::Association::Relatable::PRIMARY_KEY_DEFAULT)
932
+ end
933
+ end
934
+ end
935
+
936
+ describe '#indexed?' do
937
+
938
+ context 'when :index is specified in the options' do
939
+
940
+ context 'when :index is true' do
941
+
942
+ let(:options) do
943
+ {
944
+ index: true
945
+ }
946
+ end
947
+
948
+ it 'returns true' do
949
+ expect(association.indexed?).to be(true)
950
+ end
951
+ end
952
+
953
+ context 'when :index is false' do
954
+
955
+ let(:options) do
956
+ {
957
+ index: false
958
+ }
959
+ end
960
+
961
+ it 'returns false' do
962
+ expect(association.indexed?).to be(false)
963
+ end
964
+ end
965
+ end
966
+
967
+ context 'when :index is not specified in the options' do
968
+
969
+ it 'returns nil' do
970
+ expect(association.indexed?).to be(false)
971
+ end
972
+ end
973
+ end
974
+
975
+ describe '#relation' do
976
+
977
+ it 'returns Mongoid::Association::Referenced::BelongsTo::Proxy' do
978
+ expect(association.relation).to be(Mongoid::Association::Referenced::BelongsTo::Proxy)
979
+ end
980
+ end
981
+
982
+ describe '#validation_default' do
983
+
984
+ it 'returns false' do
985
+ expect(association.validation_default).to be(false)
986
+ end
987
+ end
988
+
989
+ describe '#name' do
990
+
991
+ it 'returns the name of the relation' do
992
+ expect(association.name).to be(name)
993
+ end
994
+ end
995
+
996
+ describe '#options' do
997
+
998
+ it 'returns the options' do
999
+ expect(association.options).to be(options)
1000
+ end
1001
+ end
1002
+
1003
+ describe '#cyclic?' do
1004
+
1005
+ it 'returns false' do
1006
+ expect(association.cyclic?).to be(false)
1007
+ end
1008
+ end
1009
+
1010
+ describe '#merge!' do
1011
+
1012
+ end
1013
+
1014
+ describe '#store_as' do
1015
+
1016
+ it 'returns nil' do
1017
+ expect(association.store_as).to be_nil
1018
+ end
1019
+ end
1020
+
1021
+ describe '#touchable?' do
1022
+
1023
+ context 'when :touch is in the options' do
1024
+
1025
+ let(:options) do
1026
+ { touch: true}
1027
+ end
1028
+
1029
+ it 'returns true' do
1030
+ expect(association.send(:touchable?)).to be(true)
1031
+ end
1032
+ end
1033
+
1034
+ context 'when :touch is not in the options' do
1035
+
1036
+ it 'return false' do
1037
+ expect(association.send(:touchable?)).to be(false)
1038
+ end
1039
+ end
1040
+ end
1041
+
1042
+ describe '#order' do
1043
+
1044
+ it 'returns nil' do
1045
+ expect(association.order).to be_nil
1046
+ end
1047
+ end
1048
+
1049
+ describe '#as' do
1050
+
1051
+ it 'returns nil' do
1052
+ expect(association.as).to be_nil
1053
+ end
1054
+ end
1055
+
1056
+ describe '#polymorphic?' do
1057
+
1058
+ context 'when :polymorphic is specified in the options as true' do
1059
+
1060
+ let(:options) do
1061
+ { polymorphic: true }
1062
+ end
1063
+
1064
+ it 'returns true' do
1065
+ expect(association.polymorphic?).to be(true)
1066
+ end
1067
+ end
1068
+
1069
+ context 'when :polymorphic is specified in the options as false' do
1070
+
1071
+ let(:options) do
1072
+ { polymorphic: false }
1073
+ end
1074
+
1075
+ it 'returns false' do
1076
+ expect(association.polymorphic?).to be(false)
1077
+ end
1078
+ end
1079
+
1080
+ context 'when :polymorphic is not specified in the options' do
1081
+
1082
+ it 'returns false' do
1083
+ expect(association.polymorphic?).to be(false)
1084
+ end
1085
+ end
1086
+ end
1087
+
1088
+ describe '#dependent' do
1089
+
1090
+ context 'when the dependent option is provided' do
1091
+
1092
+ context 'when the dependent option is :delete_all' do
1093
+
1094
+ let(:options) do
1095
+ {
1096
+ dependent: :delete_all
1097
+ }
1098
+ end
1099
+
1100
+ it 'returns :delete_all' do
1101
+ expect(association.dependent).to eq(:delete_all)
1102
+ end
1103
+ end
1104
+
1105
+ context 'when the dependent option is :destroy' do
1106
+
1107
+ let(:options) do
1108
+ {
1109
+ dependent: :destroy
1110
+ }
1111
+ end
1112
+
1113
+ it 'returns :destroy' do
1114
+ expect(association.dependent).to eq(:destroy)
1115
+ end
1116
+ end
1117
+
1118
+ context 'when the dependent option is :nullify' do
1119
+
1120
+ let(:options) do
1121
+ {
1122
+ dependent: :nullify
1123
+ }
1124
+ end
1125
+
1126
+ it 'returns :nullify' do
1127
+ expect(association.dependent).to eq(:nullify)
1128
+ end
1129
+ end
1130
+
1131
+ context 'when the dependent option is :restrict_with_exception' do
1132
+
1133
+ let(:options) do
1134
+ {
1135
+ dependent: :restrict_with_exception
1136
+ }
1137
+ end
1138
+
1139
+ it 'returns :restrict_with_exception' do
1140
+ expect(association.dependent).to eq(:restrict_with_exception)
1141
+ end
1142
+ end
1143
+
1144
+ context 'when the dependent option is :restrict_with_error' do
1145
+
1146
+ let(:options) do
1147
+ {
1148
+ dependent: :restrict_with_error
1149
+ }
1150
+ end
1151
+
1152
+ it 'returns :restrict_with_error' do
1153
+ expect(association.dependent).to eq(:restrict_with_error)
1154
+ end
1155
+ end
1156
+ end
1157
+
1158
+ context 'when the dependent option is not provided' do
1159
+
1160
+ it 'returns nil' do
1161
+ expect(association.dependent).to be_nil
1162
+ end
1163
+ end
1164
+ end
1165
+
1166
+ describe '#bindable?' do
1167
+
1168
+ it 'returns false' do
1169
+ expect(association.bindable?(Person.new)).to be(false)
1170
+ end
1171
+ end
1172
+
1173
+ describe '#inverses' do
1174
+
1175
+ context 'when polymorphic' do
1176
+
1177
+ let(:options) do
1178
+ {
1179
+ polymorphic: true
1180
+ }
1181
+ end
1182
+
1183
+ let(:name) do
1184
+ :containable
1185
+ end
1186
+
1187
+ context 'when another object is passed to the method' do
1188
+
1189
+ let(:instance_of_other_class) do
1190
+ OwnerObject.new
1191
+ end
1192
+
1193
+ context 'when the relation class has only one relation whose class matches the owning class' do
1194
+
1195
+ before do
1196
+ OwnerObject.has_one :belonging_object, as: :containable
1197
+ end
1198
+
1199
+ context 'when :inverse_of is specified' do
1200
+
1201
+ before do
1202
+ options.merge!(inverse_of: :inverse_name)
1203
+ end
1204
+
1205
+ it 'returns the :inverse_of value' do
1206
+ expect(association.inverses(instance_of_other_class)).to eq([ :inverse_name ])
1207
+ end
1208
+ end
1209
+
1210
+ context 'when inverse_of is not specified' do
1211
+
1212
+ it 'returns the list of relations whose :as attribute matches the name of this association' do
1213
+ expect(association.inverses(instance_of_other_class)).to match_array([ :belonging_object ])
1214
+ end
1215
+ end
1216
+ end
1217
+
1218
+ context 'when the relation class has more than one relation whose class matches the owning class' do
1219
+
1220
+ before do
1221
+ OwnerObject.has_one :other_belonging_object, as: :containable, class_name: 'BelongingObject'
1222
+ OwnerObject.has_one :belonging_object, as: :containable
1223
+ end
1224
+
1225
+ context 'when :inverse_of is specified' do
1226
+
1227
+ before do
1228
+ options.merge!(inverse_of: :inverse_name)
1229
+ end
1230
+
1231
+ it 'returns the :inverse_of value' do
1232
+ expect(association.inverses(instance_of_other_class)).to eq([ :inverse_name ])
1233
+ end
1234
+ end
1235
+
1236
+ context 'when inverse_of is not specified' do
1237
+
1238
+ it 'returns the list of relations whose :as attribute matches the name of this association' do
1239
+ expect(association.inverses(instance_of_other_class)).to match_array([ :other_belonging_object,
1240
+ :belonging_object ])
1241
+ end
1242
+
1243
+ context 'when the relation class has two associations with the same name' do
1244
+
1245
+ before do
1246
+ OwnerObject.has_one :belonging_object, as: :containable
1247
+ OwnerObject.has_one :other_belonging_object, as: :containable
1248
+ end
1249
+
1250
+ it 'returns only the relations whose :as attribute and class match' do
1251
+ expect(association.inverses(instance_of_other_class)).to match_array([ :belonging_object ])
1252
+ end
1253
+ end
1254
+ end
1255
+ end
1256
+ end
1257
+
1258
+ context 'when another object is not passed to the method' do
1259
+
1260
+ context 'when inverse_of is specified' do
1261
+
1262
+ before do
1263
+ options.merge!(inverse_of: :inverse_name)
1264
+ end
1265
+
1266
+ it 'returns the :inverse_of value' do
1267
+ expect(association.inverses).to eq([ :inverse_name ])
1268
+ end
1269
+ end
1270
+
1271
+ context 'when inverse_of is not specified' do
1272
+
1273
+ it 'returns nil' do
1274
+ expect(association.inverses).to eq(nil)
1275
+ end
1276
+ end
1277
+ end
1278
+ end
1279
+
1280
+ context 'when not polymorphic' do
1281
+
1282
+ context 'when inverse_of is specified' do
1283
+
1284
+ before do
1285
+ options.merge!(inverse_of: :inverse_name)
1286
+ end
1287
+
1288
+ it 'returns the :inverse_of value' do
1289
+ expect(association.inverses).to eq([ :inverse_name ])
1290
+ end
1291
+ end
1292
+
1293
+ context 'when inverse_of is not specified' do
1294
+
1295
+ before do
1296
+ OwnerObject.has_many :belonging_objects
1297
+ end
1298
+
1299
+ it 'uses the inverse class to find the inverse name' do
1300
+ expect(association.inverses).to eq([ :belonging_objects ])
1301
+ end
1302
+ end
1303
+
1304
+ context 'when :cyclic is specified' do
1305
+
1306
+ it 'returns the cyclic inverse name' do
1307
+
1308
+ end
1309
+ end
1310
+
1311
+ context 'when the inverse class has more than one relation with objects of the owner class' do
1312
+
1313
+ before do
1314
+ OwnerObject.has_many :belonging_objects
1315
+ OwnerObject.has_one :other_belonging_object, class_name: 'BelongingObject'
1316
+ end
1317
+
1318
+ it 'raises a Mongoid::Errors::AmbiguousRelationship exception' do
1319
+ expect {
1320
+ association.inverses
1321
+ }.to raise_exception(Mongoid::Errors::AmbiguousRelationship)
1322
+ end
1323
+ end
1324
+
1325
+ context 'when the inverse class only has one relation with objects of the owner class' do
1326
+
1327
+ before do
1328
+ OwnerObject.has_many :belonging_objects
1329
+ end
1330
+
1331
+ it 'uses the inverse class to find the inverse name' do
1332
+ expect(association.inverses).to eq([ :belonging_objects ])
1333
+ end
1334
+ end
1335
+ end
1336
+ end
1337
+
1338
+ describe '#inverse' do
1339
+
1340
+ context 'when polymorphic' do
1341
+
1342
+ let(:options) do
1343
+ {
1344
+ polymorphic: true
1345
+ }
1346
+ end
1347
+
1348
+ let(:name) do
1349
+ :containable
1350
+ end
1351
+
1352
+ context 'when another object is passed to the method' do
1353
+
1354
+ let(:instance_of_other_class) do
1355
+ OwnerObject.new
1356
+ end
1357
+
1358
+ context 'when the relation class has only one relation whose class matches the owning class' do
1359
+
1360
+ before do
1361
+ OwnerObject.has_many :belonging_objects, as: :containable
1362
+ end
1363
+
1364
+ context 'when :inverse_of is specified' do
1365
+
1366
+ before do
1367
+ options.merge!(inverse_of: :inverse_name)
1368
+ end
1369
+
1370
+ it 'returns the :inverse_of value' do
1371
+ expect(association.inverse(instance_of_other_class)).to eq(:inverse_name)
1372
+ end
1373
+ end
1374
+
1375
+ context 'when inverse_of is not specified' do
1376
+
1377
+ it 'returns the list of relations whose :as attribute matches the name of this association' do
1378
+ expect(association.inverse(instance_of_other_class)).to eq(:belonging_objects)
1379
+ end
1380
+ end
1381
+ end
1382
+
1383
+ context 'when the relation class has more than one relation whose class matches the owning class' do
1384
+
1385
+ before do
1386
+ OwnerObject.has_one :other_belonging_object, as: :containable, class_name: 'BelongingObject'
1387
+ OwnerObject.has_one :belonging_object, as: :containable
1388
+ end
1389
+
1390
+ context 'when :inverse_of is specified' do
1391
+
1392
+ before do
1393
+ options.merge!(inverse_of: :inverse_name)
1394
+ end
1395
+
1396
+ it 'returns the :inverse_of value' do
1397
+ expect(association.inverse(instance_of_other_class)).to eq(:inverse_name)
1398
+ end
1399
+ end
1400
+
1401
+ context 'when inverse_of is not specified' do
1402
+
1403
+ it 'returns the first candidate whose :as attribute matches the name of this association' do
1404
+ expect(association.inverse(instance_of_other_class)).to eq(:other_belonging_object)
1405
+ end
1406
+ end
1407
+ end
1408
+ end
1409
+
1410
+ context 'when another object is not passed to the method' do
1411
+
1412
+ context 'when inverse_of is specified' do
1413
+
1414
+ before do
1415
+ options.merge!(inverse_of: :inverse_name)
1416
+ end
1417
+
1418
+ it 'returns the :inverse_of value' do
1419
+ expect(association.inverse).to eq(:inverse_name)
1420
+ end
1421
+ end
1422
+
1423
+ context 'when inverse_of is not specified' do
1424
+
1425
+ it 'returns nil' do
1426
+ expect(association.inverse).to eq(nil)
1427
+ end
1428
+ end
1429
+ end
1430
+ end
1431
+
1432
+ context 'when not polymorphic' do
1433
+
1434
+ context 'when inverse_of is specified' do
1435
+
1436
+ before do
1437
+ options.merge!(inverse_of: :inverse_name)
1438
+ end
1439
+
1440
+ it 'returns the :inverse_of value' do
1441
+ expect(association.inverse).to eq(:inverse_name)
1442
+ end
1443
+ end
1444
+
1445
+ context 'when inverse_of is not specified' do
1446
+
1447
+ before do
1448
+ OwnerObject.has_many :belonging_objects
1449
+ end
1450
+
1451
+ it 'uses the inverse class to find the inverse name' do
1452
+ expect(association.inverse).to eq(:belonging_objects)
1453
+ end
1454
+ end
1455
+
1456
+ context 'when :cyclic is specified' do
1457
+
1458
+ it 'returns the cyclic inverse name' do
1459
+
1460
+ end
1461
+ end
1462
+
1463
+ context 'when the inverse class has more than one relation with objects of the owner class' do
1464
+
1465
+ before do
1466
+ OwnerObject.has_many :belonging_objects
1467
+ OwnerObject.has_many :other_belonging_objects, class_name: 'BelongingObject'
1468
+ end
1469
+
1470
+ it 'raises a Mongoid::Errors::AmbiguousRelationship exception' do
1471
+ expect {
1472
+ association.inverse
1473
+ }.to raise_exception(Mongoid::Errors::AmbiguousRelationship)
1474
+ end
1475
+ end
1476
+
1477
+ context 'when the inverse class only has one relation with objects of the owner class' do
1478
+
1479
+ before do
1480
+ OwnerObject.has_many :belonging_objects
1481
+ end
1482
+
1483
+ it 'uses the inverse class to find the inverse name' do
1484
+ expect(association.inverse).to eq(:belonging_objects)
1485
+ end
1486
+ end
1487
+ end
1488
+ end
1489
+
1490
+ describe '#inverse_association' do
1491
+
1492
+ end
1493
+
1494
+ describe '#autosave' do
1495
+
1496
+ context 'when the :autosave option is specified' do
1497
+
1498
+ context 'when the :autosave option is true' do
1499
+
1500
+ let(:options) do
1501
+ {
1502
+ autosave: true
1503
+ }
1504
+ end
1505
+
1506
+ it 'returns true' do
1507
+ expect(association.autosave).to be(true)
1508
+ end
1509
+ end
1510
+
1511
+ context 'when the :autosave option is false' do
1512
+
1513
+ let(:options) do
1514
+ {
1515
+ autosave: false
1516
+ }
1517
+ end
1518
+
1519
+ it 'returns false' do
1520
+ expect(association.autosave).to be(false)
1521
+ end
1522
+ end
1523
+ end
1524
+
1525
+ context 'when the :autosave option is not specified' do
1526
+
1527
+ it 'returns nil' do
1528
+ expect(association.autosave).to be(false)
1529
+ end
1530
+ end
1531
+ end
1532
+
1533
+ describe '#counter_cached?' do
1534
+
1535
+ context 'when the :counter_cache option is true' do
1536
+
1537
+ let(:options) do
1538
+ {
1539
+ counter_cache: true
1540
+ }
1541
+ end
1542
+
1543
+ it 'returns true' do
1544
+ expect(association.counter_cached?).to be(true)
1545
+ end
1546
+ end
1547
+
1548
+ context 'when the :counter_cache option is a String' do
1549
+
1550
+ let(:options) do
1551
+ {
1552
+ counter_cache: 'counts_field'
1553
+ }
1554
+ end
1555
+
1556
+ it 'returns true' do
1557
+ expect(association.counter_cached?).to be(true)
1558
+ end
1559
+ end
1560
+
1561
+ context 'when the :counter_cache option is false' do
1562
+
1563
+ let(:options) do
1564
+ {
1565
+ counter_cache: false
1566
+ }
1567
+ end
1568
+
1569
+ it 'returns false' do
1570
+ expect(association.counter_cached?).to be(false)
1571
+ end
1572
+ end
1573
+
1574
+ context 'when the :counter_cache option is not provided' do
1575
+
1576
+ it 'returns false' do
1577
+ expect(association.counter_cached?).to be(false)
1578
+ end
1579
+ end
1580
+ end
1581
+
1582
+ describe '#counter_cache_column_name' do
1583
+
1584
+ context 'when the :counter_cache option is true' do
1585
+
1586
+ let(:options) do
1587
+ {
1588
+ counter_cache: true
1589
+ }
1590
+ end
1591
+
1592
+ it 'returns the inverse name followed by "_count"' do
1593
+ expect(association.counter_cache_column_name).to eq('belonging_objects_count')
1594
+ end
1595
+ end
1596
+
1597
+ context 'when the :counter_cache option is a String' do
1598
+
1599
+ let(:options) do
1600
+ {
1601
+ counter_cache: 'counts_field'
1602
+ }
1603
+ end
1604
+
1605
+ it 'returns the String' do
1606
+ expect(association.counter_cache_column_name).to eq('counts_field')
1607
+ end
1608
+ end
1609
+ end
1610
+
1611
+ describe '#relation_class_name' do
1612
+
1613
+ context 'when the :class_name option is specified' do
1614
+
1615
+ let(:options) do
1616
+ { class_name: 'OtherOwnerObject' }
1617
+ end
1618
+
1619
+ it 'returns the class name option' do
1620
+ expect(association.relation_class_name).to eq('OtherOwnerObject')
1621
+ end
1622
+ end
1623
+
1624
+ context 'when the class_name option is not specified' do
1625
+
1626
+ it 'uses the name of the relation to deduce the class name' do
1627
+ expect(association.relation_class_name).to eq('OwnerObject')
1628
+ end
1629
+ end
1630
+ end
1631
+
1632
+ describe '#klass' do
1633
+
1634
+ context 'when the :class_name option is specified' do
1635
+
1636
+ let!(:_class) do
1637
+ class OtherOwnerObject; end
1638
+ OtherOwnerObject
1639
+ end
1640
+
1641
+ let(:options) do
1642
+ { class_name: 'OtherOwnerObject' }
1643
+ end
1644
+
1645
+ it 'returns the class name option' do
1646
+ expect(association.klass).to eq(_class)
1647
+ end
1648
+ end
1649
+
1650
+ context 'when the class_name option is not specified' do
1651
+
1652
+ it 'uses the name of the relation to deduce the class name' do
1653
+ expect(association.klass).to eq(OwnerObject)
1654
+ end
1655
+ end
1656
+ end
1657
+
1658
+ describe '#inverse_class_name' do
1659
+
1660
+ it 'returns the name of the owner class' do
1661
+ expect(association.inverse_class_name).to eq(belonging_class.name)
1662
+ end
1663
+ end
1664
+
1665
+ describe '#inverse_class' do
1666
+
1667
+ it 'returns the owner class' do
1668
+ expect(association.inverse_class).to be(belonging_class)
1669
+ end
1670
+ end
1671
+
1672
+ describe '#inverse_of' do
1673
+
1674
+ context 'when :inverse_of is specified in the options' do
1675
+
1676
+ let(:options) do
1677
+ { inverse_of: :a_belonging_object }
1678
+ end
1679
+
1680
+ it 'returns the inverse_of value' do
1681
+ expect(association.inverse_of).to eq(options[:inverse_of])
1682
+ end
1683
+ end
1684
+
1685
+ context 'when :inverse_of is not specified in the options' do
1686
+
1687
+ it 'returns nil' do
1688
+ expect(association.inverse_of).to be_nil
1689
+ end
1690
+ end
1691
+ end
1692
+
1693
+ describe '#key' do
1694
+
1695
+ it 'returns the name of the foreign_key as a string' do
1696
+ expect(association.key).to eq(association.foreign_key.to_s)
1697
+ end
1698
+ end
1699
+
1700
+ describe '#setter' do
1701
+
1702
+ it 'returns a string of the name followed by =' do
1703
+ expect(association.setter).to eq("#{name}=")
1704
+ end
1705
+ end
1706
+
1707
+ describe '#validate?' do
1708
+
1709
+ context 'when :validate is specified in the options' do
1710
+
1711
+ context 'when validate is true' do
1712
+
1713
+ let(:options) do
1714
+ { validate: true }
1715
+ end
1716
+
1717
+ it 'returns true' do
1718
+ expect(association.send(:validate?)).to be(true)
1719
+ end
1720
+ end
1721
+
1722
+ context 'when validate is false' do
1723
+
1724
+ let(:options) do
1725
+ { validate: false }
1726
+ end
1727
+
1728
+ it 'returns false' do
1729
+ expect(association.send(:validate?)).to be(false)
1730
+ end
1731
+ end
1732
+ end
1733
+
1734
+ context 'when :validate is not specified in the options' do
1735
+
1736
+ it 'returns the validation_default' do
1737
+ expect(association.send(:validate?)).to eq(association.validation_default)
1738
+ end
1739
+ end
1740
+ end
1741
+
1742
+ describe '#autobuilding?' do
1743
+
1744
+ context 'when :autobuild is specified in the options' do
1745
+
1746
+ context 'when autobuild is true' do
1747
+
1748
+ let(:options) do
1749
+ { autobuild: true }
1750
+ end
1751
+
1752
+ it 'returns true' do
1753
+ expect(association.autobuilding?).to be(true)
1754
+ end
1755
+ end
1756
+
1757
+ context 'when autobuild is false' do
1758
+
1759
+ let(:options) do
1760
+ { autobuild: false }
1761
+ end
1762
+
1763
+ it 'returns true' do
1764
+ expect(association.autobuilding?).to be(false)
1765
+ end
1766
+ end
1767
+ end
1768
+
1769
+ context 'when :validate is not specified in the options' do
1770
+
1771
+ it 'returns false' do
1772
+ expect(association.autobuilding?).to be(false)
1773
+ end
1774
+ end
1775
+ end
1776
+
1777
+ describe '#forced_nil_inverse?' do
1778
+
1779
+ it 'returns false' do
1780
+ expect(association.forced_nil_inverse?).to be(false)
1781
+ end
1782
+ end
1783
+
1784
+ describe '#stores_foreign_key?' do
1785
+
1786
+ it 'returns true' do
1787
+ expect(association.stores_foreign_key?).to be(true)
1788
+ end
1789
+ end
1790
+
1791
+ describe '#inverse_setter' do
1792
+
1793
+ context 'when an inverse can be determined' do
1794
+
1795
+ before do
1796
+ OwnerObject.has_many :belonging_objects
1797
+ end
1798
+
1799
+ it 'returns the name of the inverse followed by =' do
1800
+ expect(association.inverse_setter).to eq('belonging_objects=')
1801
+ end
1802
+ end
1803
+
1804
+ context 'when an inverse cannot be determined' do
1805
+
1806
+ it 'returns nil' do
1807
+ expect(association.inverse_setter).to be_nil
1808
+ end
1809
+ end
1810
+ end
1811
+
1812
+ describe '#extension' do
1813
+
1814
+ context 'when a block is passed' do
1815
+
1816
+ let(:association) do
1817
+ belonging_class.belongs_to name, options do; end
1818
+ end
1819
+
1820
+ it 'defines an extension module' do
1821
+ expect(association.extension).to be_a(Module)
1822
+ end
1823
+
1824
+ it 'returns the extension' do
1825
+ expect(association.extension).to eq(
1826
+ "#{belonging_class.name}::#{belonging_class.name}#{name.to_s.camelize}RelationExtension".constantize)
1827
+ end
1828
+ end
1829
+
1830
+ context 'when an :extension is not specified in the options' do
1831
+
1832
+ it 'returns false' do
1833
+ expect(association.extension).to be_nil
1834
+ end
1835
+ end
1836
+ end
1837
+
1838
+ describe '#foreign_key_setter' do
1839
+
1840
+ it 'returns the foriegn key field followed by "="' do
1841
+ expect(association.foreign_key_setter).to eq("owner_object_id=")
1842
+ end
1843
+ end
1844
+
1845
+ describe '#destructive?' do
1846
+
1847
+ context 'when the dependent option is provided' do
1848
+
1849
+ context 'when the dependent option is :delete_all' do
1850
+
1851
+ let(:options) do
1852
+ {
1853
+ dependent: :delete_all
1854
+ }
1855
+ end
1856
+
1857
+ it 'returns true' do
1858
+ expect(association.destructive?).to be(true)
1859
+ end
1860
+ end
1861
+
1862
+ context 'when the dependent option is :destroy' do
1863
+
1864
+ let(:options) do
1865
+ {
1866
+ dependent: :destroy
1867
+ }
1868
+ end
1869
+
1870
+ it 'returns true' do
1871
+ expect(association.destructive?).to be(true)
1872
+ end
1873
+ end
1874
+
1875
+ context 'when the dependent option is :nullify' do
1876
+
1877
+ let(:options) do
1878
+ {
1879
+ dependent: :nullify
1880
+ }
1881
+ end
1882
+
1883
+ it 'returns false' do
1884
+ expect(association.destructive?).to be(false)
1885
+ end
1886
+ end
1887
+
1888
+ context 'when the dependent option is :restrict_with_exception' do
1889
+
1890
+ let(:options) do
1891
+ {
1892
+ dependent: :restrict_with_exception
1893
+ }
1894
+ end
1895
+
1896
+ it 'returns false' do
1897
+ expect(association.destructive?).to be(false)
1898
+ end
1899
+ end
1900
+
1901
+ context 'when the dependent option is :restrict_with_error' do
1902
+
1903
+ let(:options) do
1904
+ {
1905
+ dependent: :restrict_with_error
1906
+ }
1907
+ end
1908
+
1909
+ it 'returns false' do
1910
+ expect(association.destructive?).to be(false)
1911
+ end
1912
+ end
1913
+ end
1914
+
1915
+ context 'when the dependent option is not provided' do
1916
+
1917
+ it 'returns false' do
1918
+ expect(association.destructive?).to be(false)
1919
+ end
1920
+ end
1921
+ end
1922
+
1923
+ describe '#nested_builder' do
1924
+
1925
+ it 'returns an instance of Association::Nested::One' do
1926
+ expect(association.nested_builder({}, {})).to be_a(Mongoid::Association::Nested::One)
1927
+ end
1928
+ end
1929
+
1930
+ describe '#path' do
1931
+
1932
+ it 'returns an instance of Mongoid::Atomic::Paths::Root' do
1933
+ expect(association.path({})).to be_a(Mongoid::Atomic::Paths::Root)
1934
+ end
1935
+ end
1936
+
1937
+ describe '#foreign_key_check' do
1938
+
1939
+ it 'returns the foreign_key followed by "_changed?"' do
1940
+ expect(association.foreign_key_check).to eq('owner_object_id_changed?')
1941
+ end
1942
+ end
1943
+
1944
+ describe '#create_relation' do
1945
+
1946
+ let(:owner) do
1947
+ BelongingObject.new
1948
+ end
1949
+
1950
+ let(:target) do
1951
+ OwnerObject.new
1952
+ end
1953
+
1954
+ before do
1955
+ OwnerObject.has_one :belonging_object
1956
+ end
1957
+
1958
+ it 'returns an instance of Mongoid::Association::Referenced::BelongsTo::Proxy' do
1959
+ expect(Mongoid::Association::Referenced::BelongsTo::Proxy).to receive(:new).and_call_original
1960
+ expect(association.create_relation(owner, target)).to be_a(OwnerObject)
1961
+ end
1962
+ end
1963
+ end