mongoid 6.4.4 → 7.1.7

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 (942) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +13 -13
  4. data/LICENSE +1 -0
  5. data/README.md +25 -18
  6. data/Rakefile +28 -5
  7. data/lib/config/locales/en.yml +76 -50
  8. data/lib/mongoid/association/accessors.rb +417 -0
  9. data/lib/mongoid/{relations/binding.rb → association/bindable.rb} +39 -57
  10. data/lib/mongoid/association/builders.rb +93 -0
  11. data/lib/mongoid/association/constrainable.rb +46 -0
  12. data/lib/mongoid/association/depending.rb +140 -0
  13. data/lib/mongoid/{relations/eager.rb → association/eager_loadable.rb} +13 -11
  14. data/lib/mongoid/{relations → association}/embedded/batchable.rb +23 -21
  15. data/lib/mongoid/association/embedded/cyclic.rb +111 -0
  16. data/lib/mongoid/association/embedded/embedded_in/binding.rb +59 -0
  17. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +41 -0
  18. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +124 -0
  19. data/lib/mongoid/association/embedded/embedded_in.rb +157 -0
  20. data/lib/mongoid/{relations/bindings/embedded/many.rb → association/embedded/embeds_many/binding.rb} +14 -9
  21. data/lib/mongoid/{relations/builders/embedded/many.rb → association/embedded/embeds_many/buildable.rb} +19 -7
  22. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +555 -0
  23. data/lib/mongoid/association/embedded/embeds_many.rb +214 -0
  24. data/lib/mongoid/{relations/bindings/embedded/one.rb → association/embedded/embeds_one/binding.rb} +15 -10
  25. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +42 -0
  26. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +133 -0
  27. data/lib/mongoid/association/embedded/embeds_one.rb +177 -0
  28. data/lib/mongoid/association/embedded.rb +7 -0
  29. data/lib/mongoid/association/macros.rb +206 -0
  30. data/lib/mongoid/{relations → association}/many.rb +32 -59
  31. data/lib/mongoid/{relations → association}/marshalable.rb +9 -5
  32. data/lib/mongoid/association/nested/many.rb +202 -0
  33. data/lib/mongoid/association/nested/nested_buildable.rb +75 -0
  34. data/lib/mongoid/association/nested/one.rb +129 -0
  35. data/lib/mongoid/association/nested.rb +18 -0
  36. data/lib/mongoid/{relations → association}/one.rb +9 -7
  37. data/lib/mongoid/association/options.rb +155 -0
  38. data/lib/mongoid/{relations → association}/proxy.rb +59 -69
  39. data/lib/mongoid/association/referenced/auto_save.rb +82 -0
  40. data/lib/mongoid/association/referenced/belongs_to/binding.rb +89 -0
  41. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +49 -0
  42. data/lib/mongoid/association/referenced/belongs_to/eager.rb +74 -0
  43. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +138 -0
  44. data/lib/mongoid/association/referenced/belongs_to.rb +251 -0
  45. data/lib/mongoid/association/referenced/counter_cache.rb +165 -0
  46. data/lib/mongoid/association/referenced/eager.rb +184 -0
  47. data/lib/mongoid/association/referenced/has_and_belongs_to_many/binding.rb +77 -0
  48. data/lib/mongoid/association/referenced/has_and_belongs_to_many/buildable.rb +43 -0
  49. data/lib/mongoid/association/referenced/has_and_belongs_to_many/eager.rb +54 -0
  50. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +319 -0
  51. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +297 -0
  52. data/lib/mongoid/{relations/bindings/referenced/many.rb → association/referenced/has_many/binding.rb} +9 -6
  53. data/lib/mongoid/association/referenced/has_many/buildable.rb +41 -0
  54. data/lib/mongoid/association/referenced/has_many/eager.rb +45 -0
  55. data/lib/mongoid/association/referenced/has_many/enumerable.rb +517 -0
  56. data/lib/mongoid/association/referenced/has_many/proxy.rb +581 -0
  57. data/lib/mongoid/association/referenced/has_many.rb +278 -0
  58. data/lib/mongoid/{relations/bindings/referenced/one.rb → association/referenced/has_one/binding.rb} +14 -9
  59. data/lib/mongoid/association/referenced/has_one/buildable.rb +67 -0
  60. data/lib/mongoid/association/referenced/has_one/eager.rb +37 -0
  61. data/lib/mongoid/{relations/builders/nested_attributes/one.rb → association/referenced/has_one/nested_builder.rb} +20 -18
  62. data/lib/mongoid/association/referenced/has_one/proxy.rb +120 -0
  63. data/lib/mongoid/association/referenced/has_one.rb +207 -0
  64. data/lib/mongoid/association/referenced/syncable.rb +172 -0
  65. data/lib/mongoid/association/referenced.rb +10 -0
  66. data/lib/mongoid/association/reflections.rb +70 -0
  67. data/lib/mongoid/association/relatable.rb +514 -0
  68. data/lib/mongoid/association.rb +152 -0
  69. data/lib/mongoid/atomic/modifiers.rb +24 -1
  70. data/lib/mongoid/atomic/paths/embedded/many.rb +5 -3
  71. data/lib/mongoid/atomic/paths/embedded/one.rb +5 -3
  72. data/lib/mongoid/atomic/paths/embedded.rb +3 -1
  73. data/lib/mongoid/atomic/paths/root.rb +4 -2
  74. data/lib/mongoid/atomic/paths.rb +2 -0
  75. data/lib/mongoid/atomic.rb +16 -4
  76. data/lib/mongoid/attributes/dynamic.rb +18 -15
  77. data/lib/mongoid/attributes/nested.rb +29 -16
  78. data/lib/mongoid/attributes/processing.rb +10 -8
  79. data/lib/mongoid/attributes/readonly.rb +5 -5
  80. data/lib/mongoid/attributes.rb +62 -44
  81. data/lib/mongoid/cacheable.rb +3 -1
  82. data/lib/mongoid/changeable.rb +4 -2
  83. data/lib/mongoid/clients/factory.rb +3 -2
  84. data/lib/mongoid/clients/options.rb +17 -13
  85. data/lib/mongoid/clients/sessions.rb +23 -4
  86. data/lib/mongoid/clients/storage_options.rb +7 -5
  87. data/lib/mongoid/clients/validators/storage.rb +2 -0
  88. data/lib/mongoid/clients/validators.rb +2 -0
  89. data/lib/mongoid/clients.rb +2 -0
  90. data/lib/mongoid/composable.rb +8 -6
  91. data/lib/mongoid/config/environment.rb +23 -8
  92. data/lib/mongoid/config/options.rb +20 -12
  93. data/lib/mongoid/config/validators/client.rb +2 -0
  94. data/lib/mongoid/config/validators/option.rb +2 -0
  95. data/lib/mongoid/config/validators.rb +2 -0
  96. data/lib/mongoid/config.rb +53 -9
  97. data/lib/mongoid/contextual/aggregable/memory.rb +3 -1
  98. data/lib/mongoid/contextual/aggregable/mongo.rb +3 -1
  99. data/lib/mongoid/contextual/atomic.rb +24 -6
  100. data/lib/mongoid/contextual/command.rb +2 -0
  101. data/lib/mongoid/contextual/geo_near.rb +6 -4
  102. data/lib/mongoid/contextual/map_reduce.rb +5 -2
  103. data/lib/mongoid/contextual/memory.rb +23 -3
  104. data/lib/mongoid/contextual/mongo.rb +16 -9
  105. data/lib/mongoid/contextual/none.rb +2 -0
  106. data/lib/mongoid/contextual/queryable.rb +2 -0
  107. data/lib/mongoid/contextual.rb +7 -4
  108. data/lib/mongoid/copyable.rb +14 -7
  109. data/lib/mongoid/criteria/findable.rb +11 -1
  110. data/lib/mongoid/criteria/includable.rb +21 -19
  111. data/lib/mongoid/criteria/inspectable.rb +2 -0
  112. data/lib/mongoid/criteria/marshalable.rb +2 -0
  113. data/lib/mongoid/criteria/modifiable.rb +10 -3
  114. data/lib/mongoid/criteria/options.rb +4 -2
  115. data/lib/mongoid/criteria/permission.rb +2 -0
  116. data/lib/mongoid/criteria/queryable/aggregable.rb +2 -0
  117. data/lib/mongoid/criteria/queryable/expandable.rb +93 -0
  118. data/lib/mongoid/criteria/queryable/extensions/array.rb +3 -1
  119. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +3 -1
  120. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +2 -0
  121. data/lib/mongoid/criteria/queryable/extensions/date.rb +3 -1
  122. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +5 -6
  123. data/lib/mongoid/criteria/queryable/extensions/hash.rb +3 -1
  124. data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +3 -1
  125. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +4 -2
  126. data/lib/mongoid/criteria/queryable/extensions/object.rb +3 -1
  127. data/lib/mongoid/criteria/queryable/extensions/range.rb +3 -1
  128. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +9 -7
  129. data/lib/mongoid/criteria/queryable/extensions/set.rb +3 -1
  130. data/lib/mongoid/criteria/queryable/extensions/string.rb +4 -2
  131. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +3 -1
  132. data/lib/mongoid/criteria/queryable/extensions/time.rb +4 -2
  133. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +15 -1
  134. data/lib/mongoid/criteria/queryable/extensions.rb +2 -0
  135. data/lib/mongoid/criteria/queryable/key.rb +101 -14
  136. data/lib/mongoid/criteria/queryable/macroable.rb +3 -1
  137. data/lib/mongoid/criteria/queryable/mergeable.rb +158 -15
  138. data/lib/mongoid/criteria/queryable/optional.rb +5 -3
  139. data/lib/mongoid/criteria/queryable/options.rb +2 -0
  140. data/lib/mongoid/criteria/queryable/pipeline.rb +14 -6
  141. data/lib/mongoid/criteria/queryable/selectable.rb +376 -90
  142. data/lib/mongoid/criteria/queryable/selector.rb +43 -36
  143. data/lib/mongoid/criteria/queryable/smash.rb +2 -0
  144. data/lib/mongoid/criteria/queryable/storable.rb +233 -0
  145. data/lib/mongoid/criteria/queryable.rb +7 -2
  146. data/lib/mongoid/criteria/scopable.rb +2 -0
  147. data/lib/mongoid/criteria.rb +27 -6
  148. data/lib/mongoid/document.rb +16 -4
  149. data/lib/mongoid/equality.rb +3 -2
  150. data/lib/mongoid/errors/ambiguous_relationship.rb +4 -2
  151. data/lib/mongoid/errors/callback.rb +2 -0
  152. data/lib/mongoid/errors/criteria_argument_required.rb +19 -0
  153. data/lib/mongoid/errors/delete_restriction.rb +3 -2
  154. data/lib/mongoid/errors/document_not_destroyed.rb +2 -0
  155. data/lib/mongoid/errors/document_not_found.rb +2 -0
  156. data/lib/mongoid/errors/eager_load.rb +6 -2
  157. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +2 -0
  158. data/lib/mongoid/errors/invalid_collection.rb +2 -0
  159. data/lib/mongoid/errors/invalid_config_option.rb +2 -0
  160. data/lib/mongoid/errors/invalid_dependent_strategy.rb +34 -0
  161. data/lib/mongoid/errors/invalid_field.rb +2 -0
  162. data/lib/mongoid/errors/invalid_field_option.rb +2 -0
  163. data/lib/mongoid/errors/invalid_find.rb +2 -0
  164. data/lib/mongoid/errors/invalid_includes.rb +2 -0
  165. data/lib/mongoid/errors/invalid_index.rb +2 -0
  166. data/lib/mongoid/errors/invalid_options.rb +4 -2
  167. data/lib/mongoid/errors/invalid_path.rb +2 -0
  168. data/lib/mongoid/errors/invalid_persistence_option.rb +2 -0
  169. data/lib/mongoid/errors/invalid_relation.rb +4 -2
  170. data/lib/mongoid/errors/invalid_relation_option.rb +31 -0
  171. data/lib/mongoid/errors/invalid_scope.rb +2 -0
  172. data/lib/mongoid/errors/invalid_session_use.rb +2 -0
  173. data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +6 -4
  174. data/lib/mongoid/errors/invalid_storage_options.rb +2 -0
  175. data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
  176. data/lib/mongoid/errors/invalid_time.rb +2 -0
  177. data/lib/mongoid/errors/invalid_value.rb +2 -0
  178. data/lib/mongoid/errors/inverse_not_found.rb +3 -1
  179. data/lib/mongoid/errors/mixed_client_configuration.rb +2 -0
  180. data/lib/mongoid/errors/mixed_relations.rb +2 -0
  181. data/lib/mongoid/errors/mongoid_error.rb +2 -0
  182. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +3 -1
  183. data/lib/mongoid/errors/no_client_config.rb +4 -2
  184. data/lib/mongoid/errors/no_client_database.rb +2 -0
  185. data/lib/mongoid/errors/no_client_hosts.rb +2 -0
  186. data/lib/mongoid/errors/no_clients_config.rb +2 -0
  187. data/lib/mongoid/errors/no_default_client.rb +3 -1
  188. data/lib/mongoid/errors/no_environment.rb +2 -0
  189. data/lib/mongoid/errors/no_map_reduce_output.rb +2 -0
  190. data/lib/mongoid/errors/no_metadata.rb +2 -0
  191. data/lib/mongoid/errors/no_parent.rb +2 -0
  192. data/lib/mongoid/errors/readonly_attribute.rb +2 -0
  193. data/lib/mongoid/errors/readonly_document.rb +2 -0
  194. data/lib/mongoid/errors/scope_overwrite.rb +2 -0
  195. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +3 -0
  196. data/lib/mongoid/errors/unknown_attribute.rb +2 -0
  197. data/lib/mongoid/errors/unknown_model.rb +27 -0
  198. data/lib/mongoid/errors/unsaved_document.rb +2 -0
  199. data/lib/mongoid/errors/unsupported_javascript.rb +2 -0
  200. data/lib/mongoid/errors/validations.rb +2 -0
  201. data/lib/mongoid/errors.rb +6 -0
  202. data/lib/mongoid/evolvable.rb +3 -1
  203. data/lib/mongoid/extensions/array.rb +28 -11
  204. data/lib/mongoid/extensions/big_decimal.rb +2 -0
  205. data/lib/mongoid/extensions/boolean.rb +2 -0
  206. data/lib/mongoid/extensions/date.rb +13 -3
  207. data/lib/mongoid/extensions/date_time.rb +4 -3
  208. data/lib/mongoid/extensions/decimal128.rb +2 -0
  209. data/lib/mongoid/extensions/false_class.rb +2 -0
  210. data/lib/mongoid/extensions/float.rb +5 -3
  211. data/lib/mongoid/extensions/hash.rb +56 -11
  212. data/lib/mongoid/extensions/integer.rb +5 -3
  213. data/lib/mongoid/extensions/module.rb +2 -0
  214. data/lib/mongoid/extensions/nil_class.rb +2 -0
  215. data/lib/mongoid/extensions/object.rb +20 -8
  216. data/lib/mongoid/extensions/object_id.rb +2 -0
  217. data/lib/mongoid/extensions/range.rb +3 -0
  218. data/lib/mongoid/extensions/regexp.rb +3 -1
  219. data/lib/mongoid/extensions/set.rb +2 -0
  220. data/lib/mongoid/extensions/string.rb +23 -12
  221. data/lib/mongoid/extensions/symbol.rb +2 -0
  222. data/lib/mongoid/extensions/time.rb +14 -0
  223. data/lib/mongoid/extensions/time_with_zone.rb +14 -0
  224. data/lib/mongoid/extensions/true_class.rb +2 -0
  225. data/lib/mongoid/extensions.rb +2 -4
  226. data/lib/mongoid/factory.rb +38 -5
  227. data/lib/mongoid/fields/foreign_key.rb +8 -6
  228. data/lib/mongoid/fields/localized.rb +2 -0
  229. data/lib/mongoid/fields/standard.rb +8 -17
  230. data/lib/mongoid/fields/validators/macro.rb +17 -3
  231. data/lib/mongoid/fields/validators.rb +2 -0
  232. data/lib/mongoid/fields.rb +8 -5
  233. data/lib/mongoid/findable.rb +9 -4
  234. data/lib/mongoid/indexable/specification.rb +3 -1
  235. data/lib/mongoid/indexable/validators/options.rb +2 -0
  236. data/lib/mongoid/indexable.rb +7 -2
  237. data/lib/mongoid/inspectable.rb +3 -1
  238. data/lib/mongoid/interceptable.rb +17 -9
  239. data/lib/mongoid/loggable.rb +13 -7
  240. data/lib/mongoid/matchable/all.rb +6 -3
  241. data/lib/mongoid/matchable/and.rb +3 -1
  242. data/lib/mongoid/matchable/default.rb +73 -24
  243. data/lib/mongoid/matchable/elem_match.rb +11 -3
  244. data/lib/mongoid/matchable/eq.rb +23 -0
  245. data/lib/mongoid/matchable/exists.rb +2 -0
  246. data/lib/mongoid/matchable/gt.rb +2 -0
  247. data/lib/mongoid/matchable/gte.rb +2 -0
  248. data/lib/mongoid/matchable/in.rb +2 -0
  249. data/lib/mongoid/matchable/lt.rb +2 -0
  250. data/lib/mongoid/matchable/lte.rb +2 -0
  251. data/lib/mongoid/matchable/ne.rb +3 -1
  252. data/lib/mongoid/matchable/nin.rb +2 -0
  253. data/lib/mongoid/matchable/nor.rb +2 -1
  254. data/lib/mongoid/matchable/or.rb +2 -0
  255. data/lib/mongoid/matchable/regexp.rb +5 -2
  256. data/lib/mongoid/matchable/size.rb +2 -0
  257. data/lib/mongoid/matchable.rb +19 -16
  258. data/lib/mongoid/persistable/creatable.rb +3 -1
  259. data/lib/mongoid/persistable/deletable.rb +10 -7
  260. data/lib/mongoid/persistable/destroyable.rb +3 -1
  261. data/lib/mongoid/persistable/incrementable.rb +7 -3
  262. data/lib/mongoid/persistable/logical.rb +5 -2
  263. data/lib/mongoid/persistable/poppable.rb +3 -1
  264. data/lib/mongoid/persistable/pullable.rb +3 -1
  265. data/lib/mongoid/persistable/pushable.rb +14 -3
  266. data/lib/mongoid/persistable/renamable.rb +10 -3
  267. data/lib/mongoid/persistable/savable.rb +3 -1
  268. data/lib/mongoid/persistable/settable.rb +60 -13
  269. data/lib/mongoid/persistable/unsettable.rb +8 -3
  270. data/lib/mongoid/persistable/updatable.rb +3 -1
  271. data/lib/mongoid/persistable/upsertable.rb +3 -1
  272. data/lib/mongoid/persistable.rb +136 -19
  273. data/lib/mongoid/persistence_context.rb +47 -20
  274. data/lib/mongoid/positional.rb +3 -1
  275. data/lib/mongoid/query_cache.rb +76 -29
  276. data/lib/mongoid/railtie.rb +3 -1
  277. data/lib/mongoid/railties/controller_runtime.rb +4 -1
  278. data/lib/mongoid/railties/database.rake +9 -0
  279. data/lib/mongoid/reloadable.rb +4 -2
  280. data/lib/mongoid/scopable.rb +2 -1
  281. data/lib/mongoid/selectable.rb +3 -1
  282. data/lib/mongoid/serializable.rb +27 -17
  283. data/lib/mongoid/shardable.rb +60 -6
  284. data/lib/mongoid/stateful.rb +3 -1
  285. data/lib/mongoid/tasks/database.rake +12 -5
  286. data/lib/mongoid/tasks/database.rb +85 -0
  287. data/lib/mongoid/threaded/lifecycle.rb +2 -0
  288. data/lib/mongoid/threaded.rb +2 -0
  289. data/lib/mongoid/timestamps/created/short.rb +2 -0
  290. data/lib/mongoid/timestamps/created.rb +3 -1
  291. data/lib/mongoid/timestamps/short.rb +2 -0
  292. data/lib/mongoid/timestamps/timeless.rb +6 -2
  293. data/lib/mongoid/timestamps/updated/short.rb +2 -0
  294. data/lib/mongoid/timestamps/updated.rb +3 -1
  295. data/lib/mongoid/timestamps.rb +3 -1
  296. data/lib/mongoid/touchable.rb +110 -0
  297. data/lib/mongoid/traversable.rb +7 -5
  298. data/lib/mongoid/validatable/associated.rb +4 -2
  299. data/lib/mongoid/validatable/format.rb +2 -0
  300. data/lib/mongoid/validatable/length.rb +2 -0
  301. data/lib/mongoid/validatable/localizable.rb +2 -0
  302. data/lib/mongoid/validatable/macros.rb +3 -1
  303. data/lib/mongoid/validatable/presence.rb +6 -4
  304. data/lib/mongoid/validatable/queryable.rb +2 -0
  305. data/lib/mongoid/validatable/uniqueness.rb +9 -7
  306. data/lib/mongoid/validatable.rb +15 -13
  307. data/lib/mongoid/version.rb +3 -1
  308. data/lib/mongoid.rb +11 -2
  309. data/lib/rails/generators/mongoid/config/config_generator.rb +2 -0
  310. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +44 -26
  311. data/lib/rails/generators/mongoid/model/model_generator.rb +3 -1
  312. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +1 -1
  313. data/lib/rails/generators/mongoid_generator.rb +2 -0
  314. data/lib/rails/mongoid.rb +4 -2
  315. data/lib/support/ruby_version.rb +3 -0
  316. data/spec/README.md +18 -0
  317. data/spec/app/models/account.rb +3 -0
  318. data/spec/app/models/acolyte.rb +3 -0
  319. data/spec/app/models/actor.rb +3 -0
  320. data/spec/app/models/actress.rb +3 -0
  321. data/spec/app/models/address.rb +3 -0
  322. data/spec/app/models/address_component.rb +3 -0
  323. data/spec/app/models/address_number.rb +3 -0
  324. data/spec/app/models/agency.rb +3 -0
  325. data/spec/app/models/agent.rb +3 -0
  326. data/spec/app/models/album.rb +3 -0
  327. data/spec/app/models/alert.rb +3 -0
  328. data/spec/app/models/animal.rb +5 -1
  329. data/spec/app/models/answer.rb +3 -0
  330. data/spec/app/models/appointment.rb +3 -0
  331. data/spec/app/models/array_field.rb +1 -0
  332. data/spec/app/models/article.rb +3 -0
  333. data/spec/app/models/artist.rb +3 -0
  334. data/spec/app/models/artwork.rb +3 -0
  335. data/spec/app/models/audio.rb +3 -0
  336. data/spec/app/models/augmentation.rb +3 -0
  337. data/spec/app/models/author.rb +3 -0
  338. data/spec/app/models/baby.rb +3 -0
  339. data/spec/app/models/band.rb +3 -0
  340. data/spec/app/models/bar.rb +3 -0
  341. data/spec/app/models/basic.rb +3 -0
  342. data/spec/app/models/bed.rb +3 -0
  343. data/spec/app/models/big_palette.rb +3 -0
  344. data/spec/app/models/birthday.rb +3 -0
  345. data/spec/app/models/bomb.rb +4 -1
  346. data/spec/app/models/book.rb +3 -0
  347. data/spec/app/models/breed.rb +3 -0
  348. data/spec/app/models/browser.rb +3 -0
  349. data/spec/app/models/building.rb +3 -0
  350. data/spec/app/models/building_address.rb +3 -0
  351. data/spec/app/models/bus.rb +3 -0
  352. data/spec/app/models/business.rb +3 -0
  353. data/spec/app/models/callback_test.rb +3 -0
  354. data/spec/app/models/canvas.rb +3 -0
  355. data/spec/app/models/car.rb +3 -0
  356. data/spec/app/models/cat.rb +3 -0
  357. data/spec/app/models/category.rb +3 -0
  358. data/spec/app/models/child.rb +3 -0
  359. data/spec/app/models/child_doc.rb +3 -0
  360. data/spec/app/models/church.rb +3 -0
  361. data/spec/app/models/circle.rb +3 -0
  362. data/spec/app/models/circuit.rb +3 -0
  363. data/spec/app/models/circus.rb +3 -0
  364. data/spec/app/models/code.rb +3 -0
  365. data/spec/app/models/coding/pull_request.rb +12 -0
  366. data/spec/app/models/coding.rb +4 -0
  367. data/spec/app/models/comment.rb +3 -0
  368. data/spec/app/models/company.rb +3 -0
  369. data/spec/app/models/consumption_period.rb +3 -0
  370. data/spec/app/models/contextable_item.rb +3 -0
  371. data/spec/app/models/contractor.rb +3 -0
  372. data/spec/app/models/cookie.rb +3 -0
  373. data/spec/app/models/country_code.rb +3 -0
  374. data/spec/app/models/courier_job.rb +3 -0
  375. data/spec/app/models/customer.rb +11 -0
  376. data/spec/app/models/customer_address.rb +12 -0
  377. data/spec/app/models/definition.rb +3 -0
  378. data/spec/app/models/delegating_patient.rb +16 -0
  379. data/spec/app/models/description.rb +3 -0
  380. data/spec/app/models/dictionary.rb +9 -0
  381. data/spec/app/models/division.rb +3 -0
  382. data/spec/app/models/doctor.rb +3 -0
  383. data/spec/app/models/dog.rb +3 -0
  384. data/spec/app/models/dokument.rb +3 -0
  385. data/spec/app/models/draft.rb +3 -0
  386. data/spec/app/models/dragon.rb +3 -0
  387. data/spec/app/models/driver.rb +3 -0
  388. data/spec/app/models/drug.rb +3 -0
  389. data/spec/app/models/dungeon.rb +3 -0
  390. data/spec/app/models/edit.rb +3 -0
  391. data/spec/app/models/email.rb +3 -0
  392. data/spec/app/models/employer.rb +3 -0
  393. data/spec/app/models/entry.rb +3 -0
  394. data/spec/app/models/eraser.rb +3 -0
  395. data/spec/app/models/even.rb +3 -0
  396. data/spec/app/models/event.rb +3 -0
  397. data/spec/app/models/exhibition.rb +3 -0
  398. data/spec/app/models/exhibitor.rb +3 -0
  399. data/spec/app/models/explosion.rb +3 -0
  400. data/spec/app/models/eye.rb +3 -0
  401. data/spec/app/models/eye_bowl.rb +3 -0
  402. data/spec/app/models/face.rb +3 -0
  403. data/spec/app/models/favorite.rb +3 -0
  404. data/spec/app/models/filesystem.rb +3 -0
  405. data/spec/app/models/fire_hydrant.rb +3 -0
  406. data/spec/app/models/firefox.rb +3 -0
  407. data/spec/app/models/fish.rb +3 -0
  408. data/spec/app/models/folder.rb +3 -0
  409. data/spec/app/models/folder_item.rb +3 -0
  410. data/spec/app/models/fruits.rb +3 -0
  411. data/spec/app/models/game.rb +3 -0
  412. data/spec/app/models/ghost.rb +3 -0
  413. data/spec/app/models/home.rb +3 -0
  414. data/spec/app/models/house.rb +3 -0
  415. data/spec/app/models/html_writer.rb +3 -0
  416. data/spec/app/models/id_key.rb +3 -0
  417. data/spec/app/models/image.rb +3 -0
  418. data/spec/app/models/implant.rb +3 -0
  419. data/spec/app/models/item.rb +3 -0
  420. data/spec/app/models/jar.rb +3 -0
  421. data/spec/app/models/kaleidoscope.rb +3 -0
  422. data/spec/app/models/kangaroo.rb +4 -1
  423. data/spec/app/models/label.rb +3 -0
  424. data/spec/app/models/language.rb +3 -0
  425. data/spec/app/models/lat_lng.rb +3 -0
  426. data/spec/app/models/league.rb +3 -0
  427. data/spec/app/models/learner.rb +3 -0
  428. data/spec/app/models/line_item.rb +3 -0
  429. data/spec/app/models/location.rb +3 -0
  430. data/spec/app/models/login.rb +3 -0
  431. data/spec/app/models/manufacturer.rb +3 -0
  432. data/spec/app/models/meat.rb +3 -0
  433. data/spec/app/models/membership.rb +3 -0
  434. data/spec/app/models/message.rb +4 -1
  435. data/spec/app/models/minim.rb +7 -0
  436. data/spec/app/models/mixed_drink.rb +3 -0
  437. data/spec/app/models/movie.rb +3 -0
  438. data/spec/app/models/my_hash.rb +3 -0
  439. data/spec/app/models/name.rb +3 -0
  440. data/spec/app/models/name_only.rb +9 -0
  441. data/spec/app/models/node.rb +3 -0
  442. data/spec/app/models/note.rb +3 -0
  443. data/spec/app/models/odd.rb +3 -0
  444. data/spec/app/models/ordered_post.rb +3 -0
  445. data/spec/app/models/ordered_preference.rb +3 -0
  446. data/spec/app/models/oscar.rb +3 -0
  447. data/spec/app/models/other_owner_object.rb +5 -0
  448. data/spec/app/models/override.rb +3 -0
  449. data/spec/app/models/ownable.rb +3 -0
  450. data/spec/app/models/owner.rb +3 -0
  451. data/spec/app/models/pack.rb +3 -0
  452. data/spec/app/models/page.rb +3 -0
  453. data/spec/app/models/page_question.rb +3 -0
  454. data/spec/app/models/palette.rb +3 -0
  455. data/spec/app/models/parent.rb +3 -0
  456. data/spec/app/models/parent_doc.rb +3 -0
  457. data/spec/app/models/passport.rb +4 -0
  458. data/spec/app/models/patient.rb +3 -0
  459. data/spec/app/models/pdf_writer.rb +3 -0
  460. data/spec/app/models/pencil.rb +3 -0
  461. data/spec/app/models/person.rb +10 -2
  462. data/spec/app/models/pet.rb +3 -0
  463. data/spec/app/models/pet_owner.rb +3 -0
  464. data/spec/app/models/phone.rb +4 -0
  465. data/spec/app/models/pizza.rb +3 -0
  466. data/spec/app/models/player.rb +3 -0
  467. data/spec/app/models/post.rb +3 -0
  468. data/spec/app/models/post_genre.rb +3 -0
  469. data/spec/app/models/powerup.rb +3 -0
  470. data/spec/app/models/preference.rb +3 -0
  471. data/spec/app/models/princess.rb +3 -0
  472. data/spec/app/models/product.rb +3 -0
  473. data/spec/app/models/profile.rb +3 -0
  474. data/spec/app/models/pronunciation.rb +3 -0
  475. data/spec/app/models/pub.rb +3 -0
  476. data/spec/app/models/publication/encyclopedia.rb +12 -0
  477. data/spec/app/models/publication/review.rb +14 -0
  478. data/spec/app/models/publication.rb +5 -0
  479. data/spec/app/models/purchase.rb +3 -0
  480. data/spec/app/models/question.rb +3 -0
  481. data/spec/app/models/quiz.rb +3 -0
  482. data/spec/app/models/rating.rb +3 -0
  483. data/spec/app/models/record.rb +3 -0
  484. data/spec/app/models/registry.rb +3 -0
  485. data/spec/app/models/role.rb +3 -0
  486. data/spec/app/models/root_category.rb +3 -0
  487. data/spec/app/models/sandwich.rb +3 -0
  488. data/spec/app/models/scheduler.rb +3 -0
  489. data/spec/app/models/seo.rb +3 -0
  490. data/spec/app/models/series.rb +4 -0
  491. data/spec/app/models/server.rb +3 -0
  492. data/spec/app/models/service.rb +3 -0
  493. data/spec/app/models/shape.rb +3 -0
  494. data/spec/app/models/shelf.rb +3 -0
  495. data/spec/app/models/shipment_address.rb +4 -0
  496. data/spec/app/models/shipping_container.rb +3 -0
  497. data/spec/app/models/shipping_pack.rb +3 -0
  498. data/spec/app/models/shop.rb +3 -0
  499. data/spec/app/models/short_agent.rb +3 -0
  500. data/spec/app/models/short_quiz.rb +3 -0
  501. data/spec/app/models/simple.rb +3 -0
  502. data/spec/app/models/slave.rb +3 -0
  503. data/spec/app/models/song.rb +3 -0
  504. data/spec/app/models/sound.rb +3 -0
  505. data/spec/app/models/square.rb +3 -0
  506. data/spec/app/models/staff.rb +3 -0
  507. data/spec/app/models/store_as_dup_test1.rb +3 -0
  508. data/spec/app/models/store_as_dup_test2.rb +3 -0
  509. data/spec/app/models/store_as_dup_test3.rb +8 -0
  510. data/spec/app/models/store_as_dup_test4.rb +8 -0
  511. data/spec/app/models/strategy.rb +3 -0
  512. data/spec/app/models/sub_item.rb +3 -0
  513. data/spec/app/models/subscription.rb +3 -0
  514. data/spec/app/models/survey.rb +3 -0
  515. data/spec/app/models/symptom.rb +3 -0
  516. data/spec/app/models/tag.rb +3 -0
  517. data/spec/app/models/target.rb +3 -0
  518. data/spec/app/models/template.rb +3 -0
  519. data/spec/app/models/thing.rb +3 -0
  520. data/spec/app/models/title.rb +3 -0
  521. data/spec/app/models/tool.rb +3 -0
  522. data/spec/app/models/topping.rb +3 -0
  523. data/spec/app/models/track.rb +3 -0
  524. data/spec/app/models/translation.rb +3 -0
  525. data/spec/app/models/tree.rb +3 -0
  526. data/spec/app/models/truck.rb +3 -0
  527. data/spec/app/models/updatable.rb +8 -0
  528. data/spec/app/models/user.rb +3 -0
  529. data/spec/app/models/user_account.rb +3 -0
  530. data/spec/app/models/validation_callback.rb +3 -0
  531. data/spec/app/models/vehicle.rb +3 -0
  532. data/spec/app/models/version.rb +3 -0
  533. data/spec/app/models/vertex.rb +9 -0
  534. data/spec/app/models/vet_visit.rb +3 -0
  535. data/spec/app/models/video.rb +3 -0
  536. data/spec/app/models/video_game.rb +3 -0
  537. data/spec/app/models/weapon.rb +3 -0
  538. data/spec/app/models/wiki_page.rb +5 -1
  539. data/spec/app/models/word.rb +3 -0
  540. data/spec/app/models/word_origin.rb +3 -0
  541. data/spec/app/models/writer.rb +3 -0
  542. data/spec/config/mongoid.yml +14 -3
  543. data/spec/integration/app_spec.rb +287 -0
  544. data/spec/integration/associations/belongs_to_spec.rb +16 -0
  545. data/spec/integration/associations/embedded_spec.rb +175 -0
  546. data/spec/integration/associations/embeds_many_spec.rb +24 -0
  547. data/spec/integration/associations/embeds_one_spec.rb +24 -0
  548. data/spec/integration/associations/foreign_key_spec.rb +99 -0
  549. data/spec/integration/associations/foreign_key_spec_models.rb +65 -0
  550. data/spec/integration/associations/has_many_spec.rb +76 -0
  551. data/spec/integration/associations/has_one_spec.rb +76 -0
  552. data/spec/integration/associations/reverse_population_spec.rb +35 -0
  553. data/spec/integration/associations/reverse_population_spec_models.rb +37 -0
  554. data/spec/integration/bson_regexp_raw_spec.rb +20 -0
  555. data/spec/integration/callbacks_models.rb +49 -0
  556. data/spec/integration/callbacks_spec.rb +216 -0
  557. data/spec/integration/criteria/date_field_spec.rb +41 -0
  558. data/spec/integration/criteria/default_scope_spec.rb +21 -0
  559. data/spec/integration/criteria/logical_spec.rb +94 -0
  560. data/spec/integration/criteria/time_with_zone_spec.rb +32 -0
  561. data/spec/integration/document_spec.rb +22 -0
  562. data/spec/integration/i18n_fallbacks_spec.rb +90 -0
  563. data/spec/integration/matchable_spec.rb +680 -0
  564. data/spec/integration/shardable_spec.rb +149 -0
  565. data/spec/lite_spec_helper.rb +75 -0
  566. data/spec/mongoid/{relations → association}/accessors_spec.rb +281 -64
  567. data/spec/mongoid/{relations → association}/auto_save_spec.rb +63 -12
  568. data/spec/mongoid/{relations → association}/builders_spec.rb +4 -1
  569. data/spec/mongoid/association/constrainable_spec.rb +118 -0
  570. data/spec/mongoid/{relations → association}/counter_cache_spec.rb +4 -1
  571. data/spec/mongoid/association/depending_spec.rb +869 -0
  572. data/spec/mongoid/{relations → association}/eager_spec.rb +15 -12
  573. data/spec/mongoid/{relations → association/embedded}/cyclic_spec.rb +4 -1
  574. data/spec/mongoid/{relations → association}/embedded/dirty_spec.rb +3 -0
  575. data/spec/mongoid/{relations/bindings/embedded/in_spec.rb → association/embedded/embedded_in/binding_spec.rb} +16 -13
  576. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +37 -0
  577. data/spec/mongoid/{relations/embedded/in_spec.rb → association/embedded/embedded_in/proxy_spec.rb} +58 -77
  578. data/spec/mongoid/association/embedded/embedded_in_spec.rb +904 -0
  579. data/spec/mongoid/{relations/bindings/embedded/many_spec.rb → association/embedded/embeds_many/binding_spec.rb} +6 -3
  580. data/spec/mongoid/{relations/builders/embedded/many_spec.rb → association/embedded/embeds_many/buildable_spec.rb} +20 -45
  581. data/spec/mongoid/{relations/embedded/many_spec.rb → association/embedded/embeds_many/proxy_spec.rb} +127 -182
  582. data/spec/mongoid/association/embedded/embeds_many_models.rb +53 -0
  583. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +52 -0
  584. data/spec/mongoid/association/embedded/embeds_many_spec.rb +865 -0
  585. data/spec/mongoid/{relations/bindings/embedded/one_spec.rb → association/embedded/embeds_one/binding_spec.rb} +7 -4
  586. data/spec/mongoid/{relations/builders/embedded/one_spec.rb → association/embedded/embeds_one/buildable_spec.rb} +17 -34
  587. data/spec/mongoid/{relations/embedded/one_spec.rb → association/embedded/embeds_one/proxy_spec.rb} +42 -84
  588. data/spec/mongoid/association/embedded/embeds_one_dnl_models.rb +9 -0
  589. data/spec/mongoid/association/embedded/embeds_one_models.rb +54 -0
  590. data/spec/mongoid/association/embedded/embeds_one_query_spec.rb +29 -0
  591. data/spec/mongoid/association/embedded/embeds_one_spec.rb +957 -0
  592. data/spec/mongoid/{relations → association}/macros_spec.rb +151 -73
  593. data/spec/mongoid/{relations/builders/nested_attributes → association/nested}/many_spec.rb +19 -19
  594. data/spec/mongoid/{relations/builders/nested_attributes → association/nested}/one_spec.rb +20 -20
  595. data/spec/mongoid/association/options_spec.rb +1324 -0
  596. data/spec/mongoid/{relations → association}/polymorphic_spec.rb +69 -34
  597. data/spec/mongoid/{relations/bindings/referenced/in_spec.rb → association/referenced/belongs_to/binding_spec.rb} +10 -7
  598. data/spec/mongoid/{relations/builders/referenced/in_spec.rb → association/referenced/belongs_to/buildable_spec.rb} +49 -79
  599. data/spec/mongoid/association/referenced/belongs_to/eager_spec.rb +377 -0
  600. data/spec/mongoid/{relations/referenced/in_spec.rb → association/referenced/belongs_to/proxy_spec.rb} +60 -91
  601. data/spec/mongoid/association/referenced/belongs_to_query_spec.rb +38 -0
  602. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2026 -0
  603. data/spec/mongoid/{relations/bindings/referenced/many_to_many_spec.rb → association/referenced/has_and_belongs_to_many/binding_spec.rb} +8 -5
  604. data/spec/mongoid/association/referenced/has_and_belongs_to_many/buildable_spec.rb +124 -0
  605. data/spec/mongoid/{relations/eager/has_and_belongs_to_many_spec.rb → association/referenced/has_and_belongs_to_many/eager_spec.rb} +42 -7
  606. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_persistence_spec.rb +77 -0
  607. data/spec/mongoid/{relations/referenced/many_to_many_spec.rb → association/referenced/has_and_belongs_to_many/proxy_spec.rb} +283 -112
  608. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +50 -0
  609. data/spec/mongoid/association/referenced/has_and_belongs_to_many_query_spec.rb +40 -0
  610. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +1051 -0
  611. data/spec/mongoid/{relations/bindings/referenced/many_spec.rb → association/referenced/has_many/binding_spec.rb} +8 -5
  612. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +122 -0
  613. data/spec/mongoid/{relations/eager/has_many_spec.rb → association/referenced/has_many/eager_spec.rb} +43 -13
  614. data/spec/mongoid/{relations/targets → association/referenced/has_many}/enumerable_spec.rb +230 -1
  615. data/spec/mongoid/association/referenced/has_many/proxy_query_spec.rb +24 -0
  616. data/spec/mongoid/{relations/referenced/many_spec.rb → association/referenced/has_many/proxy_spec.rb} +33 -94
  617. data/spec/mongoid/association/referenced/has_many_models.rb +40 -0
  618. data/spec/mongoid/association/referenced/has_many_query_spec.rb +38 -0
  619. data/spec/mongoid/association/referenced/has_many_spec.rb +1228 -0
  620. data/spec/mongoid/{relations/bindings/referenced/one_spec.rb → association/referenced/has_one/binding_spec.rb} +7 -4
  621. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +116 -0
  622. data/spec/mongoid/{relations/eager/has_one_spec.rb → association/referenced/has_one/eager_spec.rb} +27 -12
  623. data/spec/mongoid/{relations/referenced/one_spec.rb → association/referenced/has_one/proxy_spec.rb} +12 -109
  624. data/spec/mongoid/association/referenced/has_one_models.rb +51 -0
  625. data/spec/mongoid/association/referenced/has_one_query_spec.rb +38 -0
  626. data/spec/mongoid/association/referenced/has_one_spec.rb +1363 -0
  627. data/spec/mongoid/{relations → association}/reflections_spec.rb +4 -12
  628. data/spec/mongoid/{relations/synchronization_spec.rb → association/syncable_spec.rb} +7 -2
  629. data/spec/mongoid/{relations_spec.rb → association_spec.rb} +4 -1
  630. data/spec/mongoid/atomic/modifiers_spec.rb +5 -2
  631. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +3 -0
  632. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +3 -0
  633. data/spec/mongoid/atomic/paths/root_spec.rb +3 -0
  634. data/spec/mongoid/atomic/paths_spec.rb +44 -0
  635. data/spec/mongoid/atomic_spec.rb +7 -4
  636. data/spec/mongoid/attributes/dynamic_spec.rb +153 -0
  637. data/spec/mongoid/attributes/nested_spec.rb +32 -11
  638. data/spec/mongoid/attributes/readonly_spec.rb +83 -125
  639. data/spec/mongoid/attributes_spec.rb +60 -9
  640. data/spec/mongoid/cacheable_spec.rb +3 -0
  641. data/spec/mongoid/changeable_spec.rb +26 -0
  642. data/spec/mongoid/clients/factory_spec.rb +57 -33
  643. data/spec/mongoid/clients/options_spec.rb +81 -56
  644. data/spec/mongoid/clients/sessions_spec.rb +24 -8
  645. data/spec/mongoid/clients/transactions_spec.rb +393 -0
  646. data/spec/mongoid/clients_spec.rb +73 -10
  647. data/spec/mongoid/composable_spec.rb +3 -0
  648. data/spec/mongoid/config/environment_spec.rb +3 -0
  649. data/spec/mongoid/config/options_spec.rb +23 -3
  650. data/spec/mongoid/config_spec.rb +66 -1
  651. data/spec/mongoid/contextual/aggregable/memory_spec.rb +3 -0
  652. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +3 -0
  653. data/spec/mongoid/contextual/atomic_spec.rb +120 -10
  654. data/spec/mongoid/contextual/geo_near_spec.rb +15 -2
  655. data/spec/mongoid/contextual/map_reduce_spec.rb +23 -5
  656. data/spec/mongoid/contextual/memory_spec.rb +22 -0
  657. data/spec/mongoid/contextual/mongo_spec.rb +113 -57
  658. data/spec/mongoid/contextual/none_spec.rb +3 -0
  659. data/spec/mongoid/copyable_spec.rb +93 -6
  660. data/spec/mongoid/copyable_spec_models.rb +20 -0
  661. data/spec/mongoid/criteria/findable_spec.rb +58 -0
  662. data/spec/mongoid/criteria/inspectable_spec.rb +3 -0
  663. data/spec/mongoid/criteria/marshalable_spec.rb +3 -0
  664. data/spec/mongoid/criteria/modifiable_spec.rb +180 -4
  665. data/spec/mongoid/criteria/options_spec.rb +3 -0
  666. data/spec/mongoid/criteria/queryable/aggregable_spec.rb +3 -0
  667. data/spec/mongoid/criteria/queryable/expandable_spec.rb +135 -0
  668. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +3 -0
  669. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +3 -0
  670. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +3 -0
  671. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +3 -0
  672. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +3 -0
  673. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +36 -17
  674. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +3 -0
  675. data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +3 -0
  676. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +3 -0
  677. data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +3 -0
  678. data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +3 -0
  679. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +54 -0
  680. data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +3 -0
  681. data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +3 -0
  682. data/spec/mongoid/criteria/queryable/extensions/regexp_raw_spec.rb +4 -1
  683. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +10 -7
  684. data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +3 -0
  685. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +47 -1
  686. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +3 -0
  687. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +43 -23
  688. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +31 -1
  689. data/spec/mongoid/criteria/queryable/key_spec.rb +51 -6
  690. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +48 -12
  691. data/spec/mongoid/criteria/queryable/optional_spec.rb +3 -0
  692. data/spec/mongoid/criteria/queryable/options_spec.rb +3 -0
  693. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +15 -0
  694. data/spec/mongoid/criteria/queryable/queryable_spec.rb +3 -0
  695. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +1865 -0
  696. data/spec/mongoid/criteria/queryable/selectable_spec.rb +1007 -2389
  697. data/spec/mongoid/criteria/queryable/selector_spec.rb +40 -0
  698. data/spec/mongoid/criteria/queryable/smash_spec.rb +3 -0
  699. data/spec/mongoid/criteria/queryable/storable_spec.rb +190 -0
  700. data/spec/mongoid/criteria/scopable_spec.rb +3 -0
  701. data/spec/mongoid/criteria_spec.rb +108 -19
  702. data/spec/mongoid/document_fields_spec.rb +88 -0
  703. data/spec/mongoid/document_persistence_context_spec.rb +33 -0
  704. data/spec/mongoid/document_query_spec.rb +39 -0
  705. data/spec/mongoid/document_spec.rb +32 -4
  706. data/spec/mongoid/equality_spec.rb +3 -0
  707. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +6 -3
  708. data/spec/mongoid/errors/callback_spec.rb +3 -0
  709. data/spec/mongoid/errors/delete_restriction_spec.rb +3 -0
  710. data/spec/mongoid/errors/document_not_destroyed_spec.rb +3 -0
  711. data/spec/mongoid/errors/document_not_found_spec.rb +3 -0
  712. data/spec/mongoid/errors/eager_load_spec.rb +3 -0
  713. data/spec/mongoid/errors/invalid_collection_spec.rb +3 -0
  714. data/spec/mongoid/errors/invalid_config_option_spec.rb +3 -0
  715. data/spec/mongoid/errors/invalid_field_option_spec.rb +3 -0
  716. data/spec/mongoid/errors/invalid_field_spec.rb +3 -0
  717. data/spec/mongoid/errors/invalid_find_spec.rb +3 -0
  718. data/spec/mongoid/errors/invalid_includes_spec.rb +3 -0
  719. data/spec/mongoid/errors/invalid_index_spec.rb +3 -0
  720. data/spec/mongoid/errors/invalid_options_spec.rb +5 -2
  721. data/spec/mongoid/errors/invalid_path_spec.rb +3 -0
  722. data/spec/mongoid/errors/invalid_relation_spec.rb +5 -2
  723. data/spec/mongoid/errors/invalid_scope_spec.rb +3 -0
  724. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +3 -0
  725. data/spec/mongoid/errors/invalid_storage_options_spec.rb +3 -0
  726. data/spec/mongoid/errors/invalid_time_spec.rb +3 -0
  727. data/spec/mongoid/errors/inverse_not_found_spec.rb +4 -1
  728. data/spec/mongoid/errors/mixed_client_configuration_spec.rb +3 -0
  729. data/spec/mongoid/errors/mixed_relations_spec.rb +3 -0
  730. data/spec/mongoid/errors/mongoid_error_spec.rb +3 -0
  731. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +6 -3
  732. data/spec/mongoid/errors/no_client_config_spec.rb +5 -2
  733. data/spec/mongoid/errors/no_client_database_spec.rb +6 -3
  734. data/spec/mongoid/errors/no_client_hosts_spec.rb +6 -3
  735. data/spec/mongoid/errors/no_clients_config_spec.rb +3 -0
  736. data/spec/mongoid/errors/no_environment_spec.rb +3 -0
  737. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +3 -0
  738. data/spec/mongoid/errors/no_metadata_spec.rb +5 -2
  739. data/spec/mongoid/errors/no_parent_spec.rb +4 -1
  740. data/spec/mongoid/errors/readonly_attribute_spec.rb +3 -0
  741. data/spec/mongoid/errors/readonly_document_spec.rb +3 -0
  742. data/spec/mongoid/errors/scope_overwrite_spec.rb +3 -0
  743. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +3 -0
  744. data/spec/mongoid/errors/unknown_attribute_spec.rb +3 -0
  745. data/spec/mongoid/errors/unsaved_document_spec.rb +4 -1
  746. data/spec/mongoid/errors/unsupported_javascript_spec.rb +3 -0
  747. data/spec/mongoid/errors/validations_spec.rb +3 -0
  748. data/spec/mongoid/extensions/array_spec.rb +37 -58
  749. data/spec/mongoid/extensions/big_decimal_spec.rb +3 -0
  750. data/spec/mongoid/extensions/binary_spec.rb +3 -0
  751. data/spec/mongoid/extensions/boolean_spec.rb +3 -0
  752. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +336 -0
  753. data/spec/mongoid/extensions/date_spec.rb +9 -160
  754. data/spec/mongoid/extensions/date_time_spec.rb +18 -60
  755. data/spec/mongoid/extensions/decimal128_spec.rb +3 -0
  756. data/spec/mongoid/extensions/false_class_spec.rb +3 -0
  757. data/spec/mongoid/extensions/float_spec.rb +18 -3
  758. data/spec/mongoid/extensions/hash_spec.rb +124 -1
  759. data/spec/mongoid/extensions/integer_spec.rb +15 -2
  760. data/spec/mongoid/extensions/module_spec.rb +3 -0
  761. data/spec/mongoid/extensions/nil_class_spec.rb +3 -0
  762. data/spec/mongoid/extensions/object_id_spec.rb +3 -0
  763. data/spec/mongoid/extensions/object_spec.rb +21 -35
  764. data/spec/mongoid/extensions/range_spec.rb +10 -0
  765. data/spec/mongoid/extensions/regexp_spec.rb +3 -0
  766. data/spec/mongoid/extensions/set_spec.rb +3 -0
  767. data/spec/mongoid/extensions/string_spec.rb +95 -33
  768. data/spec/mongoid/extensions/symbol_spec.rb +3 -0
  769. data/spec/mongoid/extensions/time_spec.rb +30 -0
  770. data/spec/mongoid/extensions/time_with_zone_spec.rb +34 -0
  771. data/spec/mongoid/extensions/true_class_spec.rb +3 -0
  772. data/spec/mongoid/extensions_spec.rb +3 -0
  773. data/spec/mongoid/factory_spec.rb +46 -1
  774. data/spec/mongoid/fields/foreign_key_spec.rb +27 -32
  775. data/spec/mongoid/fields/localized_spec.rb +3 -0
  776. data/spec/mongoid/fields/standard_spec.rb +3 -0
  777. data/spec/mongoid/fields_spec.rb +42 -1
  778. data/spec/mongoid/findable_spec.rb +4 -1
  779. data/spec/mongoid/indexable/specification_spec.rb +3 -0
  780. data/spec/mongoid/indexable_spec.rb +27 -12
  781. data/spec/mongoid/inspectable_spec.rb +3 -0
  782. data/spec/mongoid/interceptable_spec.rb +87 -1
  783. data/spec/mongoid/interceptable_spec_models.rb +76 -0
  784. data/spec/mongoid/loggable_spec.rb +3 -0
  785. data/spec/mongoid/matchable/all_spec.rb +3 -0
  786. data/spec/mongoid/matchable/and_spec.rb +3 -0
  787. data/spec/mongoid/matchable/default_spec.rb +13 -3
  788. data/spec/mongoid/matchable/elem_match_spec.rb +23 -0
  789. data/spec/mongoid/matchable/eq_spec.rb +49 -0
  790. data/spec/mongoid/matchable/exists_spec.rb +3 -0
  791. data/spec/mongoid/matchable/gt_spec.rb +3 -0
  792. data/spec/mongoid/matchable/gte_spec.rb +3 -0
  793. data/spec/mongoid/matchable/in_spec.rb +3 -0
  794. data/spec/mongoid/matchable/lt_spec.rb +3 -0
  795. data/spec/mongoid/matchable/lte_spec.rb +3 -0
  796. data/spec/mongoid/matchable/ne_spec.rb +3 -0
  797. data/spec/mongoid/matchable/nin_spec.rb +3 -0
  798. data/spec/mongoid/matchable/nor_spec.rb +1 -0
  799. data/spec/mongoid/matchable/or_spec.rb +3 -0
  800. data/spec/mongoid/matchable/regexp_spec.rb +5 -2
  801. data/spec/mongoid/matchable/size_spec.rb +3 -0
  802. data/spec/mongoid/matchable_spec.rb +5 -2
  803. data/spec/mongoid/persistable/creatable_spec.rb +3 -0
  804. data/spec/mongoid/persistable/deletable_spec.rb +3 -0
  805. data/spec/mongoid/persistable/destroyable_spec.rb +3 -0
  806. data/spec/mongoid/persistable/incrementable_spec.rb +17 -0
  807. data/spec/mongoid/persistable/logical_spec.rb +17 -0
  808. data/spec/mongoid/persistable/poppable_spec.rb +17 -0
  809. data/spec/mongoid/persistable/pullable_spec.rb +31 -0
  810. data/spec/mongoid/persistable/pushable_spec.rb +86 -1
  811. data/spec/mongoid/persistable/renamable_spec.rb +17 -0
  812. data/spec/mongoid/persistable/savable_spec.rb +5 -2
  813. data/spec/mongoid/persistable/settable_spec.rb +112 -10
  814. data/spec/mongoid/persistable/unsettable_spec.rb +17 -0
  815. data/spec/mongoid/persistable/updatable_spec.rb +3 -0
  816. data/spec/mongoid/persistable/upsertable_spec.rb +3 -0
  817. data/spec/mongoid/persistable_spec.rb +106 -14
  818. data/spec/mongoid/persistence_context_spec.rb +4 -1
  819. data/spec/mongoid/positional_spec.rb +3 -0
  820. data/spec/mongoid/query_cache_middleware_spec.rb +48 -0
  821. data/spec/mongoid/query_cache_spec.rb +131 -65
  822. data/spec/mongoid/relations/proxy_spec.rb +127 -124
  823. data/spec/mongoid/reloadable_spec.rb +3 -0
  824. data/spec/mongoid/scopable_spec.rb +5 -1
  825. data/spec/mongoid/selectable_spec.rb +3 -0
  826. data/spec/mongoid/serializable_spec.rb +132 -18
  827. data/spec/mongoid/shardable_models.rb +61 -0
  828. data/spec/mongoid/shardable_spec.rb +104 -28
  829. data/spec/mongoid/stateful_spec.rb +3 -0
  830. data/spec/mongoid/tasks/database_rake_spec.rb +16 -13
  831. data/spec/mongoid/tasks/database_spec.rb +4 -1
  832. data/spec/mongoid/threaded_spec.rb +3 -0
  833. data/spec/mongoid/timestamps/created/short_spec.rb +3 -0
  834. data/spec/mongoid/timestamps/created_spec.rb +3 -0
  835. data/spec/mongoid/timestamps/timeless_spec.rb +3 -0
  836. data/spec/mongoid/timestamps/updated/short_spec.rb +3 -0
  837. data/spec/mongoid/timestamps/updated_spec.rb +3 -0
  838. data/spec/mongoid/timestamps_spec.rb +3 -0
  839. data/spec/mongoid/{relations/touchable_spec.rb → touchable_spec.rb} +89 -4
  840. data/spec/mongoid/traversable_spec.rb +3 -0
  841. data/spec/mongoid/validatable/associated_spec.rb +4 -1
  842. data/spec/mongoid/validatable/format_spec.rb +3 -0
  843. data/spec/mongoid/validatable/length_spec.rb +3 -0
  844. data/spec/mongoid/validatable/numericality_spec.rb +3 -0
  845. data/spec/mongoid/validatable/presence_spec.rb +10 -6
  846. data/spec/mongoid/validatable/uniqueness_spec.rb +36 -6
  847. data/spec/mongoid/validatable_spec.rb +4 -1
  848. data/spec/mongoid_spec.rb +3 -0
  849. data/spec/rails/controller_extension/controller_runtime_spec.rb +4 -1
  850. data/spec/rails/mongoid_spec.rb +5 -2
  851. data/spec/shared/LICENSE +20 -0
  852. data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
  853. data/spec/shared/lib/mrss/cluster_config.rb +211 -0
  854. data/spec/shared/lib/mrss/constraints.rb +330 -0
  855. data/spec/shared/lib/mrss/docker_runner.rb +262 -0
  856. data/spec/shared/lib/mrss/lite_constraints.rb +175 -0
  857. data/spec/shared/lib/mrss/server_version_registry.rb +69 -0
  858. data/spec/shared/lib/mrss/spec_organizer.rb +149 -0
  859. data/spec/shared/share/Dockerfile.erb +229 -0
  860. data/spec/shared/shlib/distro.sh +73 -0
  861. data/spec/shared/shlib/server.sh +270 -0
  862. data/spec/shared/shlib/set_env.sh +128 -0
  863. data/spec/spec_helper.rb +56 -55
  864. data/spec/support/authorization.rb +3 -0
  865. data/spec/support/child_process_helper.rb +76 -0
  866. data/spec/support/cluster_config.rb +158 -0
  867. data/spec/support/constraints.rb +256 -0
  868. data/spec/support/expectations.rb +22 -3
  869. data/spec/support/helpers.rb +11 -0
  870. data/spec/support/lite_constraints.rb +22 -0
  871. data/spec/support/macros.rb +21 -0
  872. data/spec/support/session_registry.rb +50 -0
  873. data/spec/support/shared/time.rb +54 -0
  874. data/spec/support/spec_config.rb +50 -0
  875. data.tar.gz.sig +2 -1
  876. metadata +737 -550
  877. metadata.gz.sig +0 -0
  878. data/lib/mongoid/criteria/queryable/forwardable.rb +0 -65
  879. data/lib/mongoid/relations/accessors.rb +0 -267
  880. data/lib/mongoid/relations/auto_save.rb +0 -94
  881. data/lib/mongoid/relations/bindings/embedded/in.rb +0 -59
  882. data/lib/mongoid/relations/bindings/referenced/in.rb +0 -65
  883. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +0 -70
  884. data/lib/mongoid/relations/bindings.rb +0 -9
  885. data/lib/mongoid/relations/builder.rb +0 -57
  886. data/lib/mongoid/relations/builders/embedded/in.rb +0 -29
  887. data/lib/mongoid/relations/builders/embedded/one.rb +0 -30
  888. data/lib/mongoid/relations/builders/nested_attributes/many.rb +0 -199
  889. data/lib/mongoid/relations/builders/referenced/in.rb +0 -26
  890. data/lib/mongoid/relations/builders/referenced/many.rb +0 -26
  891. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +0 -39
  892. data/lib/mongoid/relations/builders/referenced/one.rb +0 -26
  893. data/lib/mongoid/relations/builders.rb +0 -106
  894. data/lib/mongoid/relations/cascading/delete.rb +0 -44
  895. data/lib/mongoid/relations/cascading/destroy.rb +0 -43
  896. data/lib/mongoid/relations/cascading/nullify.rb +0 -35
  897. data/lib/mongoid/relations/cascading/restrict.rb +0 -39
  898. data/lib/mongoid/relations/cascading.rb +0 -56
  899. data/lib/mongoid/relations/constraint.rb +0 -55
  900. data/lib/mongoid/relations/conversions.rb +0 -34
  901. data/lib/mongoid/relations/counter_cache.rb +0 -160
  902. data/lib/mongoid/relations/cyclic.rb +0 -107
  903. data/lib/mongoid/relations/eager/base.rb +0 -153
  904. data/lib/mongoid/relations/eager/belongs_to.rb +0 -31
  905. data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +0 -47
  906. data/lib/mongoid/relations/eager/has_many.rb +0 -38
  907. data/lib/mongoid/relations/eager/has_one.rb +0 -30
  908. data/lib/mongoid/relations/embedded/in.rb +0 -241
  909. data/lib/mongoid/relations/embedded/many.rb +0 -683
  910. data/lib/mongoid/relations/embedded/one.rb +0 -235
  911. data/lib/mongoid/relations/macros.rb +0 -367
  912. data/lib/mongoid/relations/metadata.rb +0 -1179
  913. data/lib/mongoid/relations/nested_builder.rb +0 -74
  914. data/lib/mongoid/relations/options.rb +0 -49
  915. data/lib/mongoid/relations/polymorphic.rb +0 -39
  916. data/lib/mongoid/relations/referenced/in.rb +0 -304
  917. data/lib/mongoid/relations/referenced/many.rb +0 -812
  918. data/lib/mongoid/relations/referenced/many_to_many.rb +0 -479
  919. data/lib/mongoid/relations/referenced/one.rb +0 -290
  920. data/lib/mongoid/relations/reflections.rb +0 -64
  921. data/lib/mongoid/relations/synchronization.rb +0 -169
  922. data/lib/mongoid/relations/targets/enumerable.rb +0 -493
  923. data/lib/mongoid/relations/targets.rb +0 -2
  924. data/lib/mongoid/relations/touchable.rb +0 -97
  925. data/lib/mongoid/relations.rb +0 -148
  926. data/spec/mongoid/criteria/queryable/forwardable_spec.rb +0 -87
  927. data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +0 -184
  928. data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +0 -201
  929. data/spec/mongoid/relations/builders/embedded/in_spec.rb +0 -34
  930. data/spec/mongoid/relations/builders/referenced/many_spec.rb +0 -137
  931. data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +0 -178
  932. data/spec/mongoid/relations/builders/referenced/one_spec.rb +0 -111
  933. data/spec/mongoid/relations/cascading/delete_spec.rb +0 -101
  934. data/spec/mongoid/relations/cascading/destroy_spec.rb +0 -47
  935. data/spec/mongoid/relations/cascading/nullify_spec.rb +0 -32
  936. data/spec/mongoid/relations/cascading/restrict_spec.rb +0 -68
  937. data/spec/mongoid/relations/cascading_spec.rb +0 -355
  938. data/spec/mongoid/relations/constraint_spec.rb +0 -75
  939. data/spec/mongoid/relations/conversions_spec.rb +0 -128
  940. data/spec/mongoid/relations/eager/belongs_to_spec.rb +0 -163
  941. data/spec/mongoid/relations/metadata_spec.rb +0 -1985
  942. data/spec/mongoid/relations/options_spec.rb +0 -35
