mongoid 6.4.2 → 7.0.3

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