@@ -1,6 +1,9 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
1
4
  require "spec_helper"
2
5
 
3
- describe Mongoid::Relations::Referenced::In do
6
+ describe Mongoid::Association::Referenced::BelongsTo::Proxy do
4
7
 
5
8
  before(:all) do
6
9
  Person.reset_callbacks(:validate)
@@ -78,8 +81,8 @@ describe Mongoid::Relations::Referenced::In do
78
81
  expect(address.account).to eq(account)
79
82
  end
80
83
 
81
- it "does not erase the metadata" do
82
- expect(address.__metadata).to_not be_nil
84
+ it "does not erase the association metadata" do
85
+ expect(address._association).to_not be_nil
83
86
  end
84
87
 
85
88
  it "allows saving of the embedded document" do
@@ -106,7 +109,7 @@ describe Mongoid::Relations::Referenced::In do
106
109
  end
107
110
 
108
111
  it "sets the target of the relation" do
109
- expect(game.person.target).to eq(person)
112
+ expect(game.person._target).to eq(person)
110
113
  end
111
114
 
112
115
  it "sets the foreign key on the relation" do
@@ -141,7 +144,7 @@ describe Mongoid::Relations::Referenced::In do
141
144
  end
142
145
 
143
146
  it "sets the target of the relation" do
144
- expect(game.person.target).to eq(person)
147
+ expect(game.person._target).to eq(person)
145
148
  end
146
149
 
147
150
  it "sets the foreign key of the relation" do
@@ -203,7 +206,7 @@ describe Mongoid::Relations::Referenced::In do
203
206
  end
204
207
 
205
208
  it "sets the target of the relation" do
206
- expect(rating.ratable.target).to eq(bar)
209
+ expect(rating.ratable._target).to eq(bar)
207
210
  end
208
211
 
209
212
  it "sets the foreign key on the relation" do
@@ -238,7 +241,7 @@ describe Mongoid::Relations::Referenced::In do
238
241
  end
239
242
 
240
243
  it "sets the target of the relation" do
241
- expect(rating.ratable.target).to eq(bar)
244
+ expect(rating.ratable._target).to eq(bar)
242
245
  end
243
246
 
244
247
  it "sets the foreign key of the relation" do
@@ -317,7 +320,7 @@ describe Mongoid::Relations::Referenced::In do
317
320
  end
318
321
 
319
322
  it "sets the target of the relation" do
320
- expect(post.person.target).to eq(person)
323
+ expect(post.person._target).to eq(person)
321
324
  end
322
325
 
323
326
  it "sets the foreign key on the relation" do
@@ -344,7 +347,7 @@ describe Mongoid::Relations::Referenced::In do
344
347
  end
345
348
 
346
349
  it "sets the target of the relation" do
347
- expect(post.person.target).to eq(person)
350
+ expect(post.person._target).to eq(person)
348
351
  end
349
352
 
350
353
  it "sets the foreign key of the relation" do
@@ -388,7 +391,7 @@ describe Mongoid::Relations::Referenced::In do
388
391
 
389
392
  it "should assign as expected" do
390
393
  eye.suspended_in = eye_bowl
391
- expect(eye.suspended_in.target).to eq(eye_bowl)
394
+ expect(eye.suspended_in._target).to eq(eye_bowl)
392
395
  end
393
396
  end
394
397
 
@@ -409,7 +412,7 @@ describe Mongoid::Relations::Referenced::In do
409
412
  end
410
413
 
411
414
  it "sets the target of the relation" do
412
- expect(rating.ratable.target).to eq(movie)
415
+ expect(rating.ratable._target).to eq(movie)
413
416
  end
414
417
 
415
418
  it "sets the foreign key on the relation" do
@@ -436,7 +439,7 @@ describe Mongoid::Relations::Referenced::In do
436
439
  end
437
440
 
438
441
  it "sets the target of the relation" do
439
- expect(rating.ratable.target).to eq(movie)
442
+ expect(rating.ratable._target).to eq(movie)
440
443
  end
441
444
 
442
445
  it "sets the foreign key of the relation" do
@@ -470,6 +473,13 @@ describe Mongoid::Relations::Referenced::In do
470
473
 
471
474
  context "when relation is has_one" do
472
475
 
476
+ around(:each) do |example|
477
+ original_account_dependents = Account.dependents
478
+ Account.dependents = []
479
+ example.run
480
+ Account.dependents = original_account_dependents
481
+ end
482
+
473
483
  before do
474
484
  Account.belongs_to :person, dependent: :destroy
475
485
  Person.has_one :account
@@ -514,6 +524,13 @@ describe Mongoid::Relations::Referenced::In do
514
524
 
515
525
  context "when relation is has_many" do
516
526
 
527
+ around(:each) do |example|
528
+ original_drug_dependents = Drug.dependents
529
+ Drug.dependents = []
530
+ example.run
531
+ Drug.dependents = original_drug_dependents
532
+ end
533
+
517
534
  before do
518
535
  Drug.belongs_to :person, dependent: :destroy
519
536
  Person.has_many :drugs
@@ -562,8 +579,15 @@ describe Mongoid::Relations::Referenced::In do
562
579
 
563
580
  context "when relation is has_one" do
564
581
 
582
+ around(:each) do |example|
583
+ original_account_dependents = Account.dependents
584
+ Account.dependents = []
585
+ example.run
586
+ Account.dependents = original_account_dependents
587
+ end
588
+
565
589
  before do
566
- Account.belongs_to :person, dependent: :delete
590
+ Account.belongs_to :person, dependent: :delete_all
567
591
  Person.has_one :account
568
592
  person.account = account
569
593
  person.save
@@ -595,8 +619,15 @@ describe Mongoid::Relations::Referenced::In do
595
619
 
596
620
  context "when relation is has_many" do
597
621
 
622
+ around(:each) do |example|
623
+ original_drug_dependents = Drug.dependents
624
+ Drug.dependents = []
625
+ example.run
626
+ Drug.dependents = original_drug_dependents
627
+ end
628
+
598
629
  before do
599
- Drug.belongs_to :person, dependent: :delete
630
+ Drug.belongs_to :person, dependent: :delete_all
600
631
  Person.has_many :drugs
601
632
  person.drugs = [drug]
602
633
  person.save
@@ -643,6 +674,13 @@ describe Mongoid::Relations::Referenced::In do
643
674
 
644
675
  context "when relation is has_one" do
645
676
 
677
+ around(:each) do |example|
678
+ original_account_dependents = Account.dependents
679
+ Account.dependents = []
680
+ example.run
681
+ Account.dependents = original_account_dependents
682
+ end
683
+
646
684
  before do
647
685
  Account.belongs_to :person, dependent: :nullify
648
686
  Person.has_one :account
@@ -675,6 +713,13 @@ describe Mongoid::Relations::Referenced::In do
675
713
 
676
714
  context "when relation is has_many" do
677
715
 
716
+ around(:each) do |example|
717
+ original_drug_dependents = Drug.dependents
718
+ Drug.dependents = []
719
+ example.run
720
+ Drug.dependents = original_drug_dependents
721
+ end
722
+
678
723
  before do
679
724
  Drug.belongs_to :person, dependent: :nullify
680
725
  Person.has_many :drugs
@@ -980,48 +1025,6 @@ describe Mongoid::Relations::Referenced::In do
980
1025
  end
981
1026
  end
982
1027
 
983
- describe ".builder" do
984
-
985
- let(:builder_klass) do
986
- Mongoid::Relations::Builders::Referenced::In
987
- end
988
-
989
- let(:document) do
990
- double
991
- end
992
-
993
- let(:metadata) do
994
- double(extension?: false)
995
- end
996
-
997
- it "returns the embedded in builder" do
998
- expect(
999
- described_class.builder(nil, metadata, document)
1000
- ).to be_a_kind_of(builder_klass)
1001
- end
1002
- end
1003
-
1004
- describe ".embedded?" do
1005
-
1006
- it "returns false" do
1007
- expect(described_class).to_not be_embedded
1008
- end
1009
- end
1010
-
1011
- describe ".foreign_key_suffix" do
1012
-
1013
- it "returns _id" do
1014
- expect(described_class.foreign_key_suffix).to eq("_id")
1015
- end
1016
- end
1017
-
1018
- describe ".macro" do
1019
-
1020
- it "returns belongs_to" do
1021
- expect(described_class.macro).to eq(:belongs_to)
1022
- end
1023
- end
1024
-
1025
1028
  describe "#respond_to?" do
1026
1029
 
1027
1030
  let(:person) do
@@ -1047,40 +1050,6 @@ describe Mongoid::Relations::Referenced::In do
1047
1050
  end
1048
1051
  end
1049
1052
 
1050
- describe ".stores_foreign_key?" do
1051
-
1052
- it "returns true" do
1053
- expect(described_class.stores_foreign_key?).to be true
1054
- end
1055
- end
1056
-
1057
- describe ".valid_options" do
1058
-
1059
- it "returns the valid options" do
1060
- expect(described_class.valid_options).to eq(
1061
- [
1062
- :autobuild,
1063
- :autosave,
1064
- :dependent,
1065
- :foreign_key,
1066
- :index,
1067
- :polymorphic,
1068
- :primary_key,
1069
- :touch,
1070
- :optional,
1071
- :required
1072
- ]
1073
- )
1074
- end
1075
- end
1076
-
1077
- describe ".validation_default" do
1078
-
1079
- it "returns false" do
1080
- expect(described_class.validation_default).to be false
1081
- end
1082
- end
1083
-
1084
1053
  context "when the relation is self referencing" do
1085
1054
 
1086
1055
  let(:game_one) do
@@ -1280,7 +1249,7 @@ describe Mongoid::Relations::Referenced::In do
1280
1249
 
1281
1250
  before do
1282
1251
  Person.collection.find({ _id: person_one.id }).
1283
- update_one({ "$set" => { title: "Madam" }})
1252
+ update_one({ "$set" => { title: "Madam" }})
1284
1253
  end
1285
1254
 
1286
1255
  let(:reloaded) do
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ require "spec_helper"
5
+ require_relative './has_many_models'
6
+
7
+ describe Mongoid::Association::Referenced::BelongsTo do
8
+ context 'when projecting with #only' do
9
+ before do
10
+ school = HmmSchool.create!(district: 'foo', team: 'Bulldogs')
11
+ HmmStudent.create!(school: school, name: 'Dave', grade: 10)
12
+ end
13
+
14
+ let(:student) do
15
+ HmmStudent.where(name: 'Dave').only(:school_id, 'school._id', 'school.district').first
16
+ end
17
+
18
+ let(:school) { student.school }
19
+
20
+ it 'populates specified fields only' do
21
+ pending 'https://jira.mongodb.org/browse/MONGOID-4704'
22
+
23
+ expect(school.district).to eq('foo')
24
+ # has a default value specified in the model
25
+ expect do
26
+ school.team
27
+ end.to raise_error(ActiveModel::MissingAttributeError)
28
+ expect(student.attributes.keys).to eq(['_id', 'name'])
29
+ end
30
+
31
+ # Delete this test when https://jira.mongodb.org/browse/MONGOID-4704 is
32
+ # implemented and above test is unpended
33
+ it 'fetches all fields' do
34
+ expect(school.district).to eq('foo')
35
+ expect(school.team).to eq('Bulldogs')
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,2026 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ require "spec_helper"
5
+ require_relative './has_one_models'
6
+
7
+ describe Mongoid::Association::Referenced::BelongsTo do
8
+
9
+ before do
10
+ class OwnerObject; include Mongoid::Document; end
11
+ class BelongingObject; include Mongoid::Document; end
12
+ end
13
+
14
+ after do
15
+ Object.send(:remove_const, :BelongingObject)
16
+ Object.send(:remove_const, :OwnerObject)
17
+ end
18
+
19
+ let(:belonging_class) do
20
+ BelongingObject
21
+ end
22
+
23
+ let(:name) do
24
+ :owner_object
25
+ end
26
+
27
+ let(:association) do
28
+ belonging_class.belongs_to name, options
29
+ end
30
+
31
+ let(:options) do
32
+ { }
33
+ end
34
+
35
+ describe '#relation_complements' do
36
+
37
+ let(:expected_complements) do
38
+ [
39
+ Mongoid::Association::Referenced::HasMany,
40
+ Mongoid::Association::Referenced::HasOne
41
+ ]
42
+ end
43
+
44
+ it 'returns the relation complements' do
45
+ expect(association.relation_complements).to eq(expected_complements)
46
+ end
47
+ end
48
+
49
+ describe '#setup!' do
50
+
51
+ it 'sets up a getter for the relation' do
52
+ expect(Mongoid::Association::Accessors).to receive(:define_getter!).with(association)
53
+ association.setup!
54
+ end
55
+
56
+ it 'sets up a setter for the relation' do
57
+ expect(Mongoid::Association::Accessors).to receive(:define_setter!).with(association)
58
+ association.setup!
59
+ end
60
+
61
+ it 'sets up an existence check for the relation' do
62
+ expect(Mongoid::Association::Accessors).to receive(:define_existence_check!).with(association)
63
+ association.setup!
64
+ end
65
+
66
+ it 'sets up the builder for the relation' do
67
+ expect(Mongoid::Association::Builders).to receive(:define_builder!).with(association)
68
+ association.setup!
69
+ end
70
+
71
+ it 'sets up the creator for the relation' do
72
+ expect(Mongoid::Association::Builders).to receive(:define_creator!).with(association)
73
+ association.setup!
74
+ end
75
+
76
+ context 'autosave' do
77
+
78
+ context 'when the :autosave option is true' do
79
+
80
+ let(:options) do
81
+ {
82
+ autosave: true
83
+ }
84
+ end
85
+
86
+ let(:association) do
87
+ # Note that it is necessary to create the association directly, otherwise the
88
+ # setup!! method will be called by the :belongs_to macro
89
+ described_class.new(belonging_class, name, options)
90
+ end
91
+
92
+ it 'sets up autosave' do
93
+ expect(Mongoid::Association::Referenced::AutoSave).to receive(:define_autosave!).with(association)
94
+ association.setup!
95
+ end
96
+ end
97
+
98
+ context 'when the :autosave option is false' do
99
+
100
+ let(:options) do
101
+ {
102
+ autosave: false
103
+ }
104
+ end
105
+
106
+ it 'does not set up autosave' do
107
+ expect(Mongoid::Association::Referenced::AutoSave).not_to receive(:define_autosave!)
108
+ association.setup!
109
+ end
110
+ end
111
+
112
+ context 'when the :autosave option is not provided' do
113
+
114
+ let(:association) do
115
+ # Note that it is necessary to create the association directly, otherwise the
116
+ # setup!! method will be called by the :embeds_many macro
117
+ described_class.new(belonging_class, name, options)
118
+ end
119
+
120
+ it 'does not set up autosave' do
121
+ expect(Mongoid::Association::Referenced::AutoSave).not_to receive(:define_autosave!)
122
+ association.setup!
123
+ end
124
+ end
125
+ end
126
+
127
+ context 'counter cache callbacks' do
128
+
129
+ context 'when the :counter_cache option is true' do
130
+
131
+ let(:options) do
132
+ {
133
+ counter_cache: true
134
+ }
135
+ end
136
+
137
+ let(:association) do
138
+ # Note that it is necessary to create the association directly, otherwise the
139
+ # setup! method will be called by the :belongs_to macro
140
+ described_class.new(belonging_class, name, options)
141
+ end
142
+
143
+ it 'sets up counter cache callbacks' do
144
+ expect(Mongoid::Association::Referenced::CounterCache).to receive(:define_callbacks!).with(association)
145
+ association.setup!
146
+ end
147
+ end
148
+
149
+ context 'when the :counter_cache option is a String' do
150
+
151
+ let(:options) do
152
+ {
153
+ counter_cache: 'counts_field'
154
+ }
155
+ end
156
+
157
+ let(:association) do
158
+ # Note that it is necessary to create the association directly, otherwise the
159
+ # setup! method will be called by the :belongs_to macro
160
+ described_class.new(belonging_class, name, options)
161
+ end
162
+
163
+ it 'sets up counter cache callbacks' do
164
+ expect(Mongoid::Association::Referenced::CounterCache).to receive(:define_callbacks!).with(association)
165
+ association.setup!
166
+ end
167
+ end
168
+
169
+ context 'when the :counter_cache option is false' do
170
+
171
+ let(:options) do
172
+ {
173
+ counter_cache: false
174
+ }
175
+ end
176
+
177
+ it 'does not set up counter cache callbacks' do
178
+ expect(Mongoid::Association::Referenced::CounterCache).not_to receive(:define_callbacks!)
179
+ association.setup!
180
+ end
181
+ end
182
+
183
+ context 'when the :counter_cache option is not provided' do
184
+
185
+ let(:association) do
186
+ # Note that it is necessary to create the association directly, otherwise the
187
+ # setup! method will be called by the :embeds_many macro
188
+ described_class.new(belonging_class, name, options)
189
+ end
190
+
191
+ it 'does not set up counter cache callbacks' do
192
+ expect(Mongoid::Association::Referenced::CounterCache).not_to receive(:define_callbacks!)
193
+ association.setup!
194
+ end
195
+ end
196
+ end
197
+
198
+ context 'polymorphic' do
199
+
200
+ context 'when the polymorphic option is provided' do
201
+
202
+ context 'when the polymorphic option is true' do
203
+
204
+ let(:options) do
205
+ {
206
+ polymorphic: true
207
+ }
208
+ end
209
+
210
+ before do
211
+ association
212
+ end
213
+
214
+ it 'set the polymorphic attribute on the owner class' do
215
+ expect(belonging_class.polymorphic).to be(true)
216
+ end
217
+
218
+ it 'sets up a field for the inverse type' do
219
+ expect(belonging_class.fields.keys).to include(association.inverse_type)
220
+ end
221
+ end
222
+
223
+ context 'when the polymorphic option is false' do
224
+
225
+ let(:options) do
226
+ {
227
+ polymorphic: false
228
+ }
229
+ end
230
+
231
+ it 'does not set the polymorphic attribute on the owner class' do
232
+ expect(belonging_class.polymorphic).to be(false)
233
+ end
234
+
235
+ it 'does not set up a field for the inverse type' do
236
+ expect(belonging_class.fields.keys).not_to include(association.inverse_type)
237
+ end
238
+ end
239
+ end
240
+
241
+ context 'when the polymorphic option is not provided' do
242
+
243
+ it 'does not set the polymorphic attribute on the owner class' do
244
+ expect(belonging_class.polymorphic).to be(false)
245
+ end
246
+
247
+ it 'does not set up a field for the inverse type' do
248
+ expect(belonging_class.fields.keys).not_to include(association.inverse_type)
249
+ end
250
+ end
251
+ end
252
+
253
+ context 'dependent' do
254
+
255
+ context 'when the dependent option is provided' do
256
+
257
+ context 'when the dependent option is :delete_all' do
258
+
259
+ let(:options) do
260
+ {
261
+ dependent: :delete_all
262
+ }
263
+ end
264
+
265
+ let(:association) do
266
+ # Note that it is necessary to create the association directly, otherwise the
267
+ # setup! method will be called by the :belongs_to macro
268
+ described_class.new(belonging_class, name, options)
269
+ end
270
+
271
+ it 'sets up the dependency' do
272
+ expect(Mongoid::Association::Depending).to receive(:define_dependency!)
273
+ association.setup!
274
+ end
275
+ end
276
+
277
+ context 'when the dependent option is :destroy' do
278
+
279
+ let(:options) do
280
+ {
281
+ dependent: :destroy
282
+ }
283
+ end
284
+
285
+ let(:association) do
286
+ # Note that it is necessary to create the association directly, otherwise the
287
+ # setup! method will be called by the :belongs_to macro
288
+ described_class.new(belonging_class, name, options)
289
+ end
290
+
291
+ it 'sets up the dependency' do
292
+ expect(Mongoid::Association::Depending).to receive(:define_dependency!)
293
+ association.setup!
294
+ end
295
+ end
296
+
297
+ context 'when the dependent option is :nullify' do
298
+
299
+ let(:options) do
300
+ {
301
+ dependent: :nullify
302
+ }
303
+ end
304
+
305
+ let(:association) do
306
+ # Note that it is necessary to create the association directly, otherwise the
307
+ # setup! method will be called by the :belongs_to macro
308
+ described_class.new(belonging_class, name, options)
309
+ end
310
+
311
+ it 'sets up the dependency' do
312
+ expect(Mongoid::Association::Depending).to receive(:define_dependency!)
313
+ association.setup!
314
+ end
315
+ end
316
+
317
+ context 'when the dependent option is :restrict_with_exception' do
318
+
319
+ let(:options) do
320
+ {
321
+ dependent: :restrict_with_exception
322
+ }
323
+ end
324
+
325
+ let(:association) do
326
+ # Note that it is necessary to create the association directly, otherwise the
327
+ # setup! method will be called by the :belongs_to macro
328
+ described_class.new(belonging_class, name, options)
329
+ end
330
+
331
+ it 'sets up the dependency' do
332
+ expect(Mongoid::Association::Depending).to receive(:define_dependency!)
333
+ association.setup!
334
+ end
335
+ end
336
+
337
+ context 'when the dependent option is :restrict_with_error' do
338
+
339
+ let(:options) do
340
+ {
341
+ dependent: :restrict_with_error
342
+ }
343
+ end
344
+
345
+ let(:association) do
346
+ # Note that it is necessary to create the association directly, otherwise the
347
+ # setup! method will be called by the :belongs_to macro
348
+ described_class.new(belonging_class, name, options)
349
+ end
350
+
351
+ it 'sets up the dependency' do
352
+ expect(Mongoid::Association::Depending).to receive(:define_dependency!)
353
+ association.setup!
354
+ end
355
+ end
356
+ end
357
+
358
+ context 'when the dependent option is not provided' do
359
+
360
+ it 'does not set up the dependency' do
361
+ expect(Mongoid::Association::Depending).not_to receive(:define_dependency!)
362
+ association.setup!
363
+ end
364
+ end
365
+ end
366
+
367
+ context 'foreign key field' do
368
+
369
+ before do
370
+ association
371
+ end
372
+
373
+ it 'sets up the foreign key field' do
374
+ expect(belonging_class.fields.keys).to include(association.foreign_key)
375
+ end
376
+ end
377
+
378
+ context 'index' do
379
+
380
+ before do
381
+ association
382
+ end
383
+
384
+ context 'when index is true' do
385
+
386
+ context 'when polymorphic' do
387
+
388
+ let(:options) do
389
+ {
390
+ polymorphic: true,
391
+ index: true
392
+ }
393
+ end
394
+
395
+ it 'sets up the index with the key and inverse type' do
396
+ expect(belonging_class.index_specifications.first.fields).to match_array([ association.key.to_sym,
397
+ association.inverse_type.to_sym])
398
+ end
399
+ end
400
+
401
+ context 'when not polymorphic' do
402
+
403
+ let(:options) do
404
+ {
405
+ index: true
406
+ }
407
+ end
408
+
409
+ it 'sets up the index with the key' do
410
+ expect(belonging_class.index_specifications.first.fields).to match_array([ association.key.to_sym ])
411
+ end
412
+ end
413
+ end
414
+
415
+ context 'when index is false' do
416
+
417
+ context 'when polymorphic' do
418
+
419
+ let(:options) do
420
+ {
421
+ polymorphic: true
422
+ }
423
+ end
424
+
425
+ it 'does not set up an index' do
426
+ expect(belonging_class.index_specifications).to eq([ ])
427
+ end
428
+ end
429
+
430
+ context 'when not polymorphic' do
431
+
432
+ it 'does not set up an index' do
433
+ expect(belonging_class.index_specifications).to eq([ ])
434
+ end
435
+ end
436
+ end
437
+ end
438
+
439
+ context 'touchable' do
440
+
441
+ context 'when the :touch option is true' do
442
+
443
+ let(:options) do
444
+ {
445
+ touch: true
446
+ }
447
+ end
448
+
449
+ let(:association) do
450
+ # Note that it is necessary to create the association directly, otherwise the
451
+ # setup! method will be called by the :belongs_to macro
452
+ described_class.new(belonging_class, name, options)
453
+ end
454
+
455
+ it 'sets up touch' do
456
+ expect(Mongoid::Touchable).to receive(:define_touchable!).with(association)
457
+ association.setup!
458
+ end
459
+ end
460
+
461
+ context 'when the :touch option is false' do
462
+
463
+ let(:options) do
464
+ {
465
+ touch: false
466
+ }
467
+ end
468
+
469
+ it 'does not set up touch' do
470
+ expect(Mongoid::Touchable).not_to receive(:define_touchable!).with(association)
471
+ association.setup!
472
+ end
473
+ end
474
+
475
+ context 'when the :touch option is not provided' do
476
+
477
+ let(:association) do
478
+ # Note that it is necessary to create the association directly, otherwise the
479
+ # setup! method will be called by the :embeds_many macro
480
+ described_class.new(belonging_class, name, options)
481
+ end
482
+
483
+ it 'does not set up touch' do
484
+ expect(Mongoid::Touchable).not_to receive(:define_touchable!).with(association)
485
+ association.setup!
486
+ end
487
+ end
488
+ end
489
+
490
+ context 'validate' do
491
+
492
+ context 'when the :validate option is true' do
493
+
494
+ let(:options) do
495
+ {
496
+ validate: true
497
+ }
498
+ end
499
+
500
+ let(:association) do
501
+ # Note that it is necessary to create the association directly, otherwise the
502
+ # setup! method will be called by the :belongs_to macro
503
+ described_class.new(belonging_class, name, options)
504
+ end
505
+
506
+ it 'sets up validation' do
507
+ expect(belonging_class).to receive(:validates_associated).with(name).and_call_original
508
+ association.setup!
509
+ end
510
+ end
511
+
512
+ context 'when the :validate option is false' do
513
+
514
+ let(:options) do
515
+ {
516
+ validate: false
517
+ }
518
+ end
519
+
520
+ it 'does not set up validation' do
521
+ expect(belonging_class).not_to receive(:validates_associated)
522
+ association.setup!
523
+ end
524
+ end
525
+
526
+ context 'when the :validate option is not provided' do
527
+
528
+ let(:association) do
529
+ # Note that it is necessary to create the association directly, otherwise the
530
+ # setup! method will be called by the :belongs_to macro
531
+ described_class.new(belonging_class, name, options)
532
+ end
533
+
534
+ it 'does not set up the validation because it uses the validation default (false)' do
535
+ expect(belonging_class).not_to receive(:validates_associated)
536
+ association.setup!
537
+ end
538
+ end
539
+ end
540
+
541
+ context 'presence of validation' do
542
+
543
+ let(:association) do
544
+ # Note that it is necessary to create the association directly, otherwise the
545
+ # setup! method will be called by the :belongs_to macro
546
+ described_class.new(belonging_class, name, options)
547
+ end
548
+
549
+ context 'when the global config option is true' do
550
+
551
+ around(:example) do |example|
552
+ original_config = Mongoid.belongs_to_required_by_default
553
+ Mongoid.belongs_to_required_by_default = true
554
+ example.run
555
+ Mongoid.belongs_to_required_by_default = original_config
556
+ end
557
+
558
+ let!(:original_required_config) do
559
+ Mongoid.belongs_to_required_by_default
560
+ end
561
+
562
+ context 'when the required option is true' do
563
+
564
+ let(:options) do
565
+ {
566
+ required: true
567
+ }
568
+ end
569
+
570
+ it 'sets up the presence of validation' do
571
+ expect(belonging_class).to receive(:validates).with(name, { presence: true }).and_call_original
572
+ association.setup!
573
+ end
574
+
575
+ context 'when the optional option is true' do
576
+
577
+ let(:options) do
578
+ {
579
+ required: true,
580
+ optional: true
581
+ }
582
+ end
583
+
584
+ it 'sets up the presence of validation' do
585
+ expect(belonging_class).to receive(:validates).with(name, { presence: true }).and_call_original
586
+ association.setup!
587
+ end
588
+ end
589
+
590
+ context 'when the optional option is false' do
591
+
592
+ let(:options) do
593
+ {
594
+ required: true,
595
+ optional: false
596
+ }
597
+ end
598
+
599
+ it 'sets up the presence of validation' do
600
+ expect(belonging_class).to receive(:validates).with(name, { presence: true }).and_call_original
601
+ association.setup!
602
+ end
603
+ end
604
+ end
605
+
606
+ context 'when the required option is false' do
607
+
608
+ let(:options) do
609
+ {
610
+ required: false
611
+ }
612
+ end
613
+
614
+ it 'does not set up the presence of validation' do
615
+ expect(belonging_class).not_to receive(:validates)
616
+ association.setup!
617
+ end
618
+
619
+ context 'when the optional option is true' do
620
+
621
+ let(:options) do
622
+ {
623
+ required: false,
624
+ optional: true
625
+ }
626
+ end
627
+
628
+ it 'does not set up the presence of validation' do
629
+ expect(belonging_class).not_to receive(:validates)
630
+ association.setup!
631
+ end
632
+ end
633
+
634
+ context 'when the optional option is false' do
635
+
636
+ let(:options) do
637
+ {
638
+ required: false,
639
+ optional: false
640
+ }
641
+ end
642
+
643
+ it 'does not set up the presence of validation' do
644
+ expect(belonging_class).not_to receive(:validates)
645
+ association.setup!
646
+ end
647
+ end
648
+ end
649
+
650
+ context 'when the required option is not provided' do
651
+
652
+ it 'uses the default and sets up the presence of validation' do
653
+ expect(belonging_class).to receive(:validates).with(name, { presence: true }).and_call_original
654
+ association.setup!
655
+ end
656
+
657
+ context 'when the optional option is true' do
658
+
659
+ let(:options) do
660
+ {
661
+ optional: true
662
+ }
663
+ end
664
+
665
+ it 'does not set up the presence of validation' do
666
+ expect(belonging_class).not_to receive(:validates)
667
+ association.setup!
668
+ end
669
+ end
670
+
671
+ context 'when the optional option is false' do
672
+
673
+ let(:options) do
674
+ {
675
+ optional: false
676
+ }
677
+ end
678
+
679
+ it 'sets up the presence of validation' do
680
+ expect(belonging_class).to receive(:validates).with(name, { presence: true }).and_call_original
681
+ association.setup!
682
+ end
683
+ end
684
+ end
685
+ end
686
+
687
+ context 'when the global config option is false' do
688
+
689
+ around(:example) do |example|
690
+ original_config = Mongoid.belongs_to_required_by_default
691
+ Mongoid.belongs_to_required_by_default = false
692
+ example.run
693
+ Mongoid.belongs_to_required_by_default = original_config
694
+ end
695
+
696
+ context 'when the required option is true' do
697
+
698
+ let(:options) do
699
+ {
700
+ required: true
701
+ }
702
+ end
703
+
704
+ it 'sets up the presence of validation' do
705
+ expect(belonging_class).to receive(:validates).with(name, { presence: true }).and_call_original
706
+ association.setup!
707
+ end
708
+
709
+ context 'when the optional option is true' do
710
+
711
+ let(:options) do
712
+ {
713
+ required: true,
714
+ optional: true
715
+ }
716
+ end
717
+
718
+ it 'sets up the presence of validation' do
719
+ expect(belonging_class).to receive(:validates).with(name, { presence: true }).and_call_original
720
+ association.setup!
721
+ end
722
+ end
723
+
724
+ context 'when the optional option is false' do
725
+
726
+ let(:options) do
727
+ {
728
+ required: true,
729
+ optional: false
730
+ }
731
+ end
732
+
733
+ it 'sets up the presence of validation' do
734
+ expect(belonging_class).to receive(:validates).with(name, { presence: true }).and_call_original
735
+ association.setup!
736
+ end
737
+ end
738
+ end
739
+
740
+ context 'when the required option is false' do
741
+
742
+ let(:options) do
743
+ {
744
+ required: false
745
+ }
746
+ end
747
+
748
+ it 'does not set up the presence of validation' do
749
+ expect(belonging_class).not_to receive(:validates)
750
+ association.setup!
751
+ end
752
+
753
+ context 'when the optional option is true' do
754
+
755
+ let(:options) do
756
+ {
757
+ required: false,
758
+ optional: true
759
+ }
760
+ end
761
+
762
+ it 'does not set up the presence of validation' do
763
+ expect(belonging_class).not_to receive(:validates)
764
+ association.setup!
765
+ end
766
+ end
767
+
768
+ context 'when the optional option is false' do
769
+
770
+ let(:options) do
771
+ {
772
+ required: false,
773
+ optional: false
774
+ }
775
+ end
776
+
777
+ it 'does not set up the presence of validation' do
778
+ expect(belonging_class).not_to receive(:validates)
779
+ association.setup!
780
+ end
781
+ end
782
+ end
783
+
784
+ context 'when the required option is not provided' do
785
+
786
+ it 'uses the default and does not set up the presence of validation' do
787
+ expect(belonging_class).not_to receive(:validates)
788
+ association.setup!
789
+ end
790
+
791
+ context 'when the optional option is true' do
792
+
793
+ let(:options) do
794
+ {
795
+ optional: true
796
+ }
797
+ end
798
+
799
+ it 'does not set up the presence of validation' do
800
+ expect(belonging_class).not_to receive(:validates)
801
+ association.setup!
802
+ end
803
+ end
804
+
805
+ context 'when the optional option is false' do
806
+
807
+ let(:options) do
808
+ {
809
+ optional: false
810
+ }
811
+ end
812
+
813
+ it 'sets up the presence of validation' do
814
+ expect(belonging_class).to receive(:validates).with(name, { presence: true }).and_call_original
815
+ association.setup!
816
+ end
817
+ end
818
+ end
819
+ end
820
+ end
821
+ end
822
+
823
+ describe '#type' do
824
+
825
+ context 'when polymorphic' do
826
+
827
+ let(:options) do
828
+ { polymorphic: true }
829
+ end
830
+
831
+ it 'returns nil' do
832
+ expect(association.type).to be_nil
833
+ end
834
+ end
835
+
836
+ context 'when not polymorphic' do
837
+
838
+ it 'returns nil' do
839
+ expect(association.type).to be_nil
840
+ end
841
+ end
842
+ end
843
+
844
+ describe '#inverse_type' do
845
+
846
+ context 'when polymorphic' do
847
+
848
+ let(:options) do
849
+ { polymorphic: true }
850
+ end
851
+
852
+ it 'returns the name followed by "_type"' do
853
+ expect(association.inverse_type).to eq("#{name}_type")
854
+ end
855
+ end
856
+
857
+ context 'when not polymorphic' do
858
+
859
+ it 'returns nil' do
860
+ expect(association.inverse_type).to be_nil
861
+ end
862
+ end
863
+ end
864
+
865
+ describe '#inverse_type_setter' do
866
+
867
+ context 'when polymorphic' do
868
+
869
+ let(:options) do
870
+ { polymorphic: true }
871
+ end
872
+
873
+ it 'returns the inverse type setter' do
874
+ expect(association.inverse_type_setter).to eq("#{name}_type=")
875
+ end
876
+ end
877
+
878
+ context 'when not polymorphic' do
879
+
880
+ it 'returns nil' do
881
+ expect(association.inverse_type_setter).to be_nil
882
+ end
883
+ end
884
+ end
885
+
886
+ describe '#foreign_key' do
887
+
888
+ context 'when options has foreign_key specified' do
889
+
890
+ let(:options) do
891
+ { foreign_key: :other_object_id }
892
+ end
893
+
894
+ it 'returns the foreign key' do
895
+ expect(association.foreign_key).to eq(options[:foreign_key].to_s)
896
+ end
897
+ end
898
+
899
+ context 'when options does not have foreign_key specified' do
900
+
901
+ it 'returns the ame followed by "_id"' do
902
+ expect(association.foreign_key).to eq("#{name}_id")
903
+ end
904
+ end
905
+ end
906
+
907
+ describe '#embedded?' do
908
+
909
+ it 'returns false' do
910
+ expect(association.embedded?).to be(false)
911
+ end
912
+ end
913
+
914
+ describe '#primary_key' do
915
+
916
+ context 'when the :primary_key option is specified' do
917
+
918
+ context 'when the :primary_key option is true' do
919
+
920
+ let(:options) do
921
+ {
922
+ primary_key: :other_primary_key
923
+ }
924
+ end
925
+
926
+ it 'returns the primary key option as a String' do
927
+ expect(association.primary_key).to eq('other_primary_key')
928
+ end
929
+ end
930
+ end
931
+
932
+ context 'when the :primary_key option is not specified' do
933
+
934
+ it 'returns the default primary key' do
935
+ expect(association.primary_key).to eq(Mongoid::Association::Relatable::PRIMARY_KEY_DEFAULT)
936
+ end
937
+ end
938
+ end
939
+
940
+ describe '#indexed?' do
941
+
942
+ context 'when :index is specified in the options' do
943
+
944
+ context 'when :index is true' do
945
+
946
+ let(:options) do
947
+ {
948
+ index: true
949
+ }
950
+ end
951
+
952
+ it 'returns true' do
953
+ expect(association.indexed?).to be(true)
954
+ end
955
+ end
956
+
957
+ context 'when :index is false' do
958
+
959
+ let(:options) do
960
+ {
961
+ index: false
962
+ }
963
+ end
964
+
965
+ it 'returns false' do
966
+ expect(association.indexed?).to be(false)
967
+ end
968
+ end
969
+ end
970
+
971
+ context 'when :index is not specified in the options' do
972
+
973
+ it 'returns nil' do
974
+ expect(association.indexed?).to be(false)
975
+ end
976
+ end
977
+ end
978
+
979
+ describe '#relation' do
980
+
981
+ it 'returns Mongoid::Association::Referenced::BelongsTo::Proxy' do
982
+ expect(association.relation).to be(Mongoid::Association::Referenced::BelongsTo::Proxy)
983
+ end
984
+ end
985
+
986
+ describe '#validation_default' do
987
+
988
+ it 'returns false' do
989
+ expect(association.validation_default).to be(false)
990
+ end
991
+ end
992
+
993
+ describe '#name' do
994
+
995
+ it 'returns the name of the relation' do
996
+ expect(association.name).to be(name)
997
+ end
998
+ end
999
+
1000
+ describe '#options' do
1001
+
1002
+ it 'returns the options' do
1003
+ expect(association.options).to be(options)
1004
+ end
1005
+ end
1006
+
1007
+ describe '#cyclic?' do
1008
+
1009
+ it 'returns false' do
1010
+ expect(association.cyclic?).to be(false)
1011
+ end
1012
+ end
1013
+
1014
+ describe '#merge!' do
1015
+
1016
+ end
1017
+
1018
+ describe '#store_as' do
1019
+
1020
+ it 'returns nil' do
1021
+ expect(association.store_as).to be_nil
1022
+ end
1023
+ end
1024
+
1025
+ describe '#touchable?' do
1026
+
1027
+ context 'when :touch is in the options' do
1028
+
1029
+ let(:options) do
1030
+ { touch: true}
1031
+ end
1032
+
1033
+ it 'returns true' do
1034
+ expect(association.send(:touchable?)).to be(true)
1035
+ end
1036
+ end
1037
+
1038
+ context 'when :touch is not in the options' do
1039
+
1040
+ it 'return false' do
1041
+ expect(association.send(:touchable?)).to be(false)
1042
+ end
1043
+ end
1044
+ end
1045
+
1046
+ describe '#order' do
1047
+
1048
+ it 'returns nil' do
1049
+ expect(association.order).to be_nil
1050
+ end
1051
+ end
1052
+
1053
+ describe '#as' do
1054
+
1055
+ it 'returns nil' do
1056
+ expect(association.as).to be_nil
1057
+ end
1058
+ end
1059
+
1060
+ describe '#polymorphic?' do
1061
+
1062
+ context 'when :polymorphic is specified in the options as true' do
1063
+
1064
+ let(:options) do
1065
+ { polymorphic: true }
1066
+ end
1067
+
1068
+ it 'returns true' do
1069
+ expect(association.polymorphic?).to be(true)
1070
+ end
1071
+ end
1072
+
1073
+ context 'when :polymorphic is specified in the options as false' do
1074
+
1075
+ let(:options) do
1076
+ { polymorphic: false }
1077
+ end
1078
+
1079
+ it 'returns false' do
1080
+ expect(association.polymorphic?).to be(false)
1081
+ end
1082
+ end
1083
+
1084
+ context 'when :polymorphic is not specified in the options' do
1085
+
1086
+ it 'returns false' do
1087
+ expect(association.polymorphic?).to be(false)
1088
+ end
1089
+ end
1090
+ end
1091
+
1092
+ describe '#dependent' do
1093
+
1094
+ context 'when the dependent option is provided' do
1095
+
1096
+ context 'when the dependent option is :delete_all' do
1097
+
1098
+ let(:options) do
1099
+ {
1100
+ dependent: :delete_all
1101
+ }
1102
+ end
1103
+
1104
+ it 'returns :delete_all' do
1105
+ expect(association.dependent).to eq(:delete_all)
1106
+ end
1107
+ end
1108
+
1109
+ context 'when the dependent option is :destroy' do
1110
+
1111
+ let(:options) do
1112
+ {
1113
+ dependent: :destroy
1114
+ }
1115
+ end
1116
+
1117
+ it 'returns :destroy' do
1118
+ expect(association.dependent).to eq(:destroy)
1119
+ end
1120
+ end
1121
+
1122
+ context 'when the dependent option is :nullify' do
1123
+
1124
+ let(:options) do
1125
+ {
1126
+ dependent: :nullify
1127
+ }
1128
+ end
1129
+
1130
+ it 'returns :nullify' do
1131
+ expect(association.dependent).to eq(:nullify)
1132
+ end
1133
+ end
1134
+
1135
+ context 'when the dependent option is :restrict_with_exception' do
1136
+
1137
+ let(:options) do
1138
+ {
1139
+ dependent: :restrict_with_exception
1140
+ }
1141
+ end
1142
+
1143
+ it 'returns :restrict_with_exception' do
1144
+ expect(association.dependent).to eq(:restrict_with_exception)
1145
+ end
1146
+ end
1147
+
1148
+ context 'when the dependent option is :restrict_with_error' do
1149
+
1150
+ let(:options) do
1151
+ {
1152
+ dependent: :restrict_with_error
1153
+ }
1154
+ end
1155
+
1156
+ it 'returns :restrict_with_error' do
1157
+ expect(association.dependent).to eq(:restrict_with_error)
1158
+ end
1159
+ end
1160
+ end
1161
+
1162
+ context 'when the dependent option is not provided' do
1163
+
1164
+ it 'returns nil' do
1165
+ expect(association.dependent).to be_nil
1166
+ end
1167
+ end
1168
+ end
1169
+
1170
+ describe '#bindable?' do
1171
+
1172
+ it 'returns false' do
1173
+ expect(association.bindable?(Person.new)).to be(false)
1174
+ end
1175
+ end
1176
+
1177
+ describe '#inverses' do
1178
+
1179
+ context 'when polymorphic' do
1180
+
1181
+ let(:options) do
1182
+ {
1183
+ polymorphic: true
1184
+ }
1185
+ end
1186
+
1187
+ let(:name) do
1188
+ :containable
1189
+ end
1190
+
1191
+ context 'when another object is passed to the method' do
1192
+
1193
+ let(:instance_of_other_class) do
1194
+ OwnerObject.new
1195
+ end
1196
+
1197
+ context 'when the relation class has only one relation whose class matches the owning class' do
1198
+
1199
+ before do
1200
+ OwnerObject.has_one :belonging_object, as: :containable
1201
+ end
1202
+
1203
+ context 'when :inverse_of is specified' do
1204
+
1205
+ before do
1206
+ options.merge!(inverse_of: :inverse_name)
1207
+ end
1208
+
1209
+ it 'returns the :inverse_of value' do
1210
+ expect(association.inverses(instance_of_other_class)).to eq([ :inverse_name ])
1211
+ end
1212
+ end
1213
+
1214
+ context 'when inverse_of is not specified' do
1215
+
1216
+ it 'returns the list of relations whose :as attribute matches the name of this association' do
1217
+ expect(association.inverses(instance_of_other_class)).to match_array([ :belonging_object ])
1218
+ end
1219
+ end
1220
+ end
1221
+
1222
+ context 'when the relation class has more than one relation whose class matches the owning class' do
1223
+
1224
+ before do
1225
+ OwnerObject.has_one :other_belonging_object, as: :containable, class_name: 'BelongingObject'
1226
+ OwnerObject.has_one :belonging_object, as: :containable
1227
+ end
1228
+
1229
+ context 'when :inverse_of is specified' do
1230
+
1231
+ before do
1232
+ options.merge!(inverse_of: :inverse_name)
1233
+ end
1234
+
1235
+ it 'returns the :inverse_of value' do
1236
+ expect(association.inverses(instance_of_other_class)).to eq([ :inverse_name ])
1237
+ end
1238
+ end
1239
+
1240
+ context 'when inverse_of is not specified' do
1241
+
1242
+ it 'returns the list of relations whose :as attribute matches the name of this association' do
1243
+ expect(association.inverses(instance_of_other_class)).to match_array([ :other_belonging_object,
1244
+ :belonging_object ])
1245
+ end
1246
+
1247
+ context 'when the relation class has two associations with the same name' do
1248
+
1249
+ before do
1250
+ OwnerObject.has_one :belonging_object, as: :containable
1251
+ OwnerObject.has_one :other_belonging_object, as: :containable
1252
+ end
1253
+
1254
+ it 'returns only the relations whose :as attribute and class match' do
1255
+ expect(association.inverses(instance_of_other_class)).to match_array([ :belonging_object ])
1256
+ end
1257
+ end
1258
+ end
1259
+ end
1260
+ end
1261
+
1262
+ context 'when another object is not passed to the method' do
1263
+
1264
+ context 'when inverse_of is specified' do
1265
+
1266
+ before do
1267
+ options.merge!(inverse_of: :inverse_name)
1268
+ end
1269
+
1270
+ it 'returns the :inverse_of value' do
1271
+ expect(association.inverses).to eq([ :inverse_name ])
1272
+ end
1273
+ end
1274
+
1275
+ context 'when inverse_of is not specified' do
1276
+
1277
+ it 'returns nil' do
1278
+ expect(association.inverses).to eq(nil)
1279
+ end
1280
+ end
1281
+ end
1282
+ end
1283
+
1284
+ context 'when not polymorphic' do
1285
+
1286
+ context 'when inverse_of is specified' do
1287
+
1288
+ before do
1289
+ options.merge!(inverse_of: :inverse_name)
1290
+ end
1291
+
1292
+ it 'returns the :inverse_of value' do
1293
+ expect(association.inverses).to eq([ :inverse_name ])
1294
+ end
1295
+ end
1296
+
1297
+ context 'when inverse_of is not specified' do
1298
+
1299
+ before do
1300
+ OwnerObject.has_many :belonging_objects
1301
+ end
1302
+
1303
+ it 'uses the inverse class to find the inverse name' do
1304
+ expect(association.inverses).to eq([ :belonging_objects ])
1305
+ end
1306
+ end
1307
+
1308
+ context 'when :cyclic is specified' do
1309
+
1310
+ it 'returns the cyclic inverse name' do
1311
+
1312
+ end
1313
+ end
1314
+
1315
+ context 'when the inverse class has more than one relation with objects of the owner class' do
1316
+
1317
+ before do
1318
+ OwnerObject.has_many :belonging_objects
1319
+ OwnerObject.has_one :other_belonging_object, class_name: 'BelongingObject'
1320
+ end
1321
+
1322
+ it 'raises a Mongoid::Errors::AmbiguousRelationship exception' do
1323
+ expect {
1324
+ association.inverses
1325
+ }.to raise_exception(Mongoid::Errors::AmbiguousRelationship)
1326
+ end
1327
+ end
1328
+
1329
+ context 'when the inverse class only has one relation with objects of the owner class' do
1330
+
1331
+ before do
1332
+ OwnerObject.has_many :belonging_objects
1333
+ end
1334
+
1335
+ it 'uses the inverse class to find the inverse name' do
1336
+ expect(association.inverses).to eq([ :belonging_objects ])
1337
+ end
1338
+ end
1339
+ end
1340
+ end
1341
+
1342
+ describe '#inverse' do
1343
+
1344
+ context 'when polymorphic' do
1345
+
1346
+ let(:options) do
1347
+ {
1348
+ polymorphic: true
1349
+ }
1350
+ end
1351
+
1352
+ let(:name) do
1353
+ :containable
1354
+ end
1355
+
1356
+ context 'when another object is passed to the method' do
1357
+
1358
+ let(:instance_of_other_class) do
1359
+ OwnerObject.new
1360
+ end
1361
+
1362
+ context 'when the relation class has only one relation whose class matches the owning class' do
1363
+
1364
+ before do
1365
+ OwnerObject.has_many :belonging_objects, as: :containable
1366
+ end
1367
+
1368
+ context 'when :inverse_of is specified' do
1369
+
1370
+ before do
1371
+ options.merge!(inverse_of: :inverse_name)
1372
+ end
1373
+
1374
+ it 'returns the :inverse_of value' do
1375
+ expect(association.inverse(instance_of_other_class)).to eq(:inverse_name)
1376
+ end
1377
+ end
1378
+
1379
+ context 'when inverse_of is not specified' do
1380
+
1381
+ it 'returns the list of relations whose :as attribute matches the name of this association' do
1382
+ expect(association.inverse(instance_of_other_class)).to eq(:belonging_objects)
1383
+ end
1384
+ end
1385
+ end
1386
+
1387
+ context 'when the relation class has more than one relation whose class matches the owning class' do
1388
+
1389
+ before do
1390
+ OwnerObject.has_one :other_belonging_object, as: :containable, class_name: 'BelongingObject'
1391
+ OwnerObject.has_one :belonging_object, as: :containable
1392
+ end
1393
+
1394
+ context 'when :inverse_of is specified' do
1395
+
1396
+ before do
1397
+ options.merge!(inverse_of: :inverse_name)
1398
+ end
1399
+
1400
+ it 'returns the :inverse_of value' do
1401
+ expect(association.inverse(instance_of_other_class)).to eq(:inverse_name)
1402
+ end
1403
+ end
1404
+
1405
+ context 'when inverse_of is not specified' do
1406
+
1407
+ it 'returns the first candidate whose :as attribute matches the name of this association' do
1408
+ expect(association.inverse(instance_of_other_class)).to eq(:other_belonging_object)
1409
+ end
1410
+ end
1411
+ end
1412
+ end
1413
+
1414
+ context 'when another object is not passed to the method' do
1415
+
1416
+ context 'when inverse_of is specified' do
1417
+
1418
+ before do
1419
+ options.merge!(inverse_of: :inverse_name)
1420
+ end
1421
+
1422
+ it 'returns the :inverse_of value' do
1423
+ expect(association.inverse).to eq(:inverse_name)
1424
+ end
1425
+ end
1426
+
1427
+ context 'when inverse_of is not specified' do
1428
+
1429
+ it 'returns nil' do
1430
+ expect(association.inverse).to eq(nil)
1431
+ end
1432
+ end
1433
+ end
1434
+ end
1435
+
1436
+ context 'when not polymorphic' do
1437
+
1438
+ context 'when inverse_of is specified' do
1439
+
1440
+ before do
1441
+ options.merge!(inverse_of: :inverse_name)
1442
+ end
1443
+
1444
+ it 'returns the :inverse_of value' do
1445
+ expect(association.inverse).to eq(:inverse_name)
1446
+ end
1447
+ end
1448
+
1449
+ context 'when inverse_of is not specified' do
1450
+
1451
+ before do
1452
+ OwnerObject.has_many :belonging_objects
1453
+ end
1454
+
1455
+ it 'uses the inverse class to find the inverse name' do
1456
+ expect(association.inverse).to eq(:belonging_objects)
1457
+ end
1458
+ end
1459
+
1460
+ context 'when :cyclic is specified' do
1461
+
1462
+ it 'returns the cyclic inverse name' do
1463
+
1464
+ end
1465
+ end
1466
+
1467
+ context 'when the inverse class has more than one relation with objects of the owner class' do
1468
+
1469
+ before do
1470
+ OwnerObject.has_many :belonging_objects
1471
+ OwnerObject.has_many :other_belonging_objects, class_name: 'BelongingObject'
1472
+ end
1473
+
1474
+ it 'raises a Mongoid::Errors::AmbiguousRelationship exception' do
1475
+ expect {
1476
+ association.inverse
1477
+ }.to raise_exception(Mongoid::Errors::AmbiguousRelationship)
1478
+ end
1479
+ end
1480
+
1481
+ context 'when the inverse class only has one relation with objects of the owner class' do
1482
+
1483
+ before do
1484
+ OwnerObject.has_many :belonging_objects
1485
+ end
1486
+
1487
+ it 'uses the inverse class to find the inverse name' do
1488
+ expect(association.inverse).to eq(:belonging_objects)
1489
+ end
1490
+ end
1491
+ end
1492
+ end
1493
+
1494
+ describe '#inverse_association' do
1495
+
1496
+ end
1497
+
1498
+ describe '#autosave' do
1499
+
1500
+ context 'when the :autosave option is specified' do
1501
+
1502
+ context 'when the :autosave option is true' do
1503
+
1504
+ let(:options) do
1505
+ {
1506
+ autosave: true
1507
+ }
1508
+ end
1509
+
1510
+ it 'returns true' do
1511
+ expect(association.autosave).to be(true)
1512
+ end
1513
+ end
1514
+
1515
+ context 'when the :autosave option is false' do
1516
+
1517
+ let(:options) do
1518
+ {
1519
+ autosave: false
1520
+ }
1521
+ end
1522
+
1523
+ it 'returns false' do
1524
+ expect(association.autosave).to be(false)
1525
+ end
1526
+ end
1527
+ end
1528
+
1529
+ context 'when the :autosave option is not specified' do
1530
+
1531
+ it 'returns nil' do
1532
+ expect(association.autosave).to be(false)
1533
+ end
1534
+ end
1535
+ end
1536
+
1537
+ describe '#counter_cached?' do
1538
+
1539
+ context 'when the :counter_cache option is true' do
1540
+
1541
+ let(:options) do
1542
+ {
1543
+ counter_cache: true
1544
+ }
1545
+ end
1546
+
1547
+ it 'returns true' do
1548
+ expect(association.counter_cached?).to be(true)
1549
+ end
1550
+ end
1551
+
1552
+ context 'when the :counter_cache option is a String' do
1553
+
1554
+ let(:options) do
1555
+ {
1556
+ counter_cache: 'counts_field'
1557
+ }
1558
+ end
1559
+
1560
+ it 'returns true' do
1561
+ expect(association.counter_cached?).to be(true)
1562
+ end
1563
+ end
1564
+
1565
+ context 'when the :counter_cache option is false' do
1566
+
1567
+ let(:options) do
1568
+ {
1569
+ counter_cache: false
1570
+ }
1571
+ end
1572
+
1573
+ it 'returns false' do
1574
+ expect(association.counter_cached?).to be(false)
1575
+ end
1576
+ end
1577
+
1578
+ context 'when the :counter_cache option is not provided' do
1579
+
1580
+ it 'returns false' do
1581
+ expect(association.counter_cached?).to be(false)
1582
+ end
1583
+ end
1584
+ end
1585
+
1586
+ describe '#counter_cache_column_name' do
1587
+
1588
+ context 'when the :counter_cache option is true' do
1589
+
1590
+ let(:options) do
1591
+ {
1592
+ counter_cache: true
1593
+ }
1594
+ end
1595
+
1596
+ it 'returns the inverse name followed by "_count"' do
1597
+ expect(association.counter_cache_column_name).to eq('belonging_objects_count')
1598
+ end
1599
+ end
1600
+
1601
+ context 'when the :counter_cache option is a String' do
1602
+
1603
+ let(:options) do
1604
+ {
1605
+ counter_cache: 'counts_field'
1606
+ }
1607
+ end
1608
+
1609
+ it 'returns the String' do
1610
+ expect(association.counter_cache_column_name).to eq('counts_field')
1611
+ end
1612
+ end
1613
+ end
1614
+
1615
+ describe '#relation_class_name' do
1616
+
1617
+ context 'when the :class_name option is specified' do
1618
+
1619
+ let(:options) do
1620
+ { class_name: 'OtherOwnerObject' }
1621
+ end
1622
+
1623
+ it 'returns the class name option' do
1624
+ expect(association.relation_class_name).to eq('OtherOwnerObject')
1625
+ end
1626
+ end
1627
+
1628
+ context 'when the :class_name option is scoped with ::' do
1629
+
1630
+ let(:options) do
1631
+ { class_name: '::OtherOwnerObject' }
1632
+ end
1633
+
1634
+ it 'returns the class name option' do
1635
+ expect(association.relation_class_name).to eq('::OtherOwnerObject')
1636
+ end
1637
+ end
1638
+
1639
+ context 'when the class_name option is not specified' do
1640
+
1641
+ it 'uses the name of the relation to deduce the class name' do
1642
+ expect(association.relation_class_name).to eq('OwnerObject')
1643
+ end
1644
+ end
1645
+
1646
+ context 'when the association is polymorphic' do
1647
+ let(:association) do
1648
+ HomPolymorphicChild.relations['p_parent']
1649
+ end
1650
+
1651
+ it 'is the computed class name that does not match any existing class' do
1652
+ expect(association.relation_class_name).to eq('PParent')
1653
+ end
1654
+ end
1655
+ end
1656
+
1657
+ describe '#relation_class' do
1658
+
1659
+ context 'when the :class_name option is specified' do
1660
+
1661
+ let(:options) do
1662
+ { class_name: 'OtherOwnerObject' }
1663
+ end
1664
+
1665
+ it 'returns the named class' do
1666
+ expect(association.relation_class).to eq(OtherOwnerObject)
1667
+ end
1668
+ end
1669
+
1670
+ context 'when the :class_name option is scoped with ::' do
1671
+
1672
+ let(:options) do
1673
+ { class_name: '::OtherOwnerObject' }
1674
+ end
1675
+
1676
+ it 'returns the named class' do
1677
+ expect(association.relation_class).to eq(OtherOwnerObject)
1678
+ end
1679
+ end
1680
+
1681
+ context 'when the class_name option is not specified' do
1682
+
1683
+ it 'uses the name of the relation to deduce the class name' do
1684
+ expect(association.relation_class).to eq(OwnerObject)
1685
+ end
1686
+ end
1687
+
1688
+ context 'when the association is polymorphic' do
1689
+ let(:association) do
1690
+ HomPolymorphicChild.relations['p_parent']
1691
+ end
1692
+
1693
+ it 'raises NameError' do
1694
+ expect do
1695
+ association.relation_class
1696
+ end.to raise_error(NameError, /uninitialized constant .*PParent/)
1697
+ end
1698
+ end
1699
+ end
1700
+
1701
+ describe '#inverse_class_name' do
1702
+
1703
+ it 'returns the name of the owner class' do
1704
+ expect(association.inverse_class_name).to eq(belonging_class.name)
1705
+ end
1706
+
1707
+ context 'polymorphic association' do
1708
+ let(:association) do
1709
+ belonging_class.belongs_to :poly_owner, polymorphic: true
1710
+ end
1711
+
1712
+ it 'returns the name of the owner class' do
1713
+ expect(association.inverse_class_name).to eq(belonging_class.name)
1714
+ end
1715
+ end
1716
+ end
1717
+
1718
+ describe '#inverse_class' do
1719
+
1720
+ it 'returns the owner class' do
1721
+ expect(association.inverse_class).to be(belonging_class)
1722
+ end
1723
+
1724
+ context 'polymorphic association' do
1725
+ let(:association) do
1726
+ belonging_class.belongs_to :poly_owner, polymorphic: true
1727
+ end
1728
+
1729
+ it 'returns the owner class' do
1730
+ expect(association.inverse_class).to be(belonging_class)
1731
+ end
1732
+ end
1733
+ end
1734
+
1735
+ describe '#inverse_of' do
1736
+
1737
+ context 'when :inverse_of is specified in the options' do
1738
+
1739
+ let(:options) do
1740
+ { inverse_of: :a_belonging_object }
1741
+ end
1742
+
1743
+ it 'returns the inverse_of value' do
1744
+ expect(association.inverse_of).to eq(options[:inverse_of])
1745
+ end
1746
+ end
1747
+
1748
+ context 'when :inverse_of is not specified in the options' do
1749
+
1750
+ it 'returns nil' do
1751
+ expect(association.inverse_of).to be_nil
1752
+ end
1753
+ end
1754
+ end
1755
+
1756
+ describe '#key' do
1757
+
1758
+ it 'returns the name of the foreign_key as a string' do
1759
+ expect(association.key).to eq(association.foreign_key.to_s)
1760
+ end
1761
+ end
1762
+
1763
+ describe '#setter' do
1764
+
1765
+ it 'returns a string of the name followed by =' do
1766
+ expect(association.setter).to eq("#{name}=")
1767
+ end
1768
+ end
1769
+
1770
+ describe '#validate?' do
1771
+
1772
+ context 'when :validate is specified in the options' do
1773
+
1774
+ context 'when validate is true' do
1775
+
1776
+ let(:options) do
1777
+ { validate: true }
1778
+ end
1779
+
1780
+ it 'returns true' do
1781
+ expect(association.send(:validate?)).to be(true)
1782
+ end
1783
+ end
1784
+
1785
+ context 'when validate is false' do
1786
+
1787
+ let(:options) do
1788
+ { validate: false }
1789
+ end
1790
+
1791
+ it 'returns false' do
1792
+ expect(association.send(:validate?)).to be(false)
1793
+ end
1794
+ end
1795
+ end
1796
+
1797
+ context 'when :validate is not specified in the options' do
1798
+
1799
+ it 'returns the validation_default' do
1800
+ expect(association.send(:validate?)).to eq(association.validation_default)
1801
+ end
1802
+ end
1803
+ end
1804
+
1805
+ describe '#autobuilding?' do
1806
+
1807
+ context 'when :autobuild is specified in the options' do
1808
+
1809
+ context 'when autobuild is true' do
1810
+
1811
+ let(:options) do
1812
+ { autobuild: true }
1813
+ end
1814
+
1815
+ it 'returns true' do
1816
+ expect(association.autobuilding?).to be(true)
1817
+ end
1818
+ end
1819
+
1820
+ context 'when autobuild is false' do
1821
+
1822
+ let(:options) do
1823
+ { autobuild: false }
1824
+ end
1825
+
1826
+ it 'returns true' do
1827
+ expect(association.autobuilding?).to be(false)
1828
+ end
1829
+ end
1830
+ end
1831
+
1832
+ context 'when :validate is not specified in the options' do
1833
+
1834
+ it 'returns false' do
1835
+ expect(association.autobuilding?).to be(false)
1836
+ end
1837
+ end
1838
+ end
1839
+
1840
+ describe '#forced_nil_inverse?' do
1841
+
1842
+ it 'returns false' do
1843
+ expect(association.forced_nil_inverse?).to be(false)
1844
+ end
1845
+ end
1846
+
1847
+ describe '#stores_foreign_key?' do
1848
+
1849
+ it 'returns true' do
1850
+ expect(association.stores_foreign_key?).to be(true)
1851
+ end
1852
+ end
1853
+
1854
+ describe '#inverse_setter' do
1855
+
1856
+ context 'when an inverse can be determined' do
1857
+
1858
+ before do
1859
+ OwnerObject.has_many :belonging_objects
1860
+ end
1861
+
1862
+ it 'returns the name of the inverse followed by =' do
1863
+ expect(association.inverse_setter).to eq('belonging_objects=')
1864
+ end
1865
+ end
1866
+
1867
+ context 'when an inverse cannot be determined' do
1868
+
1869
+ it 'returns nil' do
1870
+ expect(association.inverse_setter).to be_nil
1871
+ end
1872
+ end
1873
+ end
1874
+
1875
+ describe '#extension' do
1876
+
1877
+ context 'when a block is passed' do
1878
+
1879
+ let(:association) do
1880
+ belonging_class.belongs_to name, options do; end
1881
+ end
1882
+
1883
+ it 'defines an extension module' do
1884
+ expect(association.extension).to be_a(Module)
1885
+ end
1886
+
1887
+ it 'returns the extension' do
1888
+ expect(association.extension).to eq(
1889
+ "#{belonging_class.name}::#{belonging_class.name}#{name.to_s.camelize}RelationExtension".constantize)
1890
+ end
1891
+ end
1892
+
1893
+ context 'when an :extension is not specified in the options' do
1894
+
1895
+ it 'returns false' do
1896
+ expect(association.extension).to be_nil
1897
+ end
1898
+ end
1899
+ end
1900
+
1901
+ describe '#foreign_key_setter' do
1902
+
1903
+ it 'returns the foriegn key field followed by "="' do
1904
+ expect(association.foreign_key_setter).to eq("owner_object_id=")
1905
+ end
1906
+ end
1907
+
1908
+ describe '#destructive?' do
1909
+
1910
+ context 'when the dependent option is provided' do
1911
+
1912
+ context 'when the dependent option is :delete_all' do
1913
+
1914
+ let(:options) do
1915
+ {
1916
+ dependent: :delete_all
1917
+ }
1918
+ end
1919
+
1920
+ it 'returns true' do
1921
+ expect(association.destructive?).to be(true)
1922
+ end
1923
+ end
1924
+
1925
+ context 'when the dependent option is :destroy' do
1926
+
1927
+ let(:options) do
1928
+ {
1929
+ dependent: :destroy
1930
+ }
1931
+ end
1932
+
1933
+ it 'returns true' do
1934
+ expect(association.destructive?).to be(true)
1935
+ end
1936
+ end
1937
+
1938
+ context 'when the dependent option is :nullify' do
1939
+
1940
+ let(:options) do
1941
+ {
1942
+ dependent: :nullify
1943
+ }
1944
+ end
1945
+
1946
+ it 'returns false' do
1947
+ expect(association.destructive?).to be(false)
1948
+ end
1949
+ end
1950
+
1951
+ context 'when the dependent option is :restrict_with_exception' do
1952
+
1953
+ let(:options) do
1954
+ {
1955
+ dependent: :restrict_with_exception
1956
+ }
1957
+ end
1958
+
1959
+ it 'returns false' do
1960
+ expect(association.destructive?).to be(false)
1961
+ end
1962
+ end
1963
+
1964
+ context 'when the dependent option is :restrict_with_error' do
1965
+
1966
+ let(:options) do
1967
+ {
1968
+ dependent: :restrict_with_error
1969
+ }
1970
+ end
1971
+
1972
+ it 'returns false' do
1973
+ expect(association.destructive?).to be(false)
1974
+ end
1975
+ end
1976
+ end
1977
+
1978
+ context 'when the dependent option is not provided' do
1979
+
1980
+ it 'returns false' do
1981
+ expect(association.destructive?).to be(false)
1982
+ end
1983
+ end
1984
+ end
1985
+
1986
+ describe '#nested_builder' do
1987
+
1988
+ it 'returns an instance of Association::Nested::One' do
1989
+ expect(association.nested_builder({}, {})).to be_a(Mongoid::Association::Nested::One)
1990
+ end
1991
+ end
1992
+
1993
+ describe '#path' do
1994
+
1995
+ it 'returns an instance of Mongoid::Atomic::Paths::Root' do
1996
+ expect(association.path({})).to be_a(Mongoid::Atomic::Paths::Root)
1997
+ end
1998
+ end
1999
+
2000
+ describe '#foreign_key_check' do
2001
+
2002
+ it 'returns the foreign_key followed by "_changed?"' do
2003
+ expect(association.foreign_key_check).to eq('owner_object_id_changed?')
2004
+ end
2005
+ end
2006
+
2007
+ describe '#create_relation' do
2008
+
2009
+ let(:owner) do
2010
+ BelongingObject.new
2011
+ end
2012
+
2013
+ let(:target) do
2014
+ OwnerObject.new
2015
+ end
2016
+
2017
+ before do
2018
+ OwnerObject.has_one :belonging_object
2019
+ end
2020
+
2021
+ it 'returns an instance of Mongoid::Association::Referenced::BelongsTo::Proxy' do
2022
+ expect(Mongoid::Association::Referenced::BelongsTo::Proxy).to receive(:new).and_call_original
2023
+ expect(association.create_relation(owner, target)).to be_a(OwnerObject)
2024
+ end
2025
+ end
2026
+ end