mongoid 6.4.4 → 7.3.2

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 (1341) 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 +34 -20
  6. data/Rakefile +75 -5
  7. data/lib/config/locales/en.yml +115 -53
  8. data/lib/mongoid/association/accessors.rb +429 -0
  9. data/lib/mongoid/association/bindable.rb +200 -0
  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 +135 -0
  13. data/lib/mongoid/association/eager_loadable.rb +38 -0
  14. data/lib/mongoid/association/embedded/batchable.rb +386 -0
  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/association/embedded/embeds_many/binding.rb +48 -0
  21. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +48 -0
  22. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +562 -0
  23. data/lib/mongoid/association/embedded/embeds_many.rb +214 -0
  24. data/lib/mongoid/association/embedded/embeds_one/binding.rb +50 -0
  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/association/many.rb +215 -0
  31. data/lib/mongoid/association/marshalable.rb +36 -0
  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 +131 -0
  35. data/lib/mongoid/association/nested.rb +18 -0
  36. data/lib/mongoid/association/one.rb +62 -0
  37. data/lib/mongoid/association/options.rb +155 -0
  38. data/lib/mongoid/association/proxy.rb +210 -0
  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/association/referenced/has_many/binding.rb +41 -0
  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 +550 -0
  56. data/lib/mongoid/association/referenced/has_many/proxy.rb +588 -0
  57. data/lib/mongoid/association/referenced/has_many.rb +278 -0
  58. data/lib/mongoid/association/referenced/has_one/binding.rb +49 -0
  59. data/lib/mongoid/association/referenced/has_one/buildable.rb +75 -0
  60. data/lib/mongoid/association/referenced/has_one/eager.rb +37 -0
  61. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +128 -0
  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 +25 -2
  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 +19 -16
  77. data/lib/mongoid/attributes/nested.rb +29 -16
  78. data/lib/mongoid/attributes/processing.rb +10 -8
  79. data/lib/mongoid/attributes/projector.rb +120 -0
  80. data/lib/mongoid/attributes/readonly.rb +5 -5
  81. data/lib/mongoid/attributes.rb +93 -57
  82. data/lib/mongoid/cacheable.rb +5 -3
  83. data/lib/mongoid/changeable.rb +4 -2
  84. data/lib/mongoid/clients/factory.rb +42 -10
  85. data/lib/mongoid/clients/options.rb +17 -13
  86. data/lib/mongoid/clients/sessions.rb +23 -4
  87. data/lib/mongoid/clients/storage_options.rb +7 -5
  88. data/lib/mongoid/clients/validators/storage.rb +2 -0
  89. data/lib/mongoid/clients/validators.rb +2 -0
  90. data/lib/mongoid/clients.rb +3 -1
  91. data/lib/mongoid/composable.rb +9 -6
  92. data/lib/mongoid/config/environment.rb +23 -8
  93. data/lib/mongoid/config/options.rb +20 -12
  94. data/lib/mongoid/config/validators/client.rb +2 -0
  95. data/lib/mongoid/config/validators/option.rb +2 -0
  96. data/lib/mongoid/config/validators.rb +2 -0
  97. data/lib/mongoid/config.rb +75 -11
  98. data/lib/mongoid/contextual/aggregable/memory.rb +3 -1
  99. data/lib/mongoid/contextual/aggregable/mongo.rb +13 -9
  100. data/lib/mongoid/contextual/atomic.rb +24 -6
  101. data/lib/mongoid/contextual/command.rb +2 -0
  102. data/lib/mongoid/contextual/geo_near.rb +6 -4
  103. data/lib/mongoid/contextual/map_reduce.rb +5 -2
  104. data/lib/mongoid/contextual/memory.rb +23 -3
  105. data/lib/mongoid/contextual/mongo.rb +39 -13
  106. data/lib/mongoid/contextual/none.rb +2 -0
  107. data/lib/mongoid/contextual/queryable.rb +2 -0
  108. data/lib/mongoid/contextual.rb +7 -4
  109. data/lib/mongoid/copyable.rb +20 -9
  110. data/lib/mongoid/criteria/findable.rb +12 -2
  111. data/lib/mongoid/criteria/includable.rb +21 -19
  112. data/lib/mongoid/criteria/inspectable.rb +2 -0
  113. data/lib/mongoid/criteria/marshalable.rb +2 -0
  114. data/lib/mongoid/criteria/modifiable.rb +10 -3
  115. data/lib/mongoid/criteria/options.rb +4 -2
  116. data/lib/mongoid/criteria/permission.rb +2 -0
  117. data/lib/mongoid/criteria/queryable/aggregable.rb +2 -0
  118. data/lib/mongoid/criteria/queryable/expandable.rb +69 -0
  119. data/lib/mongoid/criteria/queryable/extensions/array.rb +3 -1
  120. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +3 -1
  121. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +3 -1
  122. data/lib/mongoid/criteria/queryable/extensions/date.rb +3 -1
  123. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +5 -6
  124. data/lib/mongoid/criteria/queryable/extensions/hash.rb +3 -1
  125. data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +3 -1
  126. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +4 -2
  127. data/lib/mongoid/criteria/queryable/extensions/object.rb +3 -1
  128. data/lib/mongoid/criteria/queryable/extensions/range.rb +3 -1
  129. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +9 -7
  130. data/lib/mongoid/criteria/queryable/extensions/set.rb +3 -1
  131. data/lib/mongoid/criteria/queryable/extensions/string.rb +4 -2
  132. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +3 -1
  133. data/lib/mongoid/criteria/queryable/extensions/time.rb +4 -2
  134. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +15 -1
  135. data/lib/mongoid/criteria/queryable/extensions.rb +1 -3
  136. data/lib/mongoid/criteria/queryable/key.rb +101 -14
  137. data/lib/mongoid/criteria/queryable/macroable.rb +3 -1
  138. data/lib/mongoid/criteria/queryable/mergeable.rb +184 -15
  139. data/lib/mongoid/criteria/queryable/optional.rb +5 -3
  140. data/lib/mongoid/criteria/queryable/options.rb +2 -0
  141. data/lib/mongoid/criteria/queryable/pipeline.rb +14 -6
  142. data/lib/mongoid/criteria/queryable/selectable.rb +399 -98
  143. data/lib/mongoid/criteria/queryable/selector.rb +46 -39
  144. data/lib/mongoid/criteria/queryable/smash.rb +2 -0
  145. data/lib/mongoid/criteria/queryable/storable.rb +233 -0
  146. data/lib/mongoid/criteria/queryable.rb +7 -2
  147. data/lib/mongoid/criteria/scopable.rb +2 -0
  148. data/lib/mongoid/criteria.rb +88 -18
  149. data/lib/mongoid/document.rb +32 -22
  150. data/lib/mongoid/equality.rb +3 -2
  151. data/lib/mongoid/errors/ambiguous_relationship.rb +4 -2
  152. data/lib/mongoid/errors/callback.rb +2 -0
  153. data/lib/mongoid/errors/criteria_argument_required.rb +19 -0
  154. data/lib/mongoid/errors/delete_restriction.rb +10 -10
  155. data/lib/mongoid/errors/document_not_destroyed.rb +2 -0
  156. data/lib/mongoid/errors/document_not_found.rb +2 -0
  157. data/lib/mongoid/errors/eager_load.rb +6 -2
  158. data/lib/mongoid/errors/in_memory_collation_not_supported.rb +2 -0
  159. data/lib/mongoid/errors/invalid_collection.rb +2 -0
  160. data/lib/mongoid/errors/invalid_config_option.rb +2 -0
  161. data/lib/mongoid/errors/invalid_dependent_strategy.rb +34 -0
  162. data/lib/mongoid/errors/invalid_discriminator_key_target.rb +25 -0
  163. data/lib/mongoid/errors/invalid_elem_match_operator.rb +33 -0
  164. data/lib/mongoid/errors/invalid_estimated_count_criteria.rb +26 -0
  165. data/lib/mongoid/errors/invalid_expression_operator.rb +28 -0
  166. data/lib/mongoid/errors/invalid_field.rb +2 -0
  167. data/lib/mongoid/errors/invalid_field_operator.rb +33 -0
  168. data/lib/mongoid/errors/invalid_field_option.rb +2 -0
  169. data/lib/mongoid/errors/invalid_find.rb +2 -0
  170. data/lib/mongoid/errors/invalid_includes.rb +2 -0
  171. data/lib/mongoid/errors/invalid_index.rb +2 -0
  172. data/lib/mongoid/errors/invalid_options.rb +4 -2
  173. data/lib/mongoid/errors/invalid_path.rb +2 -0
  174. data/lib/mongoid/errors/invalid_persistence_option.rb +2 -0
  175. data/lib/mongoid/errors/invalid_query.rb +41 -0
  176. data/lib/mongoid/errors/invalid_relation.rb +4 -2
  177. data/lib/mongoid/errors/invalid_relation_option.rb +31 -0
  178. data/lib/mongoid/errors/invalid_scope.rb +2 -0
  179. data/lib/mongoid/errors/invalid_session_use.rb +2 -0
  180. data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +6 -4
  181. data/lib/mongoid/errors/invalid_storage_options.rb +2 -0
  182. data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
  183. data/lib/mongoid/errors/invalid_time.rb +2 -0
  184. data/lib/mongoid/errors/invalid_value.rb +2 -0
  185. data/lib/mongoid/errors/inverse_not_found.rb +3 -1
  186. data/lib/mongoid/errors/mixed_client_configuration.rb +2 -0
  187. data/lib/mongoid/errors/mixed_relations.rb +2 -0
  188. data/lib/mongoid/errors/mongoid_error.rb +3 -1
  189. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +3 -1
  190. data/lib/mongoid/errors/no_client_config.rb +4 -2
  191. data/lib/mongoid/errors/no_client_database.rb +2 -0
  192. data/lib/mongoid/errors/no_client_hosts.rb +2 -0
  193. data/lib/mongoid/errors/no_clients_config.rb +2 -0
  194. data/lib/mongoid/errors/no_default_client.rb +3 -1
  195. data/lib/mongoid/errors/no_environment.rb +2 -0
  196. data/lib/mongoid/errors/no_map_reduce_output.rb +2 -0
  197. data/lib/mongoid/errors/no_metadata.rb +2 -0
  198. data/lib/mongoid/errors/no_parent.rb +2 -0
  199. data/lib/mongoid/errors/readonly_attribute.rb +2 -0
  200. data/lib/mongoid/errors/readonly_document.rb +2 -0
  201. data/lib/mongoid/errors/scope_overwrite.rb +2 -0
  202. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +3 -0
  203. data/lib/mongoid/errors/unknown_attribute.rb +2 -0
  204. data/lib/mongoid/errors/unknown_model.rb +27 -0
  205. data/lib/mongoid/errors/unsaved_document.rb +2 -0
  206. data/lib/mongoid/errors/unsupported_javascript.rb +2 -0
  207. data/lib/mongoid/errors/validations.rb +2 -0
  208. data/lib/mongoid/errors.rb +13 -0
  209. data/lib/mongoid/evolvable.rb +4 -2
  210. data/lib/mongoid/extensions/array.rb +28 -11
  211. data/lib/mongoid/extensions/big_decimal.rb +2 -0
  212. data/lib/mongoid/extensions/boolean.rb +3 -2
  213. data/lib/mongoid/extensions/date.rb +13 -3
  214. data/lib/mongoid/extensions/date_time.rb +4 -3
  215. data/lib/mongoid/extensions/decimal128.rb +2 -0
  216. data/lib/mongoid/extensions/false_class.rb +3 -1
  217. data/lib/mongoid/extensions/float.rb +5 -3
  218. data/lib/mongoid/extensions/hash.rb +58 -13
  219. data/lib/mongoid/extensions/integer.rb +5 -3
  220. data/lib/mongoid/extensions/module.rb +2 -0
  221. data/lib/mongoid/extensions/nil_class.rb +2 -0
  222. data/lib/mongoid/extensions/object.rb +20 -8
  223. data/lib/mongoid/extensions/object_id.rb +2 -0
  224. data/lib/mongoid/extensions/range.rb +3 -0
  225. data/lib/mongoid/extensions/regexp.rb +3 -1
  226. data/lib/mongoid/extensions/set.rb +2 -0
  227. data/lib/mongoid/extensions/string.rb +23 -12
  228. data/lib/mongoid/extensions/symbol.rb +2 -0
  229. data/lib/mongoid/extensions/time.rb +14 -0
  230. data/lib/mongoid/extensions/time_with_zone.rb +14 -0
  231. data/lib/mongoid/extensions/true_class.rb +3 -1
  232. data/lib/mongoid/extensions.rb +3 -4
  233. data/lib/mongoid/factory.rb +59 -9
  234. data/lib/mongoid/fields/foreign_key.rb +8 -6
  235. data/lib/mongoid/fields/localized.rb +2 -0
  236. data/lib/mongoid/fields/standard.rb +8 -17
  237. data/lib/mongoid/fields/validators/macro.rb +39 -12
  238. data/lib/mongoid/fields/validators.rb +2 -0
  239. data/lib/mongoid/fields.rb +54 -10
  240. data/lib/mongoid/findable.rb +59 -18
  241. data/lib/mongoid/indexable/specification.rb +3 -1
  242. data/lib/mongoid/indexable/validators/options.rb +2 -0
  243. data/lib/mongoid/indexable.rb +9 -4
  244. data/lib/mongoid/inspectable.rb +4 -2
  245. data/lib/mongoid/interceptable.rb +18 -10
  246. data/lib/mongoid/loggable.rb +13 -7
  247. data/lib/mongoid/matchable.rb +3 -148
  248. data/lib/mongoid/matcher/all.rb +22 -0
  249. data/lib/mongoid/matcher/and.rb +21 -0
  250. data/lib/mongoid/matcher/bits.rb +41 -0
  251. data/lib/mongoid/matcher/bits_all_clear.rb +20 -0
  252. data/lib/mongoid/matcher/bits_all_set.rb +20 -0
  253. data/lib/mongoid/matcher/bits_any_clear.rb +20 -0
  254. data/lib/mongoid/matcher/bits_any_set.rb +20 -0
  255. data/lib/mongoid/matcher/elem_match.rb +36 -0
  256. data/lib/mongoid/matcher/elem_match_expression.rb +20 -0
  257. data/lib/mongoid/matcher/eq.rb +11 -0
  258. data/lib/mongoid/matcher/eq_impl.rb +32 -0
  259. data/lib/mongoid/matcher/eq_impl_with_regexp.rb +21 -0
  260. data/lib/mongoid/matcher/exists.rb +15 -0
  261. data/lib/mongoid/matcher/expression.rb +35 -0
  262. data/lib/mongoid/matcher/expression_operator.rb +19 -0
  263. data/lib/mongoid/matcher/field_expression.rb +62 -0
  264. data/lib/mongoid/matcher/field_operator.rb +54 -0
  265. data/lib/mongoid/matcher/gt.rb +17 -0
  266. data/lib/mongoid/matcher/gte.rb +17 -0
  267. data/lib/mongoid/matcher/in.rb +25 -0
  268. data/lib/mongoid/matcher/lt.rb +17 -0
  269. data/lib/mongoid/matcher/lte.rb +17 -0
  270. data/lib/mongoid/matcher/mod.rb +17 -0
  271. data/lib/mongoid/matcher/ne.rb +16 -0
  272. data/lib/mongoid/matcher/nin.rb +11 -0
  273. data/lib/mongoid/matcher/nor.rb +25 -0
  274. data/lib/mongoid/matcher/not.rb +29 -0
  275. data/lib/mongoid/matcher/or.rb +21 -0
  276. data/lib/mongoid/matcher/regex.rb +41 -0
  277. data/lib/mongoid/matcher/size.rb +26 -0
  278. data/lib/mongoid/matcher/type.rb +99 -0
  279. data/lib/mongoid/matcher.rb +110 -0
  280. data/lib/mongoid/persistable/creatable.rb +3 -1
  281. data/lib/mongoid/persistable/deletable.rb +11 -9
  282. data/lib/mongoid/persistable/destroyable.rb +11 -3
  283. data/lib/mongoid/persistable/incrementable.rb +7 -3
  284. data/lib/mongoid/persistable/logical.rb +5 -2
  285. data/lib/mongoid/persistable/poppable.rb +3 -1
  286. data/lib/mongoid/persistable/pullable.rb +3 -1
  287. data/lib/mongoid/persistable/pushable.rb +14 -3
  288. data/lib/mongoid/persistable/renamable.rb +10 -3
  289. data/lib/mongoid/persistable/savable.rb +3 -1
  290. data/lib/mongoid/persistable/settable.rb +60 -13
  291. data/lib/mongoid/persistable/unsettable.rb +8 -3
  292. data/lib/mongoid/persistable/updatable.rb +30 -3
  293. data/lib/mongoid/persistable/upsertable.rb +3 -1
  294. data/lib/mongoid/persistable.rb +136 -19
  295. data/lib/mongoid/persistence_context.rb +47 -20
  296. data/lib/mongoid/positional.rb +3 -1
  297. data/lib/mongoid/query_cache.rb +132 -77
  298. data/lib/mongoid/railtie.rb +3 -1
  299. data/lib/mongoid/railties/controller_runtime.rb +4 -1
  300. data/lib/mongoid/railties/database.rake +9 -0
  301. data/lib/mongoid/reloadable.rb +11 -4
  302. data/lib/mongoid/scopable.rb +2 -1
  303. data/lib/mongoid/selectable.rb +8 -8
  304. data/lib/mongoid/serializable.rb +28 -18
  305. data/lib/mongoid/shardable.rb +80 -10
  306. data/lib/mongoid/stateful.rb +3 -1
  307. data/lib/mongoid/stringified_symbol.rb +53 -0
  308. data/lib/mongoid/tasks/database.rake +12 -5
  309. data/lib/mongoid/tasks/database.rb +85 -0
  310. data/lib/mongoid/threaded/lifecycle.rb +2 -0
  311. data/lib/mongoid/threaded.rb +2 -0
  312. data/lib/mongoid/timestamps/created/short.rb +2 -0
  313. data/lib/mongoid/timestamps/created.rb +3 -1
  314. data/lib/mongoid/timestamps/short.rb +2 -0
  315. data/lib/mongoid/timestamps/timeless.rb +6 -2
  316. data/lib/mongoid/timestamps/updated/short.rb +2 -0
  317. data/lib/mongoid/timestamps/updated.rb +3 -1
  318. data/lib/mongoid/timestamps.rb +3 -1
  319. data/lib/mongoid/touchable.rb +129 -0
  320. data/lib/mongoid/traversable.rb +118 -9
  321. data/lib/mongoid/validatable/associated.rb +5 -3
  322. data/lib/mongoid/validatable/format.rb +2 -0
  323. data/lib/mongoid/validatable/length.rb +2 -0
  324. data/lib/mongoid/validatable/localizable.rb +2 -0
  325. data/lib/mongoid/validatable/macros.rb +3 -1
  326. data/lib/mongoid/validatable/presence.rb +9 -7
  327. data/lib/mongoid/validatable/queryable.rb +2 -0
  328. data/lib/mongoid/validatable/uniqueness.rb +10 -8
  329. data/lib/mongoid/validatable.rb +15 -13
  330. data/lib/mongoid/version.rb +3 -1
  331. data/lib/mongoid.rb +35 -2
  332. data/lib/rails/generators/mongoid/config/config_generator.rb +10 -1
  333. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +45 -27
  334. data/lib/rails/generators/mongoid/model/model_generator.rb +3 -1
  335. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +1 -1
  336. data/lib/rails/generators/mongoid_generator.rb +2 -0
  337. data/lib/rails/mongoid.rb +4 -2
  338. data/lib/support/ruby_version.rb +3 -0
  339. data/spec/README.md +33 -0
  340. data/spec/config/mongoid.yml +14 -3
  341. data/spec/integration/app_spec.rb +344 -0
  342. data/spec/integration/associations/belongs_to_spec.rb +16 -0
  343. data/spec/integration/associations/embedded_spec.rb +269 -0
  344. data/spec/integration/associations/embeds_many_spec.rb +68 -0
  345. data/spec/integration/associations/embeds_one_spec.rb +24 -0
  346. data/spec/integration/associations/foreign_key_spec.rb +99 -0
  347. data/spec/integration/associations/foreign_key_spec_models.rb +65 -0
  348. data/spec/integration/associations/has_many_spec.rb +129 -0
  349. data/spec/integration/associations/has_one_spec.rb +177 -0
  350. data/spec/integration/associations/nested_attributes_assignment_spec.rb +116 -0
  351. data/spec/integration/associations/reverse_population_spec.rb +35 -0
  352. data/spec/integration/associations/reverse_population_spec_models.rb +37 -0
  353. data/spec/integration/atomic/modifiers_spec.rb +117 -0
  354. data/spec/integration/bson_regexp_raw_spec.rb +20 -0
  355. data/spec/integration/callbacks_models.rb +49 -0
  356. data/spec/integration/callbacks_spec.rb +216 -0
  357. data/spec/integration/criteria/date_field_spec.rb +41 -0
  358. data/spec/integration/criteria/default_scope_spec.rb +21 -0
  359. data/spec/integration/criteria/logical_spec.rb +94 -0
  360. data/spec/integration/criteria/time_with_zone_spec.rb +32 -0
  361. data/spec/integration/discriminator_key_spec.rb +354 -0
  362. data/spec/integration/discriminator_value_spec.rb +207 -0
  363. data/spec/integration/document_spec.rb +52 -0
  364. data/spec/integration/i18n_fallbacks_spec.rb +90 -0
  365. data/spec/integration/matcher_examples_spec.rb +759 -0
  366. data/spec/integration/matcher_operator_data/all.yml +140 -0
  367. data/spec/integration/matcher_operator_data/and.yml +93 -0
  368. data/spec/integration/matcher_operator_data/bits_all_clear.yml +159 -0
  369. data/spec/integration/matcher_operator_data/bits_all_set.yml +159 -0
  370. data/spec/integration/matcher_operator_data/bits_any_clear.yml +159 -0
  371. data/spec/integration/matcher_operator_data/bits_any_set.yml +159 -0
  372. data/spec/integration/matcher_operator_data/comment.yml +22 -0
  373. data/spec/integration/matcher_operator_data/elem_match.yml +409 -0
  374. data/spec/integration/matcher_operator_data/elem_match_expr.yml +213 -0
  375. data/spec/integration/matcher_operator_data/eq.yml +191 -0
  376. data/spec/integration/matcher_operator_data/exists.yml +213 -0
  377. data/spec/integration/matcher_operator_data/generic_op.yml +17 -0
  378. data/spec/integration/matcher_operator_data/gt.yml +132 -0
  379. data/spec/integration/matcher_operator_data/gt_types.yml +63 -0
  380. data/spec/integration/matcher_operator_data/gte.yml +132 -0
  381. data/spec/integration/matcher_operator_data/gte_types.yml +15 -0
  382. data/spec/integration/matcher_operator_data/implicit.yml +331 -0
  383. data/spec/integration/matcher_operator_data/implicit_traversal.yml +112 -0
  384. data/spec/integration/matcher_operator_data/in.yml +210 -0
  385. data/spec/integration/matcher_operator_data/invalid_op.yml +59 -0
  386. data/spec/integration/matcher_operator_data/invalid_syntax.yml +39 -0
  387. data/spec/integration/matcher_operator_data/lt.yml +132 -0
  388. data/spec/integration/matcher_operator_data/lt_types.yml +15 -0
  389. data/spec/integration/matcher_operator_data/lte.yml +132 -0
  390. data/spec/integration/matcher_operator_data/lte_types.yml +15 -0
  391. data/spec/integration/matcher_operator_data/mod.yml +55 -0
  392. data/spec/integration/matcher_operator_data/multiple.yml +29 -0
  393. data/spec/integration/matcher_operator_data/ne.yml +150 -0
  394. data/spec/integration/matcher_operator_data/ne_types.yml +15 -0
  395. data/spec/integration/matcher_operator_data/nin.yml +114 -0
  396. data/spec/integration/matcher_operator_data/nor.yml +126 -0
  397. data/spec/integration/matcher_operator_data/not.yml +196 -0
  398. data/spec/integration/matcher_operator_data/or.yml +137 -0
  399. data/spec/integration/matcher_operator_data/regex.yml +174 -0
  400. data/spec/integration/matcher_operator_data/regex_options.yml +72 -0
  401. data/spec/integration/matcher_operator_data/size.yml +174 -0
  402. data/spec/integration/matcher_operator_data/type.yml +70 -0
  403. data/spec/integration/matcher_operator_data/type_array.yml +16 -0
  404. data/spec/integration/matcher_operator_data/type_binary.yml +18 -0
  405. data/spec/integration/matcher_operator_data/type_boolean.yml +39 -0
  406. data/spec/integration/matcher_operator_data/type_code.yml +26 -0
  407. data/spec/integration/matcher_operator_data/type_code_with_scope.yml +26 -0
  408. data/spec/integration/matcher_operator_data/type_date.yml +39 -0
  409. data/spec/integration/matcher_operator_data/type_db_pointer.yml +19 -0
  410. data/spec/integration/matcher_operator_data/type_decimal.yml +40 -0
  411. data/spec/integration/matcher_operator_data/type_double.yml +15 -0
  412. data/spec/integration/matcher_operator_data/type_int32.yml +33 -0
  413. data/spec/integration/matcher_operator_data/type_int64.yml +33 -0
  414. data/spec/integration/matcher_operator_data/type_max_key.yml +17 -0
  415. data/spec/integration/matcher_operator_data/type_min_key.yml +17 -0
  416. data/spec/integration/matcher_operator_data/type_null.yml +23 -0
  417. data/spec/integration/matcher_operator_data/type_object.yml +23 -0
  418. data/spec/integration/matcher_operator_data/type_object_id.yml +25 -0
  419. data/spec/integration/matcher_operator_data/type_regex.yml +44 -0
  420. data/spec/integration/matcher_operator_data/type_string.yml +15 -0
  421. data/spec/integration/matcher_operator_data/type_symbol.yml +32 -0
  422. data/spec/integration/matcher_operator_data/type_timestamp.yml +25 -0
  423. data/spec/integration/matcher_operator_data/type_undefined.yml +17 -0
  424. data/spec/integration/matcher_operator_spec.rb +100 -0
  425. data/spec/integration/matcher_spec.rb +189 -0
  426. data/spec/integration/server_query_spec.rb +142 -0
  427. data/spec/integration/shardable_spec.rb +149 -0
  428. data/spec/integration/stringified_symbol_field_spec.rb +190 -0
  429. data/spec/lite_spec_helper.rb +77 -0
  430. data/spec/mongoid/association/accessors_spec.rb +1038 -0
  431. data/spec/mongoid/association/auto_save_spec.rb +365 -0
  432. data/spec/mongoid/association/builders_spec.rb +256 -0
  433. data/spec/mongoid/association/constrainable_spec.rb +118 -0
  434. data/spec/mongoid/association/counter_cache_spec.rb +453 -0
  435. data/spec/mongoid/association/depending_spec.rb +960 -0
  436. data/spec/mongoid/association/eager_spec.rb +282 -0
  437. data/spec/mongoid/association/embedded/cyclic_spec.rb +181 -0
  438. data/spec/mongoid/association/embedded/dirty_spec.rb +68 -0
  439. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +174 -0
  440. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +37 -0
  441. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +560 -0
  442. data/spec/mongoid/association/embedded/embedded_in_spec.rb +904 -0
  443. data/spec/mongoid/association/embedded/embeds_many/binding_spec.rb +57 -0
  444. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +107 -0
  445. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +4403 -0
  446. data/spec/mongoid/association/embedded/embeds_many_models.rb +54 -0
  447. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +52 -0
  448. data/spec/mongoid/association/embedded/embeds_many_spec.rb +865 -0
  449. data/spec/mongoid/association/embedded/embeds_one/binding_spec.rb +80 -0
  450. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +82 -0
  451. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +1026 -0
  452. data/spec/mongoid/association/embedded/embeds_one_dnl_models.rb +9 -0
  453. data/spec/mongoid/association/embedded/embeds_one_models.rb +55 -0
  454. data/spec/mongoid/association/embedded/embeds_one_query_spec.rb +29 -0
  455. data/spec/mongoid/association/embedded/embeds_one_spec.rb +957 -0
  456. data/spec/mongoid/association/macros_spec.rb +1117 -0
  457. data/spec/mongoid/association/nested/many_spec.rb +233 -0
  458. data/spec/mongoid/association/nested/one_spec.rb +254 -0
  459. data/spec/mongoid/association/options_spec.rb +1324 -0
  460. data/spec/mongoid/association/polymorphic_spec.rb +163 -0
  461. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +244 -0
  462. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +200 -0
  463. data/spec/mongoid/association/referenced/belongs_to/eager_spec.rb +377 -0
  464. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +1369 -0
  465. data/spec/mongoid/association/referenced/belongs_to_query_spec.rb +38 -0
  466. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2026 -0
  467. data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +181 -0
  468. data/spec/mongoid/association/referenced/has_and_belongs_to_many/buildable_spec.rb +124 -0
  469. data/spec/mongoid/association/referenced/has_and_belongs_to_many/eager_spec.rb +168 -0
  470. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_persistence_spec.rb +77 -0
  471. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +3748 -0
  472. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +50 -0
  473. data/spec/mongoid/association/referenced/has_and_belongs_to_many_query_spec.rb +40 -0
  474. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +1051 -0
  475. data/spec/mongoid/association/referenced/has_many/binding_spec.rb +156 -0
  476. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +122 -0
  477. data/spec/mongoid/association/referenced/has_many/eager_spec.rb +274 -0
  478. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +2054 -0
  479. data/spec/mongoid/association/referenced/has_many/proxy_query_spec.rb +24 -0
  480. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +4029 -0
  481. data/spec/mongoid/association/referenced/has_many_models.rb +61 -0
  482. data/spec/mongoid/association/referenced/has_many_query_spec.rb +38 -0
  483. data/spec/mongoid/association/referenced/has_many_spec.rb +1228 -0
  484. data/spec/mongoid/association/referenced/has_one/binding_spec.rb +134 -0
  485. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +116 -0
  486. data/spec/mongoid/association/referenced/has_one/eager_spec.rb +178 -0
  487. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +1143 -0
  488. data/spec/mongoid/association/referenced/has_one_models.rb +80 -0
  489. data/spec/mongoid/association/referenced/has_one_query_spec.rb +38 -0
  490. data/spec/mongoid/association/referenced/has_one_spec.rb +1363 -0
  491. data/spec/mongoid/association/reflections_spec.rb +93 -0
  492. data/spec/mongoid/association/syncable_spec.rb +500 -0
  493. data/spec/mongoid/association_spec.rb +192 -0
  494. data/spec/mongoid/atomic/modifiers_spec.rb +52 -2
  495. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +3 -0
  496. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +3 -0
  497. data/spec/mongoid/atomic/paths/root_spec.rb +3 -0
  498. data/spec/mongoid/atomic/paths_spec.rb +108 -12
  499. data/spec/mongoid/atomic_spec.rb +30 -4
  500. data/spec/mongoid/attributes/dynamic_spec.rb +153 -0
  501. data/spec/mongoid/attributes/nested_spec.rb +33 -12
  502. data/spec/mongoid/attributes/projector_data/embedded.yml +105 -0
  503. data/spec/mongoid/attributes/projector_data/fields.yml +93 -0
  504. data/spec/mongoid/attributes/projector_spec.rb +41 -0
  505. data/spec/mongoid/attributes/readonly_spec.rb +83 -125
  506. data/spec/mongoid/attributes_spec.rb +393 -9
  507. data/spec/mongoid/cacheable_spec.rb +3 -0
  508. data/spec/mongoid/changeable_spec.rb +26 -0
  509. data/spec/mongoid/clients/factory_spec.rb +142 -33
  510. data/spec/mongoid/clients/options_spec.rb +83 -56
  511. data/spec/mongoid/clients/sessions_spec.rb +19 -8
  512. data/spec/mongoid/clients/transactions_spec.rb +393 -0
  513. data/spec/mongoid/clients_spec.rb +73 -10
  514. data/spec/mongoid/composable_spec.rb +3 -0
  515. data/spec/mongoid/config/environment_spec.rb +3 -0
  516. data/spec/mongoid/config/options_spec.rb +23 -3
  517. data/spec/mongoid/config_spec.rb +126 -1
  518. data/spec/mongoid/contextual/aggregable/memory_spec.rb +3 -0
  519. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +3 -0
  520. data/spec/mongoid/contextual/atomic_spec.rb +137 -14
  521. data/spec/mongoid/contextual/geo_near_spec.rb +15 -2
  522. data/spec/mongoid/contextual/map_reduce_spec.rb +23 -5
  523. data/spec/mongoid/contextual/memory_spec.rb +22 -0
  524. data/spec/mongoid/contextual/mongo_spec.rb +185 -75
  525. data/spec/mongoid/contextual/none_spec.rb +3 -0
  526. data/spec/mongoid/copyable_spec.rb +289 -23
  527. data/spec/mongoid/copyable_spec_models.rb +48 -0
  528. data/spec/mongoid/criteria/findable_spec.rb +58 -0
  529. data/spec/mongoid/criteria/inspectable_spec.rb +3 -0
  530. data/spec/mongoid/criteria/marshalable_spec.rb +3 -0
  531. data/spec/mongoid/criteria/modifiable_spec.rb +181 -5
  532. data/spec/mongoid/criteria/options_spec.rb +3 -0
  533. data/spec/mongoid/criteria/queryable/aggregable_spec.rb +3 -0
  534. data/spec/mongoid/criteria/queryable/expandable_spec.rb +62 -0
  535. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +3 -0
  536. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +3 -0
  537. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +3 -0
  538. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +4 -1
  539. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +3 -0
  540. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +36 -17
  541. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +3 -0
  542. data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +3 -0
  543. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +3 -0
  544. data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +3 -0
  545. data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +3 -0
  546. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +54 -0
  547. data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +3 -0
  548. data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +3 -0
  549. data/spec/mongoid/criteria/queryable/extensions/regexp_raw_spec.rb +4 -1
  550. data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +10 -7
  551. data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +3 -0
  552. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +47 -1
  553. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +3 -0
  554. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +43 -23
  555. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +31 -1
  556. data/spec/mongoid/criteria/queryable/key_spec.rb +51 -6
  557. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +146 -12
  558. data/spec/mongoid/criteria/queryable/optional_spec.rb +3 -0
  559. data/spec/mongoid/criteria/queryable/options_spec.rb +3 -0
  560. data/spec/mongoid/criteria/queryable/pipeline_spec.rb +15 -0
  561. data/spec/mongoid/criteria/queryable/queryable_spec.rb +3 -0
  562. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +2070 -0
  563. data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +39 -0
  564. data/spec/mongoid/criteria/queryable/selectable_spec.rb +993 -2937
  565. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +590 -0
  566. data/spec/mongoid/criteria/queryable/selector_spec.rb +40 -0
  567. data/spec/mongoid/criteria/queryable/smash_spec.rb +3 -0
  568. data/spec/mongoid/criteria/queryable/storable_spec.rb +190 -0
  569. data/spec/mongoid/criteria/scopable_spec.rb +3 -0
  570. data/spec/mongoid/criteria_projection_spec.rb +411 -0
  571. data/spec/mongoid/criteria_spec.rb +280 -297
  572. data/spec/mongoid/document_fields_spec.rb +114 -0
  573. data/spec/mongoid/document_persistence_context_spec.rb +33 -0
  574. data/spec/mongoid/document_query_spec.rb +90 -0
  575. data/spec/mongoid/document_spec.rb +121 -19
  576. data/spec/mongoid/equality_spec.rb +3 -1
  577. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +6 -3
  578. data/spec/mongoid/errors/callback_spec.rb +3 -0
  579. data/spec/mongoid/errors/delete_restriction_spec.rb +5 -2
  580. data/spec/mongoid/errors/document_not_destroyed_spec.rb +3 -0
  581. data/spec/mongoid/errors/document_not_found_spec.rb +3 -0
  582. data/spec/mongoid/errors/eager_load_spec.rb +3 -0
  583. data/spec/mongoid/errors/invalid_collection_spec.rb +3 -0
  584. data/spec/mongoid/errors/invalid_config_option_spec.rb +3 -0
  585. data/spec/mongoid/errors/invalid_field_option_spec.rb +3 -0
  586. data/spec/mongoid/errors/invalid_field_spec.rb +3 -0
  587. data/spec/mongoid/errors/invalid_find_spec.rb +3 -0
  588. data/spec/mongoid/errors/invalid_includes_spec.rb +3 -0
  589. data/spec/mongoid/errors/invalid_index_spec.rb +3 -0
  590. data/spec/mongoid/errors/invalid_options_spec.rb +5 -2
  591. data/spec/mongoid/errors/invalid_path_spec.rb +3 -0
  592. data/spec/mongoid/errors/invalid_relation_spec.rb +5 -2
  593. data/spec/mongoid/errors/invalid_scope_spec.rb +3 -0
  594. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +3 -0
  595. data/spec/mongoid/errors/invalid_storage_options_spec.rb +3 -0
  596. data/spec/mongoid/errors/invalid_time_spec.rb +3 -0
  597. data/spec/mongoid/errors/inverse_not_found_spec.rb +4 -1
  598. data/spec/mongoid/errors/mixed_client_configuration_spec.rb +3 -0
  599. data/spec/mongoid/errors/mixed_relations_spec.rb +3 -0
  600. data/spec/mongoid/errors/mongoid_error_spec.rb +23 -8
  601. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +6 -3
  602. data/spec/mongoid/errors/no_client_config_spec.rb +5 -2
  603. data/spec/mongoid/errors/no_client_database_spec.rb +6 -3
  604. data/spec/mongoid/errors/no_client_hosts_spec.rb +6 -3
  605. data/spec/mongoid/errors/no_clients_config_spec.rb +3 -0
  606. data/spec/mongoid/errors/no_environment_spec.rb +3 -0
  607. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +3 -0
  608. data/spec/mongoid/errors/no_metadata_spec.rb +5 -2
  609. data/spec/mongoid/errors/no_parent_spec.rb +4 -1
  610. data/spec/mongoid/errors/readonly_attribute_spec.rb +3 -0
  611. data/spec/mongoid/errors/readonly_document_spec.rb +3 -0
  612. data/spec/mongoid/errors/scope_overwrite_spec.rb +3 -0
  613. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +3 -0
  614. data/spec/mongoid/errors/unknown_attribute_spec.rb +3 -0
  615. data/spec/mongoid/errors/unsaved_document_spec.rb +4 -1
  616. data/spec/mongoid/errors/unsupported_javascript_spec.rb +3 -0
  617. data/spec/mongoid/errors/validations_spec.rb +3 -0
  618. data/spec/mongoid/extensions/array_spec.rb +37 -58
  619. data/spec/mongoid/extensions/big_decimal_spec.rb +3 -0
  620. data/spec/mongoid/extensions/binary_spec.rb +3 -0
  621. data/spec/mongoid/extensions/boolean_spec.rb +3 -0
  622. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +336 -0
  623. data/spec/mongoid/extensions/date_spec.rb +9 -160
  624. data/spec/mongoid/extensions/date_time_spec.rb +18 -60
  625. data/spec/mongoid/extensions/decimal128_spec.rb +3 -0
  626. data/spec/mongoid/extensions/false_class_spec.rb +4 -1
  627. data/spec/mongoid/extensions/float_spec.rb +18 -3
  628. data/spec/mongoid/extensions/hash_spec.rb +124 -1
  629. data/spec/mongoid/extensions/integer_spec.rb +15 -2
  630. data/spec/mongoid/extensions/module_spec.rb +3 -0
  631. data/spec/mongoid/extensions/nil_class_spec.rb +3 -0
  632. data/spec/mongoid/extensions/object_id_spec.rb +3 -0
  633. data/spec/mongoid/extensions/object_spec.rb +21 -35
  634. data/spec/mongoid/extensions/range_spec.rb +10 -0
  635. data/spec/mongoid/extensions/regexp_spec.rb +3 -0
  636. data/spec/mongoid/extensions/set_spec.rb +3 -0
  637. data/spec/mongoid/extensions/string_spec.rb +94 -32
  638. data/spec/mongoid/extensions/stringified_symbol_spec.rb +85 -0
  639. data/spec/mongoid/extensions/symbol_spec.rb +3 -0
  640. data/spec/mongoid/extensions/time_spec.rb +30 -0
  641. data/spec/mongoid/extensions/time_with_zone_spec.rb +34 -0
  642. data/spec/mongoid/extensions/true_class_spec.rb +4 -1
  643. data/spec/mongoid/extensions_spec.rb +3 -0
  644. data/spec/mongoid/factory_spec.rb +301 -23
  645. data/spec/mongoid/fields/foreign_key_spec.rb +27 -32
  646. data/spec/mongoid/fields/localized_spec.rb +7 -4
  647. data/spec/mongoid/fields/standard_spec.rb +3 -0
  648. data/spec/mongoid/fields_spec.rb +94 -7
  649. data/spec/mongoid/findable_spec.rb +36 -1
  650. data/spec/mongoid/indexable/specification_spec.rb +3 -0
  651. data/spec/mongoid/indexable_spec.rb +55 -14
  652. data/spec/mongoid/inspectable_spec.rb +40 -2
  653. data/spec/mongoid/interceptable_spec.rb +89 -3
  654. data/spec/mongoid/interceptable_spec_models.rb +76 -0
  655. data/spec/mongoid/loggable_spec.rb +3 -0
  656. data/spec/mongoid/matcher/extract_attribute_data/numeric_keys.yml +104 -0
  657. data/spec/mongoid/matcher/extract_attribute_data/traversal.yml +239 -0
  658. data/spec/mongoid/matcher/extract_attribute_spec.rb +37 -0
  659. data/spec/mongoid/persistable/creatable_spec.rb +111 -25
  660. data/spec/mongoid/persistable/deletable_spec.rb +264 -1
  661. data/spec/mongoid/persistable/destroyable_spec.rb +194 -3
  662. data/spec/mongoid/persistable/incrementable_spec.rb +17 -0
  663. data/spec/mongoid/persistable/logical_spec.rb +17 -0
  664. data/spec/mongoid/persistable/poppable_spec.rb +17 -0
  665. data/spec/mongoid/persistable/pullable_spec.rb +31 -0
  666. data/spec/mongoid/persistable/pushable_spec.rb +86 -1
  667. data/spec/mongoid/persistable/renamable_spec.rb +17 -0
  668. data/spec/mongoid/persistable/savable_spec.rb +176 -17
  669. data/spec/mongoid/persistable/settable_spec.rb +142 -10
  670. data/spec/mongoid/persistable/unsettable_spec.rb +17 -0
  671. data/spec/mongoid/persistable/updatable_spec.rb +3 -0
  672. data/spec/mongoid/persistable/upsertable_spec.rb +4 -1
  673. data/spec/mongoid/persistable_spec.rb +106 -14
  674. data/spec/mongoid/persistence_context_spec.rb +4 -1
  675. data/spec/mongoid/positional_spec.rb +3 -0
  676. data/spec/mongoid/query_cache_middleware_spec.rb +69 -0
  677. data/spec/mongoid/query_cache_spec.rb +532 -65
  678. data/spec/mongoid/relations/proxy_spec.rb +127 -124
  679. data/spec/mongoid/reloadable_spec.rb +93 -1
  680. data/spec/mongoid/scopable_spec.rb +5 -1
  681. data/spec/mongoid/selectable_spec.rb +3 -0
  682. data/spec/mongoid/serializable_spec.rb +152 -20
  683. data/spec/mongoid/shardable_models.rb +61 -0
  684. data/spec/mongoid/shardable_spec.rb +146 -26
  685. data/spec/mongoid/stateful_spec.rb +3 -0
  686. data/spec/mongoid/tasks/database_rake_spec.rb +16 -13
  687. data/spec/mongoid/tasks/database_spec.rb +4 -1
  688. data/spec/mongoid/threaded_spec.rb +3 -0
  689. data/spec/mongoid/timestamps/created/short_spec.rb +3 -0
  690. data/spec/mongoid/timestamps/created_spec.rb +3 -0
  691. data/spec/mongoid/timestamps/timeless_spec.rb +3 -0
  692. data/spec/mongoid/timestamps/updated/short_spec.rb +3 -0
  693. data/spec/mongoid/timestamps/updated_spec.rb +3 -0
  694. data/spec/mongoid/timestamps_spec.rb +3 -0
  695. data/spec/mongoid/touchable_spec.rb +575 -0
  696. data/spec/mongoid/touchable_spec_models.rb +52 -0
  697. data/spec/mongoid/traversable_spec.rb +1103 -0
  698. data/spec/mongoid/validatable/associated_spec.rb +4 -1
  699. data/spec/mongoid/validatable/format_spec.rb +3 -0
  700. data/spec/mongoid/validatable/length_spec.rb +3 -0
  701. data/spec/mongoid/validatable/numericality_spec.rb +3 -0
  702. data/spec/mongoid/validatable/presence_spec.rb +10 -6
  703. data/spec/mongoid/validatable/uniqueness_spec.rb +36 -6
  704. data/spec/mongoid/validatable_spec.rb +4 -1
  705. data/spec/mongoid_spec.rb +3 -0
  706. data/spec/rails/controller_extension/controller_runtime_spec.rb +4 -1
  707. data/spec/rails/mongoid_spec.rb +5 -2
  708. data/spec/shared/LICENSE +20 -0
  709. data/spec/shared/bin/get-mongodb-download-url +17 -0
  710. data/spec/shared/bin/s3-copy +45 -0
  711. data/spec/shared/bin/s3-upload +69 -0
  712. data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
  713. data/spec/shared/lib/mrss/cluster_config.rb +226 -0
  714. data/spec/shared/lib/mrss/constraints.rb +368 -0
  715. data/spec/shared/lib/mrss/docker_runner.rb +271 -0
  716. data/spec/shared/lib/mrss/lite_constraints.rb +191 -0
  717. data/spec/shared/lib/mrss/server_version_registry.rb +115 -0
  718. data/spec/shared/lib/mrss/spec_organizer.rb +179 -0
  719. data/spec/shared/lib/mrss/utils.rb +15 -0
  720. data/spec/shared/share/Dockerfile.erb +322 -0
  721. data/spec/shared/share/haproxy-1.conf +16 -0
  722. data/spec/shared/share/haproxy-2.conf +17 -0
  723. data/spec/shared/shlib/distro.sh +73 -0
  724. data/spec/shared/shlib/server.sh +317 -0
  725. data/spec/shared/shlib/set_env.sh +131 -0
  726. data/spec/spec_helper.rb +65 -58
  727. data/spec/support/authorization.rb +3 -0
  728. data/spec/support/client_registry.rb +9 -0
  729. data/spec/support/constraints.rb +54 -0
  730. data/spec/support/expectations.rb +22 -3
  731. data/spec/support/helpers.rb +11 -0
  732. data/spec/support/macros.rb +21 -0
  733. data/spec/support/models/account.rb +39 -0
  734. data/spec/support/models/acolyte.rb +20 -0
  735. data/spec/support/models/actor.rb +21 -0
  736. data/spec/support/models/actress.rb +5 -0
  737. data/spec/support/models/address.rb +86 -0
  738. data/spec/support/models/address_component.rb +8 -0
  739. data/spec/support/models/address_number.rb +9 -0
  740. data/spec/support/models/agency.rb +8 -0
  741. data/spec/support/models/agent.rb +19 -0
  742. data/spec/support/models/album.rb +21 -0
  743. data/spec/support/models/alert.rb +10 -0
  744. data/spec/support/models/animal.rb +29 -0
  745. data/spec/support/models/answer.rb +9 -0
  746. data/spec/support/models/appointment.rb +10 -0
  747. data/spec/support/models/armrest.rb +10 -0
  748. data/spec/support/models/array_field.rb +8 -0
  749. data/spec/support/models/article.rb +15 -0
  750. data/spec/support/models/artist.rb +90 -0
  751. data/spec/support/models/artwork.rb +7 -0
  752. data/spec/support/models/audio.rb +8 -0
  753. data/spec/support/models/augmentation.rb +14 -0
  754. data/spec/support/models/author.rb +9 -0
  755. data/spec/support/models/baby.rb +7 -0
  756. data/spec/support/models/band.rb +34 -0
  757. data/spec/support/models/bar.rb +13 -0
  758. data/spec/support/models/basic.rb +9 -0
  759. data/spec/support/models/bed.rb +4 -0
  760. data/spec/support/models/big_palette.rb +5 -0
  761. data/spec/support/models/birthday.rb +16 -0
  762. data/spec/support/models/bolt.rb +8 -0
  763. data/spec/support/models/bomb.rb +7 -0
  764. data/spec/support/models/book.rb +19 -0
  765. data/spec/support/models/breed.rb +7 -0
  766. data/spec/support/models/browser.rb +9 -0
  767. data/spec/support/models/building.rb +9 -0
  768. data/spec/support/models/building_address.rb +10 -0
  769. data/spec/support/models/bus.rb +10 -0
  770. data/spec/support/models/business.rb +8 -0
  771. data/spec/support/models/callback_test.rb +12 -0
  772. data/spec/support/models/canvas.rb +28 -0
  773. data/spec/support/models/car.rb +4 -0
  774. data/spec/support/models/cat.rb +11 -0
  775. data/spec/support/models/category.rb +11 -0
  776. data/spec/support/models/child.rb +7 -0
  777. data/spec/support/models/child_doc.rb +25 -0
  778. data/spec/support/models/church.rb +9 -0
  779. data/spec/support/models/circle.rb +6 -0
  780. data/spec/support/models/circuit.rb +7 -0
  781. data/spec/support/models/circus.rb +10 -0
  782. data/spec/support/models/code.rb +14 -0
  783. data/spec/support/models/coding/pull_request.rb +12 -0
  784. data/spec/support/models/coding.rb +4 -0
  785. data/spec/support/models/comment.rb +19 -0
  786. data/spec/support/models/company.rb +8 -0
  787. data/spec/support/models/consumption_period.rb +10 -0
  788. data/spec/support/models/contextable_item.rb +8 -0
  789. data/spec/support/models/contractor.rb +8 -0
  790. data/spec/support/models/cookie.rb +9 -0
  791. data/spec/support/models/country_code.rb +11 -0
  792. data/spec/support/models/courier_job.rb +7 -0
  793. data/spec/support/models/crate.rb +13 -0
  794. data/spec/support/models/customer.rb +11 -0
  795. data/spec/support/models/customer_address.rb +12 -0
  796. data/spec/support/models/deed.rb +8 -0
  797. data/spec/support/models/definition.rb +12 -0
  798. data/spec/support/models/delegating_patient.rb +16 -0
  799. data/spec/support/models/description.rb +14 -0
  800. data/spec/support/models/dictionary.rb +19 -0
  801. data/spec/support/models/division.rb +13 -0
  802. data/spec/support/models/doctor.rb +15 -0
  803. data/spec/support/models/dog.rb +10 -0
  804. data/spec/support/models/dokument.rb +9 -0
  805. data/spec/support/models/draft.rb +12 -0
  806. data/spec/support/models/dragon.rb +7 -0
  807. data/spec/support/models/driver.rb +10 -0
  808. data/spec/support/models/drug.rb +9 -0
  809. data/spec/support/models/dungeon.rb +7 -0
  810. data/spec/support/models/edit.rb +8 -0
  811. data/spec/support/models/email.rb +9 -0
  812. data/spec/support/models/employer.rb +8 -0
  813. data/spec/support/models/entry.rb +9 -0
  814. data/spec/support/models/eraser.rb +4 -0
  815. data/spec/support/models/even.rb +10 -0
  816. data/spec/support/models/event.rb +25 -0
  817. data/spec/support/models/exhibition.rb +7 -0
  818. data/spec/support/models/exhibitor.rb +9 -0
  819. data/spec/support/models/explosion.rb +7 -0
  820. data/spec/support/models/eye.rb +12 -0
  821. data/spec/support/models/eye_bowl.rb +12 -0
  822. data/spec/support/models/face.rb +11 -0
  823. data/spec/support/models/favorite.rb +9 -0
  824. data/spec/support/models/filesystem.rb +8 -0
  825. data/spec/support/models/fire_hydrant.rb +9 -0
  826. data/spec/support/models/firefox.rb +7 -0
  827. data/spec/support/models/fish.rb +10 -0
  828. data/spec/support/models/folder.rb +10 -0
  829. data/spec/support/models/folder_item.rb +12 -0
  830. data/spec/support/models/fruits.rb +37 -0
  831. data/spec/support/models/game.rb +22 -0
  832. data/spec/support/models/ghost.rb +10 -0
  833. data/spec/support/models/guitar.rb +5 -0
  834. data/spec/support/models/hole.rb +13 -0
  835. data/spec/support/models/home.rb +7 -0
  836. data/spec/support/models/house.rb +9 -0
  837. data/spec/support/models/html_writer.rb +6 -0
  838. data/spec/support/models/id_key.rb +9 -0
  839. data/spec/support/models/idnodef.rb +8 -0
  840. data/spec/support/models/image.rb +25 -0
  841. data/spec/support/models/implant.rb +19 -0
  842. data/spec/support/models/instrument.rb +9 -0
  843. data/spec/support/models/item.rb +11 -0
  844. data/spec/support/models/jar.rb +10 -0
  845. data/spec/support/models/kaleidoscope.rb +9 -0
  846. data/spec/support/models/kangaroo.rb +7 -0
  847. data/spec/support/models/label.rb +50 -0
  848. data/spec/support/models/language.rb +8 -0
  849. data/spec/support/models/lat_lng.rb +18 -0
  850. data/spec/support/models/league.rb +14 -0
  851. data/spec/support/models/learner.rb +5 -0
  852. data/spec/support/models/line_item.rb +9 -0
  853. data/spec/support/models/location.rb +11 -0
  854. data/spec/support/models/login.rb +11 -0
  855. data/spec/support/models/manufacturer.rb +10 -0
  856. data/spec/support/models/meat.rb +7 -0
  857. data/spec/support/models/membership.rb +7 -0
  858. data/spec/support/models/message.rb +14 -0
  859. data/spec/support/models/minim.rb +7 -0
  860. data/spec/support/models/mixed_drink.rb +7 -0
  861. data/spec/support/models/mop.rb +25 -0
  862. data/spec/support/models/movie.rb +16 -0
  863. data/spec/support/models/my_hash.rb +5 -0
  864. data/spec/support/models/name.rb +27 -0
  865. data/spec/support/models/name_only.rb +9 -0
  866. data/spec/support/models/node.rb +8 -0
  867. data/spec/support/models/note.rb +20 -0
  868. data/spec/support/models/nut.rb +8 -0
  869. data/spec/support/models/odd.rb +10 -0
  870. data/spec/support/models/order.rb +11 -0
  871. data/spec/support/models/ordered_post.rb +14 -0
  872. data/spec/support/models/ordered_preference.rb +9 -0
  873. data/spec/support/models/oscar.rb +17 -0
  874. data/spec/support/models/other_owner_object.rb +5 -0
  875. data/spec/support/models/override.rb +19 -0
  876. data/spec/support/models/ownable.rb +9 -0
  877. data/spec/support/models/owner.rb +11 -0
  878. data/spec/support/models/pack.rb +6 -0
  879. data/spec/support/models/page.rb +19 -0
  880. data/spec/support/models/page_question.rb +7 -0
  881. data/spec/support/models/palette.rb +10 -0
  882. data/spec/support/models/parent.rb +8 -0
  883. data/spec/support/models/parent_doc.rb +9 -0
  884. data/spec/support/models/passport.rb +9 -0
  885. data/spec/support/models/patient.rb +12 -0
  886. data/spec/support/models/pdf_writer.rb +6 -0
  887. data/spec/support/models/pencil.rb +4 -0
  888. data/spec/support/models/person.rb +230 -0
  889. data/spec/support/models/pet.rb +26 -0
  890. data/spec/support/models/pet_owner.rb +9 -0
  891. data/spec/support/models/phone.rb +13 -0
  892. data/spec/support/models/piano.rb +5 -0
  893. data/spec/support/models/pizza.rb +10 -0
  894. data/spec/support/models/player.rb +38 -0
  895. data/spec/support/models/post.rb +53 -0
  896. data/spec/support/models/post_genre.rb +9 -0
  897. data/spec/support/models/powerup.rb +14 -0
  898. data/spec/support/models/preference.rb +12 -0
  899. data/spec/support/models/princess.rb +13 -0
  900. data/spec/support/models/product.rb +20 -0
  901. data/spec/support/models/profile.rb +18 -0
  902. data/spec/support/models/pronunciation.rb +8 -0
  903. data/spec/support/models/pub.rb +9 -0
  904. data/spec/support/models/publication/encyclopedia.rb +12 -0
  905. data/spec/support/models/publication/review.rb +14 -0
  906. data/spec/support/models/publication.rb +5 -0
  907. data/spec/support/models/purchase.rb +7 -0
  908. data/spec/support/models/question.rb +11 -0
  909. data/spec/support/models/quiz.rb +10 -0
  910. data/spec/support/models/rating.rb +11 -0
  911. data/spec/support/models/record.rb +55 -0
  912. data/spec/support/models/registry.rb +7 -0
  913. data/spec/support/models/role.rb +10 -0
  914. data/spec/support/models/root_category.rb +7 -0
  915. data/spec/support/models/sandwich.rb +12 -0
  916. data/spec/support/models/scheduler.rb +10 -0
  917. data/spec/support/models/scribe.rb +8 -0
  918. data/spec/support/models/sealer.rb +8 -0
  919. data/spec/support/models/seat.rb +25 -0
  920. data/spec/support/models/seo.rb +10 -0
  921. data/spec/support/models/series.rb +8 -0
  922. data/spec/support/models/server.rb +16 -0
  923. data/spec/support/models/service.rb +25 -0
  924. data/spec/support/models/shape.rb +15 -0
  925. data/spec/support/models/shelf.rb +8 -0
  926. data/spec/support/models/shipment_address.rb +6 -0
  927. data/spec/support/models/shipping_container.rb +8 -0
  928. data/spec/support/models/shipping_pack.rb +6 -0
  929. data/spec/support/models/shirt.rb +12 -0
  930. data/spec/support/models/shop.rb +9 -0
  931. data/spec/support/models/short_agent.rb +7 -0
  932. data/spec/support/models/short_quiz.rb +8 -0
  933. data/spec/support/models/simple.rb +8 -0
  934. data/spec/support/models/slave.rb +9 -0
  935. data/spec/support/models/song.rb +11 -0
  936. data/spec/support/models/sound.rb +8 -0
  937. data/spec/support/models/spacer.rb +8 -0
  938. data/spec/support/models/square.rb +7 -0
  939. data/spec/support/models/staff.rb +10 -0
  940. data/spec/support/models/store_as_dup_test1.rb +8 -0
  941. data/spec/support/models/store_as_dup_test2.rb +8 -0
  942. data/spec/support/models/store_as_dup_test3.rb +8 -0
  943. data/spec/support/models/store_as_dup_test4.rb +8 -0
  944. data/spec/support/models/strategy.rb +6 -0
  945. data/spec/support/models/sub_item.rb +6 -0
  946. data/spec/support/models/subscription.rb +8 -0
  947. data/spec/support/models/survey.rb +8 -0
  948. data/spec/support/models/symptom.rb +9 -0
  949. data/spec/support/models/system_role.rb +7 -0
  950. data/spec/support/models/tag.rb +11 -0
  951. data/spec/support/models/target.rb +8 -0
  952. data/spec/support/models/template.rb +8 -0
  953. data/spec/support/models/thing.rb +12 -0
  954. data/spec/support/models/threadlocker.rb +8 -0
  955. data/spec/support/models/title.rb +6 -0
  956. data/spec/support/models/tool.rb +11 -0
  957. data/spec/support/models/topping.rb +8 -0
  958. data/spec/support/models/toy.rb +10 -0
  959. data/spec/support/models/track.rb +41 -0
  960. data/spec/support/models/translation.rb +8 -0
  961. data/spec/support/models/tree.rb +12 -0
  962. data/spec/support/models/truck.rb +8 -0
  963. data/spec/support/models/updatable.rb +8 -0
  964. data/spec/support/models/user.rb +24 -0
  965. data/spec/support/models/user_account.rb +13 -0
  966. data/spec/support/models/validation_callback.rb +13 -0
  967. data/spec/support/models/vehicle.rb +19 -0
  968. data/spec/support/models/version.rb +8 -0
  969. data/spec/support/models/vertex.rb +9 -0
  970. data/spec/support/models/vet_visit.rb +8 -0
  971. data/spec/support/models/video.rb +16 -0
  972. data/spec/support/models/video_game.rb +4 -0
  973. data/spec/support/models/washer.rb +8 -0
  974. data/spec/support/models/weapon.rb +14 -0
  975. data/spec/support/models/wiki_page.rb +18 -0
  976. data/spec/support/models/word.rb +18 -0
  977. data/spec/support/models/word_origin.rb +14 -0
  978. data/spec/support/models/writer.rb +14 -0
  979. data/spec/support/session_registry.rb +50 -0
  980. data/spec/support/shared/time.rb +54 -0
  981. data/spec/support/spec_config.rb +58 -0
  982. data.tar.gz.sig +0 -0
  983. metadata +1226 -814
  984. metadata.gz.sig +0 -0
  985. data/lib/mongoid/criteria/queryable/forwardable.rb +0 -65
  986. data/lib/mongoid/matchable/all.rb +0 -27
  987. data/lib/mongoid/matchable/and.rb +0 -30
  988. data/lib/mongoid/matchable/default.rb +0 -72
  989. data/lib/mongoid/matchable/elem_match.rb +0 -28
  990. data/lib/mongoid/matchable/exists.rb +0 -23
  991. data/lib/mongoid/matchable/gt.rb +0 -23
  992. data/lib/mongoid/matchable/gte.rb +0 -23
  993. data/lib/mongoid/matchable/in.rb +0 -24
  994. data/lib/mongoid/matchable/lt.rb +0 -23
  995. data/lib/mongoid/matchable/lte.rb +0 -23
  996. data/lib/mongoid/matchable/ne.rb +0 -21
  997. data/lib/mongoid/matchable/nin.rb +0 -22
  998. data/lib/mongoid/matchable/nor.rb +0 -37
  999. data/lib/mongoid/matchable/or.rb +0 -33
  1000. data/lib/mongoid/matchable/regexp.rb +0 -27
  1001. data/lib/mongoid/matchable/size.rb +0 -21
  1002. data/lib/mongoid/relations/accessors.rb +0 -267
  1003. data/lib/mongoid/relations/auto_save.rb +0 -94
  1004. data/lib/mongoid/relations/binding.rb +0 -218
  1005. data/lib/mongoid/relations/bindings/embedded/in.rb +0 -59
  1006. data/lib/mongoid/relations/bindings/embedded/many.rb +0 -43
  1007. data/lib/mongoid/relations/bindings/embedded/one.rb +0 -45
  1008. data/lib/mongoid/relations/bindings/referenced/in.rb +0 -65
  1009. data/lib/mongoid/relations/bindings/referenced/many.rb +0 -38
  1010. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +0 -70
  1011. data/lib/mongoid/relations/bindings/referenced/one.rb +0 -44
  1012. data/lib/mongoid/relations/bindings.rb +0 -9
  1013. data/lib/mongoid/relations/builder.rb +0 -57
  1014. data/lib/mongoid/relations/builders/embedded/in.rb +0 -29
  1015. data/lib/mongoid/relations/builders/embedded/many.rb +0 -36
  1016. data/lib/mongoid/relations/builders/embedded/one.rb +0 -30
  1017. data/lib/mongoid/relations/builders/nested_attributes/many.rb +0 -199
  1018. data/lib/mongoid/relations/builders/nested_attributes/one.rb +0 -126
  1019. data/lib/mongoid/relations/builders/referenced/in.rb +0 -26
  1020. data/lib/mongoid/relations/builders/referenced/many.rb +0 -26
  1021. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +0 -39
  1022. data/lib/mongoid/relations/builders/referenced/one.rb +0 -26
  1023. data/lib/mongoid/relations/builders.rb +0 -106
  1024. data/lib/mongoid/relations/cascading/delete.rb +0 -44
  1025. data/lib/mongoid/relations/cascading/destroy.rb +0 -43
  1026. data/lib/mongoid/relations/cascading/nullify.rb +0 -35
  1027. data/lib/mongoid/relations/cascading/restrict.rb +0 -39
  1028. data/lib/mongoid/relations/cascading.rb +0 -56
  1029. data/lib/mongoid/relations/constraint.rb +0 -55
  1030. data/lib/mongoid/relations/conversions.rb +0 -34
  1031. data/lib/mongoid/relations/counter_cache.rb +0 -160
  1032. data/lib/mongoid/relations/cyclic.rb +0 -107
  1033. data/lib/mongoid/relations/eager/base.rb +0 -153
  1034. data/lib/mongoid/relations/eager/belongs_to.rb +0 -31
  1035. data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +0 -47
  1036. data/lib/mongoid/relations/eager/has_many.rb +0 -38
  1037. data/lib/mongoid/relations/eager/has_one.rb +0 -30
  1038. data/lib/mongoid/relations/eager.rb +0 -36
  1039. data/lib/mongoid/relations/embedded/batchable.rb +0 -384
  1040. data/lib/mongoid/relations/embedded/in.rb +0 -241
  1041. data/lib/mongoid/relations/embedded/many.rb +0 -683
  1042. data/lib/mongoid/relations/embedded/one.rb +0 -235
  1043. data/lib/mongoid/relations/macros.rb +0 -367
  1044. data/lib/mongoid/relations/many.rb +0 -242
  1045. data/lib/mongoid/relations/marshalable.rb +0 -32
  1046. data/lib/mongoid/relations/metadata.rb +0 -1179
  1047. data/lib/mongoid/relations/nested_builder.rb +0 -74
  1048. data/lib/mongoid/relations/one.rb +0 -60
  1049. data/lib/mongoid/relations/options.rb +0 -49
  1050. data/lib/mongoid/relations/polymorphic.rb +0 -39
  1051. data/lib/mongoid/relations/proxy.rb +0 -215
  1052. data/lib/mongoid/relations/referenced/in.rb +0 -304
  1053. data/lib/mongoid/relations/referenced/many.rb +0 -812
  1054. data/lib/mongoid/relations/referenced/many_to_many.rb +0 -479
  1055. data/lib/mongoid/relations/referenced/one.rb +0 -290
  1056. data/lib/mongoid/relations/reflections.rb +0 -64
  1057. data/lib/mongoid/relations/synchronization.rb +0 -169
  1058. data/lib/mongoid/relations/targets/enumerable.rb +0 -493
  1059. data/lib/mongoid/relations/targets.rb +0 -2
  1060. data/lib/mongoid/relations/touchable.rb +0 -97
  1061. data/lib/mongoid/relations.rb +0 -148
  1062. data/spec/app/models/account.rb +0 -36
  1063. data/spec/app/models/acolyte.rb +0 -17
  1064. data/spec/app/models/actor.rb +0 -18
  1065. data/spec/app/models/actress.rb +0 -2
  1066. data/spec/app/models/address.rb +0 -79
  1067. data/spec/app/models/address_component.rb +0 -5
  1068. data/spec/app/models/address_number.rb +0 -6
  1069. data/spec/app/models/agency.rb +0 -5
  1070. data/spec/app/models/agent.rb +0 -16
  1071. data/spec/app/models/album.rb +0 -18
  1072. data/spec/app/models/alert.rb +0 -7
  1073. data/spec/app/models/animal.rb +0 -25
  1074. data/spec/app/models/answer.rb +0 -6
  1075. data/spec/app/models/appointment.rb +0 -7
  1076. data/spec/app/models/array_field.rb +0 -7
  1077. data/spec/app/models/article.rb +0 -12
  1078. data/spec/app/models/artist.rb +0 -87
  1079. data/spec/app/models/artwork.rb +0 -4
  1080. data/spec/app/models/audio.rb +0 -5
  1081. data/spec/app/models/augmentation.rb +0 -11
  1082. data/spec/app/models/author.rb +0 -6
  1083. data/spec/app/models/baby.rb +0 -4
  1084. data/spec/app/models/band.rb +0 -31
  1085. data/spec/app/models/bar.rb +0 -10
  1086. data/spec/app/models/basic.rb +0 -6
  1087. data/spec/app/models/bed.rb +0 -1
  1088. data/spec/app/models/big_palette.rb +0 -2
  1089. data/spec/app/models/birthday.rb +0 -13
  1090. data/spec/app/models/bomb.rb +0 -4
  1091. data/spec/app/models/book.rb +0 -16
  1092. data/spec/app/models/breed.rb +0 -4
  1093. data/spec/app/models/browser.rb +0 -6
  1094. data/spec/app/models/building.rb +0 -6
  1095. data/spec/app/models/building_address.rb +0 -7
  1096. data/spec/app/models/bus.rb +0 -7
  1097. data/spec/app/models/business.rb +0 -5
  1098. data/spec/app/models/callback_test.rb +0 -9
  1099. data/spec/app/models/canvas.rb +0 -25
  1100. data/spec/app/models/car.rb +0 -1
  1101. data/spec/app/models/cat.rb +0 -8
  1102. data/spec/app/models/category.rb +0 -8
  1103. data/spec/app/models/child.rb +0 -4
  1104. data/spec/app/models/child_doc.rb +0 -22
  1105. data/spec/app/models/church.rb +0 -6
  1106. data/spec/app/models/circle.rb +0 -3
  1107. data/spec/app/models/circuit.rb +0 -4
  1108. data/spec/app/models/circus.rb +0 -7
  1109. data/spec/app/models/code.rb +0 -11
  1110. data/spec/app/models/comment.rb +0 -16
  1111. data/spec/app/models/company.rb +0 -5
  1112. data/spec/app/models/consumption_period.rb +0 -7
  1113. data/spec/app/models/contextable_item.rb +0 -5
  1114. data/spec/app/models/contractor.rb +0 -5
  1115. data/spec/app/models/cookie.rb +0 -6
  1116. data/spec/app/models/country_code.rb +0 -8
  1117. data/spec/app/models/courier_job.rb +0 -4
  1118. data/spec/app/models/definition.rb +0 -9
  1119. data/spec/app/models/description.rb +0 -11
  1120. data/spec/app/models/dictionary.rb +0 -10
  1121. data/spec/app/models/division.rb +0 -10
  1122. data/spec/app/models/doctor.rb +0 -12
  1123. data/spec/app/models/dog.rb +0 -7
  1124. data/spec/app/models/dokument.rb +0 -6
  1125. data/spec/app/models/draft.rb +0 -9
  1126. data/spec/app/models/dragon.rb +0 -4
  1127. data/spec/app/models/driver.rb +0 -7
  1128. data/spec/app/models/drug.rb +0 -6
  1129. data/spec/app/models/dungeon.rb +0 -4
  1130. data/spec/app/models/edit.rb +0 -5
  1131. data/spec/app/models/email.rb +0 -6
  1132. data/spec/app/models/employer.rb +0 -5
  1133. data/spec/app/models/entry.rb +0 -6
  1134. data/spec/app/models/eraser.rb +0 -1
  1135. data/spec/app/models/even.rb +0 -7
  1136. data/spec/app/models/event.rb +0 -22
  1137. data/spec/app/models/exhibition.rb +0 -4
  1138. data/spec/app/models/exhibitor.rb +0 -6
  1139. data/spec/app/models/explosion.rb +0 -4
  1140. data/spec/app/models/eye.rb +0 -9
  1141. data/spec/app/models/eye_bowl.rb +0 -9
  1142. data/spec/app/models/face.rb +0 -8
  1143. data/spec/app/models/favorite.rb +0 -6
  1144. data/spec/app/models/filesystem.rb +0 -5
  1145. data/spec/app/models/fire_hydrant.rb +0 -6
  1146. data/spec/app/models/firefox.rb +0 -4
  1147. data/spec/app/models/fish.rb +0 -7
  1148. data/spec/app/models/folder.rb +0 -7
  1149. data/spec/app/models/folder_item.rb +0 -9
  1150. data/spec/app/models/fruits.rb +0 -34
  1151. data/spec/app/models/game.rb +0 -19
  1152. data/spec/app/models/ghost.rb +0 -7
  1153. data/spec/app/models/home.rb +0 -4
  1154. data/spec/app/models/house.rb +0 -6
  1155. data/spec/app/models/html_writer.rb +0 -3
  1156. data/spec/app/models/id_key.rb +0 -6
  1157. data/spec/app/models/image.rb +0 -22
  1158. data/spec/app/models/implant.rb +0 -16
  1159. data/spec/app/models/item.rb +0 -8
  1160. data/spec/app/models/jar.rb +0 -7
  1161. data/spec/app/models/kaleidoscope.rb +0 -6
  1162. data/spec/app/models/kangaroo.rb +0 -4
  1163. data/spec/app/models/label.rb +0 -47
  1164. data/spec/app/models/language.rb +0 -5
  1165. data/spec/app/models/lat_lng.rb +0 -15
  1166. data/spec/app/models/league.rb +0 -11
  1167. data/spec/app/models/learner.rb +0 -2
  1168. data/spec/app/models/line_item.rb +0 -6
  1169. data/spec/app/models/location.rb +0 -8
  1170. data/spec/app/models/login.rb +0 -8
  1171. data/spec/app/models/manufacturer.rb +0 -7
  1172. data/spec/app/models/meat.rb +0 -4
  1173. data/spec/app/models/membership.rb +0 -4
  1174. data/spec/app/models/message.rb +0 -11
  1175. data/spec/app/models/mixed_drink.rb +0 -4
  1176. data/spec/app/models/movie.rb +0 -13
  1177. data/spec/app/models/my_hash.rb +0 -2
  1178. data/spec/app/models/name.rb +0 -24
  1179. data/spec/app/models/node.rb +0 -5
  1180. data/spec/app/models/note.rb +0 -17
  1181. data/spec/app/models/odd.rb +0 -7
  1182. data/spec/app/models/ordered_post.rb +0 -11
  1183. data/spec/app/models/ordered_preference.rb +0 -6
  1184. data/spec/app/models/oscar.rb +0 -14
  1185. data/spec/app/models/override.rb +0 -16
  1186. data/spec/app/models/ownable.rb +0 -6
  1187. data/spec/app/models/owner.rb +0 -6
  1188. data/spec/app/models/pack.rb +0 -3
  1189. data/spec/app/models/page.rb +0 -16
  1190. data/spec/app/models/page_question.rb +0 -4
  1191. data/spec/app/models/palette.rb +0 -7
  1192. data/spec/app/models/parent.rb +0 -5
  1193. data/spec/app/models/parent_doc.rb +0 -6
  1194. data/spec/app/models/passport.rb +0 -5
  1195. data/spec/app/models/patient.rb +0 -9
  1196. data/spec/app/models/pdf_writer.rb +0 -3
  1197. data/spec/app/models/pencil.rb +0 -1
  1198. data/spec/app/models/person.rb +0 -207
  1199. data/spec/app/models/pet.rb +0 -23
  1200. data/spec/app/models/pet_owner.rb +0 -6
  1201. data/spec/app/models/phone.rb +0 -9
  1202. data/spec/app/models/pizza.rb +0 -7
  1203. data/spec/app/models/player.rb +0 -35
  1204. data/spec/app/models/post.rb +0 -50
  1205. data/spec/app/models/post_genre.rb +0 -6
  1206. data/spec/app/models/powerup.rb +0 -11
  1207. data/spec/app/models/preference.rb +0 -9
  1208. data/spec/app/models/princess.rb +0 -10
  1209. data/spec/app/models/product.rb +0 -17
  1210. data/spec/app/models/profile.rb +0 -5
  1211. data/spec/app/models/pronunciation.rb +0 -5
  1212. data/spec/app/models/pub.rb +0 -6
  1213. data/spec/app/models/purchase.rb +0 -4
  1214. data/spec/app/models/question.rb +0 -8
  1215. data/spec/app/models/quiz.rb +0 -7
  1216. data/spec/app/models/rating.rb +0 -8
  1217. data/spec/app/models/record.rb +0 -52
  1218. data/spec/app/models/registry.rb +0 -4
  1219. data/spec/app/models/role.rb +0 -7
  1220. data/spec/app/models/root_category.rb +0 -4
  1221. data/spec/app/models/sandwich.rb +0 -9
  1222. data/spec/app/models/scheduler.rb +0 -7
  1223. data/spec/app/models/seo.rb +0 -7
  1224. data/spec/app/models/series.rb +0 -4
  1225. data/spec/app/models/server.rb +0 -13
  1226. data/spec/app/models/service.rb +0 -22
  1227. data/spec/app/models/shape.rb +0 -12
  1228. data/spec/app/models/shelf.rb +0 -5
  1229. data/spec/app/models/shipment_address.rb +0 -2
  1230. data/spec/app/models/shipping_container.rb +0 -5
  1231. data/spec/app/models/shipping_pack.rb +0 -3
  1232. data/spec/app/models/shop.rb +0 -6
  1233. data/spec/app/models/short_agent.rb +0 -4
  1234. data/spec/app/models/short_quiz.rb +0 -5
  1235. data/spec/app/models/simple.rb +0 -5
  1236. data/spec/app/models/slave.rb +0 -6
  1237. data/spec/app/models/song.rb +0 -8
  1238. data/spec/app/models/sound.rb +0 -5
  1239. data/spec/app/models/square.rb +0 -4
  1240. data/spec/app/models/staff.rb +0 -7
  1241. data/spec/app/models/store_as_dup_test1.rb +0 -5
  1242. data/spec/app/models/store_as_dup_test2.rb +0 -5
  1243. data/spec/app/models/strategy.rb +0 -3
  1244. data/spec/app/models/sub_item.rb +0 -3
  1245. data/spec/app/models/subscription.rb +0 -5
  1246. data/spec/app/models/survey.rb +0 -5
  1247. data/spec/app/models/symptom.rb +0 -6
  1248. data/spec/app/models/tag.rb +0 -8
  1249. data/spec/app/models/target.rb +0 -5
  1250. data/spec/app/models/template.rb +0 -5
  1251. data/spec/app/models/thing.rb +0 -9
  1252. data/spec/app/models/title.rb +0 -3
  1253. data/spec/app/models/tool.rb +0 -8
  1254. data/spec/app/models/topping.rb +0 -5
  1255. data/spec/app/models/track.rb +0 -38
  1256. data/spec/app/models/translation.rb +0 -5
  1257. data/spec/app/models/tree.rb +0 -9
  1258. data/spec/app/models/truck.rb +0 -3
  1259. data/spec/app/models/user.rb +0 -21
  1260. data/spec/app/models/user_account.rb +0 -10
  1261. data/spec/app/models/validation_callback.rb +0 -10
  1262. data/spec/app/models/vehicle.rb +0 -11
  1263. data/spec/app/models/version.rb +0 -5
  1264. data/spec/app/models/vet_visit.rb +0 -5
  1265. data/spec/app/models/video.rb +0 -13
  1266. data/spec/app/models/video_game.rb +0 -1
  1267. data/spec/app/models/weapon.rb +0 -11
  1268. data/spec/app/models/wiki_page.rb +0 -14
  1269. data/spec/app/models/word.rb +0 -15
  1270. data/spec/app/models/word_origin.rb +0 -11
  1271. data/spec/app/models/writer.rb +0 -11
  1272. data/spec/mongoid/criteria/queryable/forwardable_spec.rb +0 -87
  1273. data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +0 -184
  1274. data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +0 -201
  1275. data/spec/mongoid/matchable/all_spec.rb +0 -31
  1276. data/spec/mongoid/matchable/and_spec.rb +0 -187
  1277. data/spec/mongoid/matchable/default_spec.rb +0 -130
  1278. data/spec/mongoid/matchable/elem_match_spec.rb +0 -86
  1279. data/spec/mongoid/matchable/exists_spec.rb +0 -57
  1280. data/spec/mongoid/matchable/gt_spec.rb +0 -86
  1281. data/spec/mongoid/matchable/gte_spec.rb +0 -84
  1282. data/spec/mongoid/matchable/in_spec.rb +0 -49
  1283. data/spec/mongoid/matchable/lt_spec.rb +0 -85
  1284. data/spec/mongoid/matchable/lte_spec.rb +0 -85
  1285. data/spec/mongoid/matchable/ne_spec.rb +0 -46
  1286. data/spec/mongoid/matchable/nin_spec.rb +0 -48
  1287. data/spec/mongoid/matchable/nor_spec.rb +0 -209
  1288. data/spec/mongoid/matchable/or_spec.rb +0 -131
  1289. data/spec/mongoid/matchable/regexp_spec.rb +0 -59
  1290. data/spec/mongoid/matchable/size_spec.rb +0 -25
  1291. data/spec/mongoid/matchable_spec.rb +0 -853
  1292. data/spec/mongoid/relations/accessors_spec.rb +0 -821
  1293. data/spec/mongoid/relations/auto_save_spec.rb +0 -314
  1294. data/spec/mongoid/relations/bindings/embedded/in_spec.rb +0 -171
  1295. data/spec/mongoid/relations/bindings/embedded/many_spec.rb +0 -54
  1296. data/spec/mongoid/relations/bindings/embedded/one_spec.rb +0 -77
  1297. data/spec/mongoid/relations/bindings/referenced/in_spec.rb +0 -241
  1298. data/spec/mongoid/relations/bindings/referenced/many_spec.rb +0 -153
  1299. data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +0 -178
  1300. data/spec/mongoid/relations/bindings/referenced/one_spec.rb +0 -131
  1301. data/spec/mongoid/relations/builders/embedded/in_spec.rb +0 -34
  1302. data/spec/mongoid/relations/builders/embedded/many_spec.rb +0 -132
  1303. data/spec/mongoid/relations/builders/embedded/one_spec.rb +0 -99
  1304. data/spec/mongoid/relations/builders/nested_attributes/many_spec.rb +0 -233
  1305. data/spec/mongoid/relations/builders/nested_attributes/one_spec.rb +0 -250
  1306. data/spec/mongoid/relations/builders/referenced/in_spec.rb +0 -230
  1307. data/spec/mongoid/relations/builders/referenced/many_spec.rb +0 -137
  1308. data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +0 -178
  1309. data/spec/mongoid/relations/builders/referenced/one_spec.rb +0 -111
  1310. data/spec/mongoid/relations/builders_spec.rb +0 -253
  1311. data/spec/mongoid/relations/cascading/delete_spec.rb +0 -101
  1312. data/spec/mongoid/relations/cascading/destroy_spec.rb +0 -47
  1313. data/spec/mongoid/relations/cascading/nullify_spec.rb +0 -32
  1314. data/spec/mongoid/relations/cascading/restrict_spec.rb +0 -68
  1315. data/spec/mongoid/relations/cascading_spec.rb +0 -355
  1316. data/spec/mongoid/relations/constraint_spec.rb +0 -75
  1317. data/spec/mongoid/relations/conversions_spec.rb +0 -128
  1318. data/spec/mongoid/relations/counter_cache_spec.rb +0 -450
  1319. data/spec/mongoid/relations/cyclic_spec.rb +0 -178
  1320. data/spec/mongoid/relations/eager/belongs_to_spec.rb +0 -163
  1321. data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +0 -133
  1322. data/spec/mongoid/relations/eager/has_many_spec.rb +0 -244
  1323. data/spec/mongoid/relations/eager/has_one_spec.rb +0 -163
  1324. data/spec/mongoid/relations/eager_spec.rb +0 -279
  1325. data/spec/mongoid/relations/embedded/dirty_spec.rb +0 -65
  1326. data/spec/mongoid/relations/embedded/in_spec.rb +0 -579
  1327. data/spec/mongoid/relations/embedded/many_spec.rb +0 -4412
  1328. data/spec/mongoid/relations/embedded/one_spec.rb +0 -1068
  1329. data/spec/mongoid/relations/macros_spec.rb +0 -1039
  1330. data/spec/mongoid/relations/metadata_spec.rb +0 -1985
  1331. data/spec/mongoid/relations/options_spec.rb +0 -35
  1332. data/spec/mongoid/relations/polymorphic_spec.rb +0 -128
  1333. data/spec/mongoid/relations/referenced/in_spec.rb +0 -1366
  1334. data/spec/mongoid/relations/referenced/many_spec.rb +0 -3816
  1335. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +0 -3577
  1336. data/spec/mongoid/relations/referenced/one_spec.rb +0 -1240
  1337. data/spec/mongoid/relations/reflections_spec.rb +0 -101
  1338. data/spec/mongoid/relations/synchronization_spec.rb +0 -495
  1339. data/spec/mongoid/relations/targets/enumerable_spec.rb +0 -1825
  1340. data/spec/mongoid/relations/touchable_spec.rb +0 -402
  1341. data/spec/mongoid/relations_spec.rb +0 -189
@@ -0,0 +1,24 @@
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::HasMany::Proxy do
8
+ context 'with primary_key and foreign_key given' do
9
+ let(:company) { HmmCompany.create!(p: 123) }
10
+ let(:criteria) { company.emails }
11
+
12
+ it 'generates correct query' do
13
+ expect(criteria.selector).to eq('f' => 123)
14
+ end
15
+
16
+ context 'unscoped' do
17
+ let(:criteria) { company.emails.unscoped }
18
+
19
+ it 'generates correct query' do
20
+ expect(criteria.selector).to eq('f' => 123)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,4029 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ require "spec_helper"
5
+
6
+ describe Mongoid::Association::Referenced::HasMany::Proxy do
7
+
8
+ before :all do
9
+ Mongoid.raise_not_found_error = true
10
+
11
+ Drug.belongs_to :person, primary_key: :username
12
+ Person.has_many :drugs, validate: false, primary_key: :username
13
+ end
14
+
15
+ after :all do
16
+ Drug.belongs_to :person, counter_cache: true
17
+ Person.has_many :drugs, validate: false
18
+ end
19
+
20
+ [ :<<, :push ].each do |method|
21
+
22
+ describe "##{method}" do
23
+
24
+ context "when providing the base class in child contructor" do
25
+
26
+ let(:person) do
27
+ Person.create
28
+ end
29
+
30
+ let!(:post) do
31
+ person.posts.send(method, Post.new(person: person))
32
+ end
33
+
34
+ it "only adds the association once" do
35
+ expect(person.posts.size).to eq(1)
36
+ end
37
+
38
+ it "only persists the association once" do
39
+ expect(person.reload.posts.size).to eq(1)
40
+ end
41
+ end
42
+
43
+ context "when the associations are not polymorphic" do
44
+
45
+ context "when the parent is a new record" do
46
+
47
+ let(:person) do
48
+ Person.new
49
+ end
50
+
51
+ context "when the child is new" do
52
+
53
+ let(:post) do
54
+ Post.new
55
+ end
56
+
57
+ let!(:added) do
58
+ person.posts.send(method, post)
59
+ end
60
+
61
+ it "sets the foreign key on the association" do
62
+ expect(post.person_id).to eq(person.id)
63
+ end
64
+
65
+ it "sets the base on the inverse association" do
66
+ expect(post.person).to eq(person)
67
+ end
68
+
69
+ it "sets the same instance on the inverse association" do
70
+ expect(post.person).to eql(person)
71
+ end
72
+
73
+ it "does not save the target" do
74
+ expect(post).to be_new_record
75
+ end
76
+
77
+ it "adds the document to the target" do
78
+ expect(person.posts.size).to eq(1)
79
+ end
80
+
81
+ it "returns the association" do
82
+ expect(added).to eq(person.posts)
83
+ end
84
+ end
85
+
86
+ context "when the child is persisted" do
87
+
88
+ let(:post) do
89
+ Post.create
90
+ end
91
+
92
+ before do
93
+ person.posts.send(method, post)
94
+ end
95
+
96
+ it "sets the foreign key on the association" do
97
+ expect(post.person_id).to eq(person.id)
98
+ end
99
+
100
+ it "sets the base on the inverse association" do
101
+ expect(post.person).to eq(person)
102
+ end
103
+
104
+ it "sets the same instance on the inverse association" do
105
+ expect(post.person).to eql(person)
106
+ end
107
+
108
+ it "does not save the parent" do
109
+ expect(person).to be_new_record
110
+ end
111
+
112
+ it "adds the document to the target" do
113
+ expect(person.posts.size).to eq(1)
114
+ end
115
+
116
+ context "when subsequently saving the parent" do
117
+
118
+ before do
119
+ person.save
120
+ post.save
121
+ end
122
+
123
+ it "returns the correct count of the association" do
124
+ expect(person.posts.count).to eq(1)
125
+ end
126
+ end
127
+ end
128
+ end
129
+
130
+ context "when appending in a parent create block" do
131
+
132
+ let!(:post) do
133
+ Post.create(title: "testing")
134
+ end
135
+
136
+ let!(:person) do
137
+ Person.create do |doc|
138
+ doc.posts << post
139
+ end
140
+ end
141
+
142
+ it "adds the documents to the association" do
143
+ expect(person.posts).to eq([ post ])
144
+ end
145
+
146
+ it "sets the foreign key on the inverse association" do
147
+ expect(post.person_id).to eq(person.id)
148
+ end
149
+
150
+ it "saves the target" do
151
+ expect(post).to be_persisted
152
+ end
153
+
154
+ it "adds the correct number of documents" do
155
+ expect(person.posts.size).to eq(1)
156
+ end
157
+
158
+ it "persists the link" do
159
+ expect(person.reload.posts).to eq([ post ])
160
+ end
161
+ end
162
+
163
+ context "when the parent is not a new record" do
164
+
165
+ let(:person) do
166
+ Person.create
167
+ end
168
+
169
+ let(:post) do
170
+ Post.new
171
+ end
172
+
173
+ before do
174
+ person.posts.send(method, post)
175
+ end
176
+
177
+ it "sets the foreign key on the association" do
178
+ expect(post.person_id).to eq(person.id)
179
+ end
180
+
181
+ it "sets the base on the inverse association" do
182
+ expect(post.person).to eq(person)
183
+ end
184
+
185
+ it "sets the same instance on the inverse association" do
186
+ expect(post.person).to eql(person)
187
+ end
188
+
189
+ it "saves the target" do
190
+ expect(post).to be_persisted
191
+ end
192
+
193
+ it "adds the document to the target" do
194
+ expect(person.posts.count).to eq(1)
195
+ end
196
+
197
+ it "increments the counter cache" do
198
+ expect(person[:posts_count]).to eq(1)
199
+ expect(person.posts_count).to eq(1)
200
+ end
201
+
202
+ it "doesnt change the list of changes" do
203
+ expect(person.changed).to eq([])
204
+ end
205
+
206
+ context "when the related item has embedded associations" do
207
+
208
+ let!(:user) do
209
+ User.create
210
+ end
211
+
212
+ before do
213
+ p = Post.create(roles: [ Role.create ])
214
+ user.posts = [ p ]
215
+ user.save
216
+ end
217
+
218
+ it "add the document to the target" do
219
+ expect(user.posts.size).to eq(1)
220
+ expect(user.posts.first.roles.size).to eq(1)
221
+ end
222
+ end
223
+
224
+ context "when saving another post" do
225
+
226
+ before do
227
+ person.posts.send(method, Post.new)
228
+ end
229
+
230
+ it "increments the counter cache" do
231
+ expect(person.posts_count).to eq(2)
232
+ end
233
+ end
234
+
235
+ context "when documents already exist on the association" do
236
+
237
+ let(:post_two) do
238
+ Post.new(title: "Test")
239
+ end
240
+
241
+ before do
242
+ person.posts.send(method, post_two)
243
+ end
244
+
245
+ it "sets the foreign key on the association" do
246
+ expect(post_two.person_id).to eq(person.id)
247
+ end
248
+
249
+ it "sets the base on the inverse association" do
250
+ expect(post_two.person).to eq(person)
251
+ end
252
+
253
+ it "sets the same instance on the inverse association" do
254
+ expect(post_two.person).to eql(person)
255
+ end
256
+
257
+ it "saves the target" do
258
+ expect(post_two).to be_persisted
259
+ end
260
+
261
+ it "adds the document to the target" do
262
+ expect(person.posts.count).to eq(2)
263
+ end
264
+
265
+ it "increments the counter cache" do
266
+ expect(person.reload.posts_count).to eq(2)
267
+ end
268
+
269
+ it "contains the initial document in the target" do
270
+ expect(person.posts).to include(post)
271
+ end
272
+
273
+ it "contains the added document in the target" do
274
+ expect(person.posts).to include(post_two)
275
+ end
276
+ end
277
+ end
278
+ end
279
+
280
+ context "when.adding to the association" do
281
+
282
+ let(:person) do
283
+ Person.create
284
+ end
285
+
286
+ context "when the operation succeeds" do
287
+
288
+ let(:post) do
289
+ Post.new
290
+ end
291
+
292
+ before do
293
+ person.posts.send(method, post)
294
+ end
295
+
296
+ it "adds the document to the association" do
297
+ expect(person.posts).to eq([ post ])
298
+ end
299
+ end
300
+
301
+ context "when the operation fails" do
302
+
303
+ let!(:existing) do
304
+ Post.create
305
+ end
306
+
307
+ let(:post) do
308
+ Post.new do |doc|
309
+ doc._id = existing.id
310
+ end
311
+ end
312
+
313
+ it "raises an error" do
314
+ expect {
315
+ person.posts.send(method, post)
316
+ }.to raise_error(Mongo::Error::OperationFailure)
317
+ end
318
+ end
319
+ end
320
+
321
+ context "when the associations are polymorphic" do
322
+
323
+ context "when the parent is a new record" do
324
+
325
+ let(:movie) do
326
+ Movie.new
327
+ end
328
+
329
+ let(:rating) do
330
+ Rating.new
331
+ end
332
+
333
+ before do
334
+ movie.ratings.send(method, rating)
335
+ end
336
+
337
+ it "sets the foreign key on the association" do
338
+ expect(rating.ratable_id).to eq(movie.id)
339
+ end
340
+
341
+ it "sets the base on the inverse association" do
342
+ expect(rating.ratable).to eq(movie)
343
+ end
344
+
345
+ it "does not save the target" do
346
+ expect(rating).to be_new_record
347
+ end
348
+
349
+ it "adds the document to the target" do
350
+ expect(movie.ratings.size).to eq(1)
351
+ end
352
+ end
353
+
354
+ context "when the parent is not a new record" do
355
+
356
+ let(:movie) do
357
+ Movie.create
358
+ end
359
+
360
+ let(:rating) do
361
+ Rating.new
362
+ end
363
+
364
+ before do
365
+ movie.ratings.send(method, rating)
366
+ end
367
+
368
+ it "sets the foreign key on the association" do
369
+ expect(rating.ratable_id).to eq(movie.id)
370
+ end
371
+
372
+ it "sets the base on the inverse association" do
373
+ expect(rating.ratable).to eq(movie)
374
+ end
375
+
376
+ it "saves the target" do
377
+ expect(rating).to be_persisted
378
+ end
379
+
380
+ it "adds the document to the target" do
381
+ expect(movie.ratings.count).to eq(1)
382
+ end
383
+ end
384
+ end
385
+ end
386
+ end
387
+
388
+ describe "#=" do
389
+
390
+ context "when the association is not polymorphic" do
391
+
392
+ context "when the parent is a new record" do
393
+
394
+ let(:person) do
395
+ Person.new
396
+ end
397
+
398
+ let(:post) do
399
+ Post.new
400
+ end
401
+
402
+ before do
403
+ person.posts = [ post ]
404
+ end
405
+
406
+ it "sets the target of the association" do
407
+ expect(person.posts._target).to eq([ post ])
408
+ end
409
+
410
+ it "sets the foreign key on the association" do
411
+ expect(post.person_id).to eq(person.id)
412
+ end
413
+
414
+ it "sets the base on the inverse association" do
415
+ expect(post.person).to eq(person)
416
+ end
417
+
418
+ it "does not save the target" do
419
+ expect(post).to_not be_persisted
420
+ end
421
+ end
422
+
423
+ context "when the parent is not a new record" do
424
+
425
+ let(:person) do
426
+ Person.create
427
+ end
428
+
429
+ let(:post) do
430
+ Post.new
431
+ end
432
+
433
+ before do
434
+ person.posts = [ post ]
435
+ end
436
+
437
+ it "sets the target of the association" do
438
+ expect(person.posts._target).to eq([ post ])
439
+ end
440
+
441
+ it "sets the foreign key of the association" do
442
+ expect(post.person_id).to eq(person.id)
443
+ end
444
+
445
+ it "sets the base on the inverse association" do
446
+ expect(post.person).to eq(person)
447
+ end
448
+
449
+ it "saves the target" do
450
+ expect(post).to be_persisted
451
+ end
452
+
453
+ context "when replacing the association with the same documents" do
454
+
455
+ context "when using the same in memory instance" do
456
+
457
+ before do
458
+ person.posts = [ post ]
459
+ end
460
+
461
+ it "keeps the association intact" do
462
+ expect(person.posts).to eq([ post ])
463
+ end
464
+
465
+ it "does not delete the association" do
466
+ expect(person.reload.posts).to eq([ post ])
467
+ end
468
+ end
469
+
470
+ context "when using a new instance" do
471
+
472
+ let(:from_db) do
473
+ Person.find(person.id)
474
+ end
475
+
476
+ before do
477
+ from_db.posts = [ post ]
478
+ end
479
+
480
+ it "keeps the association intact" do
481
+ expect(from_db.posts).to eq([ post ])
482
+ end
483
+
484
+ it "does not delete the association" do
485
+ expect(from_db.reload.posts).to eq([ post ])
486
+ end
487
+ end
488
+ end
489
+
490
+ context "when replacing the with a combination of old and new docs" do
491
+
492
+ let(:new_post) do
493
+ Post.create(title: "new post")
494
+ end
495
+
496
+ context "when using the same in memory instance" do
497
+
498
+ before do
499
+ person.posts = [ post, new_post ]
500
+ end
501
+
502
+ it "keeps the association intact" do
503
+ expect(person.posts.size).to eq(2)
504
+ end
505
+
506
+ it "keeps the first post" do
507
+ expect(person.posts).to include(post)
508
+ end
509
+
510
+ it "keeps the second post" do
511
+ expect(person.posts).to include(new_post)
512
+ end
513
+
514
+ it "does not delete the association" do
515
+ expect(person.reload.posts).to eq([ post, new_post ])
516
+ end
517
+ end
518
+
519
+ context "when using a new instance" do
520
+
521
+ let(:from_db) do
522
+ Person.find(person.id)
523
+ end
524
+
525
+ before do
526
+ from_db.posts = [ post, new_post ]
527
+ end
528
+
529
+ it "keeps the association intact" do
530
+ expect(from_db.posts).to eq([ post, new_post ])
531
+ end
532
+
533
+ it "does not delete the association" do
534
+ expect(from_db.reload.posts).to eq([ post, new_post ])
535
+ end
536
+ end
537
+ end
538
+
539
+ context "when replacing the with a combination of only new docs" do
540
+
541
+ let(:new_post) do
542
+ Post.create(title: "new post")
543
+ end
544
+
545
+ context "when using the same in memory instance" do
546
+
547
+ before do
548
+ person.posts = [ new_post ]
549
+ end
550
+
551
+ it "keeps the association intact" do
552
+ expect(person.posts).to eq([ new_post ])
553
+ end
554
+
555
+ it "does not delete the association" do
556
+ expect(person.reload.posts).to eq([ new_post ])
557
+ end
558
+ end
559
+
560
+ context "when using a new instance" do
561
+
562
+ let(:from_db) do
563
+ Person.find(person.id)
564
+ end
565
+
566
+ before do
567
+ from_db.posts = [ new_post ]
568
+ end
569
+
570
+ it "keeps the association intact" do
571
+ expect(from_db.posts).to eq([ new_post ])
572
+ end
573
+
574
+ it "does not delete the association" do
575
+ expect(from_db.reload.posts).to eq([ new_post ])
576
+ end
577
+ end
578
+ end
579
+ end
580
+ end
581
+
582
+ context "when the association is polymorphic" do
583
+
584
+ context "when the parent is a new record" do
585
+
586
+ let(:movie) do
587
+ Movie.new
588
+ end
589
+
590
+ let(:rating) do
591
+ Rating.new
592
+ end
593
+
594
+ before do
595
+ movie.ratings = [ rating ]
596
+ end
597
+
598
+ it "sets the target of the association" do
599
+ expect(movie.ratings._target).to eq([ rating ])
600
+ end
601
+
602
+ it "sets the foreign key on the association" do
603
+ expect(rating.ratable_id).to eq(movie.id)
604
+ end
605
+
606
+ it "sets the base on the inverse association" do
607
+ expect(rating.ratable).to eq(movie)
608
+ end
609
+
610
+ it "does not save the target" do
611
+ expect(rating).to_not be_persisted
612
+ end
613
+ end
614
+
615
+ context "when the parent is not a new record" do
616
+
617
+ let(:movie) do
618
+ Movie.create
619
+ end
620
+
621
+ let(:rating) do
622
+ Rating.new
623
+ end
624
+
625
+ before do
626
+ movie.ratings = [ rating ]
627
+ end
628
+
629
+ it "sets the target of the association" do
630
+ expect(movie.ratings._target).to eq([ rating ])
631
+ end
632
+
633
+ it "sets the foreign key of the association" do
634
+ expect(rating.ratable_id).to eq(movie.id)
635
+ end
636
+
637
+ it "sets the base on the inverse association" do
638
+ expect(rating.ratable).to eq(movie)
639
+ end
640
+
641
+ it "saves the target" do
642
+ expect(rating).to be_persisted
643
+ end
644
+ end
645
+ end
646
+ end
647
+
648
+ describe "#= []" do
649
+
650
+ context "when the parent is persisted" do
651
+
652
+ let(:posts) do
653
+ [ Post.create(title: "1"), Post.create(title: "2") ]
654
+ end
655
+
656
+ let(:person) do
657
+ Person.create(posts: posts)
658
+ end
659
+
660
+ context "when the parent has multiple children" do
661
+
662
+ before do
663
+ person.posts = []
664
+ end
665
+
666
+ it "removes all the children" do
667
+ expect(person.posts).to be_empty
668
+ end
669
+
670
+ it "persists the changes" do
671
+ expect(person.posts(true)).to be_empty
672
+ end
673
+ end
674
+ end
675
+ end
676
+
677
+ describe "#= nil" do
678
+
679
+ context "when the association is not polymorphic" do
680
+
681
+ context "when the parent is a new record" do
682
+
683
+ let(:person) do
684
+ Person.new
685
+ end
686
+
687
+ let(:post) do
688
+ Post.new
689
+ end
690
+
691
+ before do
692
+ person.posts = [ post ]
693
+ person.posts = nil
694
+ end
695
+
696
+ it "sets the association to an empty array" do
697
+ expect(person.posts).to be_empty
698
+ end
699
+
700
+ it "removed the inverse association" do
701
+ expect(post.person).to be_nil
702
+ end
703
+
704
+ it "removes the foreign key value" do
705
+ expect(post.person_id).to be_nil
706
+ end
707
+ end
708
+
709
+ context "when the parent is not a new record" do
710
+
711
+ let(:person) do
712
+ Person.create
713
+ end
714
+
715
+ context "when dependent is destructive" do
716
+
717
+ let(:post) do
718
+ Post.new
719
+ end
720
+
721
+ before do
722
+ person.posts = [ post ]
723
+ person.posts = nil
724
+ end
725
+
726
+ it "sets the association to empty" do
727
+ expect(person.posts).to be_empty
728
+ end
729
+
730
+ it "removed the inverse association" do
731
+ expect(post.person).to be_nil
732
+ end
733
+
734
+ it "removes the foreign key value" do
735
+ expect(post.person_id).to be_nil
736
+ end
737
+
738
+ it "deletes the target from the database" do
739
+ expect(post).to be_destroyed
740
+ end
741
+ end
742
+
743
+ context "when dependent is not destructive" do
744
+
745
+ let(:drug) do
746
+ Drug.new(name: "Oxycodone")
747
+ end
748
+
749
+ before do
750
+ person.drugs = [ drug ]
751
+ person.drugs = nil
752
+ end
753
+
754
+ it "sets the association to empty" do
755
+ expect(person.drugs).to be_empty
756
+ end
757
+
758
+ it "removed the inverse association" do
759
+ expect(drug.person).to be_nil
760
+ end
761
+
762
+ it "removes the foreign key value" do
763
+ expect(drug.person_id).to be_nil
764
+ end
765
+
766
+ it "nullifies the association" do
767
+ expect(drug).to_not be_destroyed
768
+ end
769
+ end
770
+ end
771
+ end
772
+
773
+ context "when the association is polymorphic" do
774
+
775
+ context "when the parent is a new record" do
776
+
777
+ let(:movie) do
778
+ Movie.new
779
+ end
780
+
781
+ let(:rating) do
782
+ Rating.new
783
+ end
784
+
785
+ before do
786
+ movie.ratings = [ rating ]
787
+ movie.ratings = nil
788
+ end
789
+
790
+ it "sets the association to an empty array" do
791
+ expect(movie.ratings).to be_empty
792
+ end
793
+
794
+ it "removed the inverse association" do
795
+ expect(rating.ratable).to be_nil
796
+ end
797
+
798
+ it "removes the foreign key value" do
799
+ expect(rating.ratable_id).to be_nil
800
+ end
801
+ end
802
+
803
+ context "when the parent is not a new record" do
804
+
805
+ let(:movie) do
806
+ Movie.create
807
+ end
808
+
809
+ let(:rating) do
810
+ Rating.new
811
+ end
812
+
813
+ before do
814
+ movie.ratings = [ rating ]
815
+ movie.ratings = nil
816
+ end
817
+
818
+ it "sets the association to empty" do
819
+ expect(movie.ratings).to be_empty
820
+ end
821
+
822
+ it "removed the inverse association" do
823
+ expect(rating.ratable).to be_nil
824
+ end
825
+
826
+ it "removes the foreign key value" do
827
+ expect(rating.ratable_id).to be_nil
828
+ end
829
+
830
+ context "when dependent is nullify" do
831
+
832
+ it "does not delete the target from the database" do
833
+ expect(rating).to_not be_destroyed
834
+ end
835
+ end
836
+ end
837
+ end
838
+ end
839
+
840
+ describe "#\{name}_ids=" do
841
+
842
+ let(:person) do
843
+ Person.new
844
+ end
845
+
846
+ let(:post_one) do
847
+ Post.create
848
+ end
849
+
850
+ let(:post_two) do
851
+ Post.create
852
+ end
853
+
854
+ before do
855
+ person.post_ids = [ post_one.id, post_two.id ]
856
+ end
857
+
858
+ it "calls setter with documents find by given ids" do
859
+ expect(person.posts).to eq([ post_one, post_two ])
860
+ end
861
+ end
862
+
863
+ describe "#\{name}_ids" do
864
+
865
+ let(:posts) do
866
+ [ Post.create, Post.create ]
867
+ end
868
+
869
+ let(:person) do
870
+ Person.create(posts: posts)
871
+ end
872
+
873
+ it "returns ids of documents that are in the association" do
874
+ expect(person.post_ids).to eq(posts.map(&:id))
875
+ end
876
+ end
877
+
878
+ [ :build, :new ].each do |method|
879
+
880
+ describe "##{method}" do
881
+
882
+ context "when the association is not polymorphic" do
883
+
884
+ context "when the parent is a new record" do
885
+
886
+ let(:person) do
887
+ Person.new(title: "sir")
888
+ end
889
+
890
+ let!(:post) do
891
+ person.posts.send(method, title: "$$$")
892
+ end
893
+
894
+ it "sets the foreign key on the association" do
895
+ expect(post.person_id).to eq(person.id)
896
+ end
897
+
898
+ it "sets the base on the inverse association" do
899
+ expect(post.person).to eq(person)
900
+ end
901
+
902
+ it "sets the attributes" do
903
+ expect(post.title).to eq("$$$")
904
+ end
905
+
906
+ it "sets the post processed defaults" do
907
+ expect(post.person_title).to eq(person.title)
908
+ end
909
+
910
+ it "does not save the target" do
911
+ expect(post).to be_new_record
912
+ end
913
+
914
+ it "adds the document to the target" do
915
+ expect(person.posts.size).to eq(1)
916
+ end
917
+
918
+ it "does not perform validation" do
919
+ expect(post.errors).to be_empty
920
+ end
921
+ end
922
+
923
+ context "when the parent is not a new record" do
924
+
925
+ let(:person) do
926
+ Person.create
927
+ end
928
+
929
+ let!(:post) do
930
+ person.posts.send(method, text: "Testing")
931
+ end
932
+
933
+ it "sets the foreign key on the association" do
934
+ expect(post.person_id).to eq(person.id)
935
+ end
936
+
937
+ it "sets the base on the inverse association" do
938
+ expect(post.person).to eq(person)
939
+ end
940
+
941
+ it "sets the attributes" do
942
+ expect(post.text).to eq("Testing")
943
+ end
944
+
945
+ it "does not save the target" do
946
+ expect(post).to be_new_record
947
+ end
948
+
949
+ it "adds the document to the target" do
950
+ expect(person.posts.size).to eq(1)
951
+ end
952
+ end
953
+ end
954
+
955
+ context "when the association is polymorphic" do
956
+
957
+ context "when the parent is a subclass" do
958
+
959
+ let(:video_game) do
960
+ VideoGame.create
961
+ end
962
+
963
+ let(:rating) do
964
+ video_game.ratings.build
965
+ end
966
+
967
+ it "sets the parent on the child" do
968
+ expect(rating.ratable).to eq(video_game)
969
+ end
970
+
971
+ it "sets the correct polymorphic type" do
972
+ expect(rating.ratable_type).to eq("VideoGame")
973
+ end
974
+ end
975
+
976
+ context "when the parent is a new record" do
977
+
978
+ let(:movie) do
979
+ Movie.new
980
+ end
981
+
982
+ let!(:rating) do
983
+ movie.ratings.send(method, value: 3)
984
+ end
985
+
986
+ it "sets the foreign key on the association" do
987
+ expect(rating.ratable_id).to eq(movie.id)
988
+ end
989
+
990
+ it "sets the base on the inverse association" do
991
+ expect(rating.ratable).to eq(movie)
992
+ end
993
+
994
+ it "sets the attributes" do
995
+ expect(rating.value).to eq(3)
996
+ end
997
+
998
+ it "does not save the target" do
999
+ expect(rating).to be_new_record
1000
+ end
1001
+
1002
+ it "adds the document to the target" do
1003
+ expect(movie.ratings.size).to eq(1)
1004
+ end
1005
+
1006
+ it "does not perform validation" do
1007
+ expect(rating.errors).to be_empty
1008
+ end
1009
+ end
1010
+
1011
+ context "when the parent is not a new record" do
1012
+
1013
+ let(:movie) do
1014
+ Movie.create
1015
+ end
1016
+
1017
+ let!(:rating) do
1018
+ movie.ratings.send(method, value: 4)
1019
+ end
1020
+
1021
+ it "sets the foreign key on the association" do
1022
+ expect(rating.ratable_id).to eq(movie.id)
1023
+ end
1024
+
1025
+ it "sets the base on the inverse association" do
1026
+ expect(rating.ratable).to eq(movie)
1027
+ end
1028
+
1029
+ it "sets the attributes" do
1030
+ expect(rating.value).to eq(4)
1031
+ end
1032
+
1033
+ it "does not save the target" do
1034
+ expect(rating).to be_new_record
1035
+ end
1036
+
1037
+ it "adds the document to the target" do
1038
+ expect(movie.ratings.size).to eq(1)
1039
+ end
1040
+ end
1041
+ end
1042
+ end
1043
+ end
1044
+
1045
+ describe "#clear" do
1046
+
1047
+ context "when the association is not polymorphic" do
1048
+
1049
+ context "when the parent has been persisted" do
1050
+
1051
+ let!(:person) do
1052
+ Person.create
1053
+ end
1054
+
1055
+ context "when the children are persisted" do
1056
+
1057
+ let!(:post) do
1058
+ person.posts.create(title: "Testing")
1059
+ end
1060
+
1061
+ let!(:association) do
1062
+ person.posts.clear
1063
+ end
1064
+
1065
+ it "clears out the association" do
1066
+ expect(person.posts).to be_empty
1067
+ end
1068
+
1069
+ it "marks the documents as deleted" do
1070
+ expect(post).to be_destroyed
1071
+ end
1072
+
1073
+ it "deletes the documents from the db" do
1074
+ expect(person.reload.posts).to be_empty
1075
+ end
1076
+
1077
+ it "returns the association" do
1078
+ expect(association).to be_empty
1079
+ end
1080
+ end
1081
+
1082
+ context "when the children are not persisted" do
1083
+
1084
+ let!(:post) do
1085
+ person.posts.build(title: "Testing")
1086
+ end
1087
+
1088
+ let!(:association) do
1089
+ person.posts.clear
1090
+ end
1091
+
1092
+ it "clears out the association" do
1093
+ expect(person.posts).to be_empty
1094
+ end
1095
+ end
1096
+ end
1097
+
1098
+ context "when the parent is not persisted" do
1099
+
1100
+ let(:person) do
1101
+ Person.new
1102
+ end
1103
+
1104
+ let!(:post) do
1105
+ person.posts.build(title: "Testing")
1106
+ end
1107
+
1108
+ let!(:association) do
1109
+ person.posts.clear
1110
+ end
1111
+
1112
+ it "clears out the association" do
1113
+ expect(person.posts).to be_empty
1114
+ end
1115
+ end
1116
+ end
1117
+
1118
+ context "when the association is polymorphic" do
1119
+
1120
+ context "when the parent has been persisted" do
1121
+
1122
+ let!(:movie) do
1123
+ Movie.create
1124
+ end
1125
+
1126
+ context "when the children are persisted" do
1127
+
1128
+ let!(:rating) do
1129
+ movie.ratings.create(value: 1)
1130
+ end
1131
+
1132
+ let!(:association) do
1133
+ movie.ratings.clear
1134
+ end
1135
+
1136
+ it "clears out the association" do
1137
+ expect(movie.ratings).to be_empty
1138
+ end
1139
+
1140
+ it "handles the proper dependent strategy" do
1141
+ expect(rating).to_not be_destroyed
1142
+ end
1143
+
1144
+ it "deletes the documents from the db" do
1145
+ expect(movie.reload.ratings).to be_empty
1146
+ end
1147
+
1148
+ it "returns the association" do
1149
+ expect(association).to be_empty
1150
+ end
1151
+ end
1152
+
1153
+ context "when the children are not persisted" do
1154
+
1155
+ let!(:rating) do
1156
+ movie.ratings.build(value: 3)
1157
+ end
1158
+
1159
+ let!(:association) do
1160
+ movie.ratings.clear
1161
+ end
1162
+
1163
+ it "clears out the association" do
1164
+ expect(movie.ratings).to be_empty
1165
+ end
1166
+ end
1167
+ end
1168
+
1169
+ context "when the parent is not persisted" do
1170
+
1171
+ let(:movie) do
1172
+ Movie.new
1173
+ end
1174
+
1175
+ let!(:rating) do
1176
+ movie.ratings.build(value: 2)
1177
+ end
1178
+
1179
+ let!(:association) do
1180
+ movie.ratings.clear
1181
+ end
1182
+
1183
+ it "clears out the association" do
1184
+ expect(movie.ratings).to be_empty
1185
+ end
1186
+ end
1187
+ end
1188
+ end
1189
+
1190
+ describe "#concat" do
1191
+
1192
+ context "when the associations are not polymorphic" do
1193
+
1194
+ context "when the parent is a new record" do
1195
+
1196
+ let(:person) do
1197
+ Person.new
1198
+ end
1199
+
1200
+ let(:post) do
1201
+ Post.new
1202
+ end
1203
+
1204
+ before do
1205
+ person.posts.concat([ post ])
1206
+ end
1207
+
1208
+ it "sets the foreign key on the association" do
1209
+ expect(post.person_id).to eq(person.id)
1210
+ end
1211
+
1212
+ it "sets the base on the inverse association" do
1213
+ expect(post.person).to eq(person)
1214
+ end
1215
+
1216
+ it "sets the same instance on the inverse association" do
1217
+ expect(post.person).to eql(person)
1218
+ end
1219
+
1220
+ it "does not save the target" do
1221
+ expect(post).to be_new_record
1222
+ end
1223
+
1224
+ it "adds the document to the target" do
1225
+ expect(person.posts.size).to eq(1)
1226
+ end
1227
+ end
1228
+
1229
+ context "when appending in a parent create block" do
1230
+
1231
+ let!(:post) do
1232
+ Post.create(title: "testing")
1233
+ end
1234
+
1235
+ let!(:person) do
1236
+ Person.create do |doc|
1237
+ doc.posts.concat([ post ])
1238
+ end
1239
+ end
1240
+
1241
+ it "adds the documents to the association" do
1242
+ expect(person.posts).to eq([ post ])
1243
+ end
1244
+
1245
+ it "sets the foreign key on the inverse association" do
1246
+ expect(post.person_id).to eq(person.id)
1247
+ end
1248
+
1249
+ it "saves the target" do
1250
+ expect(post).to be_persisted
1251
+ end
1252
+
1253
+ it "adds the correct number of documents" do
1254
+ expect(person.posts.size).to eq(1)
1255
+ end
1256
+
1257
+ it "persists the link" do
1258
+ expect(person.reload.posts).to eq([ post ])
1259
+ end
1260
+ end
1261
+
1262
+ context "when the parent is not a new record" do
1263
+
1264
+ let(:person) do
1265
+ Person.create
1266
+ end
1267
+
1268
+ let(:post) do
1269
+ Post.new
1270
+ end
1271
+
1272
+ let(:post_three) do
1273
+ Post.new
1274
+ end
1275
+
1276
+ before do
1277
+ person.posts.concat([ post, post_three ])
1278
+ end
1279
+
1280
+ it "sets the foreign key on the association" do
1281
+ expect(post.person_id).to eq(person.id)
1282
+ end
1283
+
1284
+ it "sets the base on the inverse association" do
1285
+ expect(post.person).to eq(person)
1286
+ end
1287
+
1288
+ it "sets the same instance on the inverse association" do
1289
+ expect(post.person).to eql(person)
1290
+ end
1291
+
1292
+ it "saves the target" do
1293
+ expect(post).to be_persisted
1294
+ end
1295
+
1296
+ it "adds the document to the target" do
1297
+ expect(person.posts.count).to eq(2)
1298
+ end
1299
+
1300
+ context "when documents already exist on the association" do
1301
+
1302
+ let(:post_two) do
1303
+ Post.new(title: "Test")
1304
+ end
1305
+
1306
+ before do
1307
+ person.posts.concat([ post_two ])
1308
+ end
1309
+
1310
+ it "sets the foreign key on the association" do
1311
+ expect(post_two.person_id).to eq(person.id)
1312
+ end
1313
+
1314
+ it "sets the base on the inverse association" do
1315
+ expect(post_two.person).to eq(person)
1316
+ end
1317
+
1318
+ it "sets the same instance on the inverse association" do
1319
+ expect(post_two.person).to eql(person)
1320
+ end
1321
+
1322
+ it "saves the target" do
1323
+ expect(post_two).to be_persisted
1324
+ end
1325
+
1326
+ it "adds the document to the target" do
1327
+ expect(person.posts.count).to eq(3)
1328
+ end
1329
+
1330
+ it "contains the initial document in the target" do
1331
+ expect(person.posts).to include(post)
1332
+ end
1333
+
1334
+ it "contains the added document in the target" do
1335
+ expect(person.posts).to include(post_two)
1336
+ end
1337
+ end
1338
+ end
1339
+ end
1340
+ end
1341
+
1342
+ context "when the associations are polymorphic" do
1343
+
1344
+ context "when the parent is a new record" do
1345
+
1346
+ let(:movie) do
1347
+ Movie.new
1348
+ end
1349
+
1350
+ let(:rating) do
1351
+ Rating.new
1352
+ end
1353
+
1354
+ before do
1355
+ movie.ratings.concat([ rating ])
1356
+ end
1357
+
1358
+ it "sets the foreign key on the association" do
1359
+ expect(rating.ratable_id).to eq(movie.id)
1360
+ end
1361
+
1362
+ it "sets the base on the inverse association" do
1363
+ expect(rating.ratable).to eq(movie)
1364
+ end
1365
+
1366
+ it "does not save the target" do
1367
+ expect(rating).to be_new_record
1368
+ end
1369
+
1370
+ it "adds the document to the target" do
1371
+ expect(movie.ratings.size).to eq(1)
1372
+ end
1373
+ end
1374
+
1375
+ context "when the parent is not a new record" do
1376
+
1377
+ let(:movie) do
1378
+ Movie.create
1379
+ end
1380
+
1381
+ let(:rating) do
1382
+ Rating.new
1383
+ end
1384
+
1385
+ before do
1386
+ movie.ratings.concat([ rating ])
1387
+ end
1388
+
1389
+ it "sets the foreign key on the association" do
1390
+ expect(rating.ratable_id).to eq(movie.id)
1391
+ end
1392
+
1393
+ it "sets the base on the inverse association" do
1394
+ expect(rating.ratable).to eq(movie)
1395
+ end
1396
+
1397
+ it "saves the target" do
1398
+ expect(rating).to be_persisted
1399
+ end
1400
+
1401
+ it "adds the document to the target" do
1402
+ expect(movie.ratings.count).to eq(1)
1403
+ end
1404
+ end
1405
+ end
1406
+
1407
+ describe "#count" do
1408
+
1409
+ let(:movie) do
1410
+ Movie.create
1411
+ end
1412
+
1413
+ context "when documents have been persisted" do
1414
+
1415
+ let!(:rating) do
1416
+ movie.ratings.create(value: 1)
1417
+ end
1418
+
1419
+ it "returns the number of persisted documents" do
1420
+ expect(movie.ratings.count).to eq(1)
1421
+ end
1422
+ end
1423
+
1424
+ context "when documents have not been persisted" do
1425
+
1426
+ let!(:rating) do
1427
+ movie.ratings.build(value: 1)
1428
+ end
1429
+
1430
+ it "returns 0" do
1431
+ expect(movie.ratings.count).to eq(0)
1432
+ end
1433
+ end
1434
+
1435
+ context "when no document is added" do
1436
+
1437
+ it "returns false" do
1438
+ expect(movie.ratings.any?).to be false
1439
+ end
1440
+ end
1441
+
1442
+ context "when new documents exist in the database" do
1443
+
1444
+ context "when the documents are part of the association" do
1445
+
1446
+ before do
1447
+ Rating.create(ratable: movie)
1448
+ end
1449
+
1450
+ it "returns the count from the db" do
1451
+ expect(movie.ratings.count).to eq(1)
1452
+ end
1453
+ end
1454
+
1455
+ context "when the documents are not part of the association" do
1456
+
1457
+ before do
1458
+ Rating.create
1459
+ end
1460
+
1461
+ it "returns the count from the db" do
1462
+ expect(movie.ratings.count).to eq(0)
1463
+ end
1464
+ end
1465
+ end
1466
+ end
1467
+
1468
+ describe "#any?" do
1469
+
1470
+ shared_examples 'does not query database when association is loaded' do
1471
+
1472
+ let(:fresh_movie) { Movie.find(movie.id) }
1473
+
1474
+ context 'when association is not loaded' do
1475
+ it 'queries database on each call' do
1476
+ fresh_movie
1477
+
1478
+ expect_query(1) do
1479
+ fresh_movie.ratings.any?.should be expected_result
1480
+ end
1481
+
1482
+ expect_query(1) do
1483
+ fresh_movie.ratings.any?.should be expected_result
1484
+ end
1485
+ end
1486
+
1487
+ context 'when using a block' do
1488
+ it 'queries database on first call only' do
1489
+ fresh_movie
1490
+
1491
+ expect_query(1) do
1492
+ fresh_movie.ratings.any? { false }.should be false
1493
+ end
1494
+
1495
+ expect_no_queries do
1496
+ fresh_movie.ratings.any? { false }.should be false
1497
+ end
1498
+ end
1499
+ end
1500
+ end
1501
+
1502
+ context 'when association is loaded' do
1503
+ it 'does not query database' do
1504
+ fresh_movie
1505
+
1506
+ expect_query(1) do
1507
+ fresh_movie.ratings.any?.should be expected_result
1508
+ end
1509
+
1510
+ fresh_movie.ratings.to_a
1511
+
1512
+ expect_no_queries do
1513
+ fresh_movie.ratings.any?.should be expected_result
1514
+ end
1515
+ end
1516
+ end
1517
+ end
1518
+
1519
+ let(:movie) do
1520
+ Movie.create
1521
+ end
1522
+
1523
+ context "when nothing exists on the association" do
1524
+
1525
+ context "when no document is added" do
1526
+
1527
+ let!(:movie) do
1528
+ Movie.create!
1529
+ end
1530
+
1531
+ it "returns false" do
1532
+ expect(movie.ratings.any?).to be false
1533
+ end
1534
+
1535
+ let(:expected_result) { false }
1536
+ include_examples 'does not query database when association is loaded'
1537
+ end
1538
+
1539
+ context "when the document is destroyed" do
1540
+
1541
+ before do
1542
+ Rating.create!
1543
+ end
1544
+
1545
+ let!(:movie) do
1546
+ Movie.create!
1547
+ end
1548
+
1549
+ it "returns false" do
1550
+ movie.destroy
1551
+ expect(movie.ratings.any?).to be false
1552
+ end
1553
+ end
1554
+ end
1555
+
1556
+ context "when appending to a association and _loaded/_unloaded are empty" do
1557
+
1558
+ let!(:movie) do
1559
+ Movie.create!
1560
+ end
1561
+
1562
+ before do
1563
+ movie.ratings << Rating.new
1564
+ end
1565
+
1566
+ it "returns true" do
1567
+ expect(movie.ratings.any?).to be true
1568
+ end
1569
+
1570
+ context 'when association is not loaded' do
1571
+ it 'queries database on each call' do
1572
+ expect_query(1) do
1573
+ movie.ratings.any?.should be true
1574
+ end
1575
+
1576
+ expect_query(1) do
1577
+ movie.ratings.any?.should be true
1578
+ end
1579
+ end
1580
+ end
1581
+
1582
+ context 'when association is loaded' do
1583
+ it 'does not query database' do
1584
+ expect_query(1) do
1585
+ movie.ratings.any?.should be true
1586
+ end
1587
+
1588
+ movie.ratings.to_a
1589
+
1590
+ expect_no_queries do
1591
+ movie.ratings.any?.should be true
1592
+ end
1593
+ end
1594
+ end
1595
+ end
1596
+
1597
+ context "when appending to a association in a transaction" do
1598
+ require_transaction_support
1599
+
1600
+ let!(:movie) do
1601
+ Movie.create!
1602
+ end
1603
+
1604
+ it "returns true" do
1605
+ movie.with_session do |session|
1606
+ session.with_transaction do
1607
+ expect{ movie.ratings << Rating.new }.to_not raise_error
1608
+ expect(movie.ratings.any?).to be true
1609
+ end
1610
+ end
1611
+ end
1612
+ end
1613
+
1614
+ context "when documents have been persisted" do
1615
+
1616
+ let!(:rating) do
1617
+ movie.ratings.create(value: 1)
1618
+ end
1619
+
1620
+ it "returns true" do
1621
+ expect(movie.ratings.any?).to be true
1622
+ end
1623
+
1624
+ let(:expected_result) { true }
1625
+ include_examples 'does not query database when association is loaded'
1626
+ end
1627
+
1628
+ context "when documents have not been persisted" do
1629
+
1630
+ let!(:rating) do
1631
+ movie.ratings.build(value: 1)
1632
+ end
1633
+
1634
+ it "returns false" do
1635
+ expect(movie.ratings.any?).to be true
1636
+ end
1637
+ end
1638
+
1639
+ context "when new documents exist in the database" do
1640
+ before do
1641
+ Rating.create(ratable: movie)
1642
+ end
1643
+
1644
+ it "returns true" do
1645
+ expect(movie.ratings.any?).to be true
1646
+ end
1647
+ end
1648
+ end
1649
+
1650
+ describe "#create" do
1651
+
1652
+ context "when providing multiple attributes" do
1653
+
1654
+ let(:person) do
1655
+ Person.create
1656
+ end
1657
+
1658
+ let!(:posts) do
1659
+ person.posts.create([{ text: "Test1" }, { text: "Test2" }])
1660
+ end
1661
+
1662
+ it "creates multiple documents" do
1663
+ expect(posts.size).to eq(2)
1664
+ end
1665
+
1666
+ it "sets the first attributes" do
1667
+ expect(posts.first.text).to eq("Test1")
1668
+ end
1669
+
1670
+ it "sets the second attributes" do
1671
+ expect(posts.last.text).to eq("Test2")
1672
+ end
1673
+
1674
+ it "persists the children" do
1675
+ expect(person.posts.count).to eq(2)
1676
+ end
1677
+ end
1678
+
1679
+ context "when the association is not polymorphic" do
1680
+
1681
+ context "when the parent is a new record" do
1682
+
1683
+ let(:person) do
1684
+ Person.new
1685
+ end
1686
+
1687
+ let(:post) do
1688
+ person.posts.create(text: "Testing")
1689
+ end
1690
+
1691
+ it "raises an unsaved document error" do
1692
+ expect { post }.to raise_error(Mongoid::Errors::UnsavedDocument)
1693
+ end
1694
+ end
1695
+
1696
+ context "when.creating the document" do
1697
+
1698
+ context "when the operation is successful" do
1699
+
1700
+ let(:person) do
1701
+ Person.create
1702
+ end
1703
+
1704
+ let!(:post) do
1705
+ person.posts.create(text: "Testing")
1706
+ end
1707
+
1708
+ it "creates the document" do
1709
+ expect(person.posts).to eq([ post ])
1710
+ end
1711
+ end
1712
+
1713
+ context "when the operation fails" do
1714
+
1715
+ let(:person) do
1716
+ Person.create
1717
+ end
1718
+
1719
+ let!(:existing) do
1720
+ Post.create
1721
+ end
1722
+
1723
+ it "raises an error" do
1724
+ expect {
1725
+ person.posts.create do |doc|
1726
+ doc._id = existing.id
1727
+ end
1728
+ }.to raise_error(Mongo::Error::OperationFailure)
1729
+ end
1730
+ end
1731
+ end
1732
+
1733
+ context "when the parent is not a new record" do
1734
+
1735
+ let(:person) do
1736
+ Person.create
1737
+ end
1738
+
1739
+ let!(:post) do
1740
+ person.posts.create(text: "Testing") do |post|
1741
+ post.content = "The Content"
1742
+ end
1743
+ end
1744
+
1745
+ it "sets the foreign key on the association" do
1746
+ expect(post.person_id).to eq(person.id)
1747
+ end
1748
+
1749
+ it "sets the base on the inverse association" do
1750
+ expect(post.person).to eq(person)
1751
+ end
1752
+
1753
+ it "sets the attributes" do
1754
+ expect(post.text).to eq("Testing")
1755
+ end
1756
+
1757
+ it "saves the target" do
1758
+ expect(post).to_not be_a_new_record
1759
+ end
1760
+
1761
+ it "calls the passed block" do
1762
+ expect(post.content).to eq("The Content")
1763
+ end
1764
+
1765
+ it "adds the document to the target" do
1766
+ expect(person.posts.count).to eq(1)
1767
+ end
1768
+ end
1769
+
1770
+ context "when passing a new object" do
1771
+
1772
+ let!(:odd) do
1773
+ Odd.create(name: 'one')
1774
+ end
1775
+
1776
+ let!(:even) do
1777
+ odd.evens.create(name: 'two', odds: [Odd.new(name: 'three')])
1778
+ end
1779
+
1780
+ it "only push one even to the list" do
1781
+ expect(odd.evens.count).to eq(1)
1782
+ end
1783
+
1784
+ it "saves the reference back" do
1785
+ expect(odd.evens.first.odds.count).to eq(1)
1786
+ end
1787
+
1788
+ it "only saves one even" do
1789
+ expect(Even.count).to eq(1)
1790
+ end
1791
+
1792
+ it "saves the first odd and the second" do
1793
+ expect(Odd.count).to eq(2)
1794
+ end
1795
+ end
1796
+ end
1797
+
1798
+ context "when the association is polymorphic" do
1799
+
1800
+ context "when the parent is a new record" do
1801
+
1802
+ let(:movie) do
1803
+ Movie.new
1804
+ end
1805
+
1806
+ let(:rating) do
1807
+ movie.ratings.create(value: 1)
1808
+ end
1809
+
1810
+ it "raises an unsaved document error" do
1811
+ expect { rating }.to raise_error(Mongoid::Errors::UnsavedDocument)
1812
+ end
1813
+ end
1814
+
1815
+ context "when the parent is not a new record" do
1816
+
1817
+ let(:movie) do
1818
+ Movie.create
1819
+ end
1820
+
1821
+ let!(:rating) do
1822
+ movie.ratings.create(value: 3)
1823
+ end
1824
+
1825
+ it "sets the foreign key on the association" do
1826
+ expect(rating.ratable_id).to eq(movie.id)
1827
+ end
1828
+
1829
+ it "sets the base on the inverse association" do
1830
+ expect(rating.ratable).to eq(movie)
1831
+ end
1832
+
1833
+ it "sets the attributes" do
1834
+ expect(rating.value).to eq(3)
1835
+ end
1836
+
1837
+ it "saves the target" do
1838
+ expect(rating).to_not be_new_record
1839
+ end
1840
+
1841
+ it "adds the document to the target" do
1842
+ expect(movie.ratings.count).to eq(1)
1843
+ end
1844
+ end
1845
+ end
1846
+
1847
+ context "when using a diferent primary_key" do
1848
+
1849
+ let(:person) do
1850
+ Person.create!(username: 'arthurnn')
1851
+ end
1852
+
1853
+ let(:drug) do
1854
+ person.drugs.create!
1855
+ end
1856
+
1857
+ it 'saves pk value on fk field' do
1858
+ expect(drug.person_id).to eq('arthurnn')
1859
+ end
1860
+ end
1861
+ end
1862
+
1863
+ describe "#create!" do
1864
+
1865
+ context "when providing multiple attributes" do
1866
+
1867
+ let(:person) do
1868
+ Person.create
1869
+ end
1870
+
1871
+ let!(:posts) do
1872
+ person.posts.create!([{ text: "Test1" }, { text: "Test2" }])
1873
+ end
1874
+
1875
+ it "creates multiple documents" do
1876
+ expect(posts.size).to eq(2)
1877
+ end
1878
+
1879
+ it "sets the first attributes" do
1880
+ expect(posts.first.text).to eq("Test1")
1881
+ end
1882
+
1883
+ it "sets the second attributes" do
1884
+ expect(posts.last.text).to eq("Test2")
1885
+ end
1886
+
1887
+ it "persists the children" do
1888
+ expect(person.posts.count).to eq(2)
1889
+ end
1890
+ end
1891
+
1892
+ context "when the association is not polymorphic" do
1893
+
1894
+ context "when the parent is a new record" do
1895
+
1896
+ let(:person) do
1897
+ Person.new
1898
+ end
1899
+
1900
+ let(:post) do
1901
+ person.posts.create!(title: "Testing")
1902
+ end
1903
+
1904
+ it "raises an unsaved document error" do
1905
+ expect { post }.to raise_error(Mongoid::Errors::UnsavedDocument)
1906
+ end
1907
+ end
1908
+
1909
+ context "when the parent is not a new record" do
1910
+
1911
+ let(:person) do
1912
+ Person.create
1913
+ end
1914
+
1915
+ let!(:post) do
1916
+ person.posts.create!(title: "Testing")
1917
+ end
1918
+
1919
+ it "sets the foreign key on the association" do
1920
+ expect(post.person_id).to eq(person.id)
1921
+ end
1922
+
1923
+ it "sets the base on the inverse association" do
1924
+ expect(post.person).to eq(person)
1925
+ end
1926
+
1927
+ it "sets the attributes" do
1928
+ expect(post.title).to eq("Testing")
1929
+ end
1930
+
1931
+ it "saves the target" do
1932
+ expect(post).to_not be_a_new_record
1933
+ end
1934
+
1935
+ it "adds the document to the target" do
1936
+ expect(person.posts.count).to eq(1)
1937
+ end
1938
+
1939
+ context "when validation fails" do
1940
+
1941
+ it "raises an error" do
1942
+ expect {
1943
+ person.posts.create!(title: "$$$")
1944
+ }.to raise_error(Mongoid::Errors::Validations)
1945
+ end
1946
+ end
1947
+ end
1948
+ end
1949
+
1950
+ context "when the association is polymorphic" do
1951
+
1952
+ context "when the parent is a new record" do
1953
+
1954
+ let(:movie) do
1955
+ Movie.new
1956
+ end
1957
+
1958
+ let(:rating) do
1959
+ movie.ratings.create!(value: 1)
1960
+ end
1961
+
1962
+ it "raises an unsaved document error" do
1963
+ expect { rating }.to raise_error(Mongoid::Errors::UnsavedDocument)
1964
+ end
1965
+ end
1966
+
1967
+ context "when the parent is not a new record" do
1968
+
1969
+ let(:movie) do
1970
+ Movie.create
1971
+ end
1972
+
1973
+ let!(:rating) do
1974
+ movie.ratings.create!(value: 4)
1975
+ end
1976
+
1977
+ it "sets the foreign key on the association" do
1978
+ expect(rating.ratable_id).to eq(movie.id)
1979
+ end
1980
+
1981
+ it "sets the base on the inverse association" do
1982
+ expect(rating.ratable).to eq(movie)
1983
+ end
1984
+
1985
+ it "sets the attributes" do
1986
+ expect(rating.value).to eq(4)
1987
+ end
1988
+
1989
+ it "saves the target" do
1990
+ expect(rating).to_not be_new_record
1991
+ end
1992
+
1993
+ it "adds the document to the target" do
1994
+ expect(movie.ratings.count).to eq(1)
1995
+ end
1996
+
1997
+ context "when validation fails" do
1998
+
1999
+ it "raises an error" do
2000
+ expect {
2001
+ movie.ratings.create!(value: 1000)
2002
+ }.to raise_error(Mongoid::Errors::Validations)
2003
+ end
2004
+ end
2005
+ end
2006
+ end
2007
+ end
2008
+
2009
+ describe "#criteria" do
2010
+
2011
+ let(:base) do
2012
+ Movie.new
2013
+ end
2014
+
2015
+ context "when the association is polymorphic" do
2016
+
2017
+ let(:association) do
2018
+ Movie.relations["ratings"]
2019
+ end
2020
+
2021
+ let(:criteria) do
2022
+ association.criteria(base)
2023
+ end
2024
+
2025
+ it "includes the type in the criteria" do
2026
+ expect(criteria.selector).to eq(
2027
+ {
2028
+ "ratable_id" => base.id,
2029
+ "ratable_type" => "Movie"
2030
+ }
2031
+ )
2032
+ end
2033
+ end
2034
+
2035
+ context "when the association is not polymorphic" do
2036
+
2037
+ let(:association) do
2038
+ Person.relations["posts"]
2039
+ end
2040
+
2041
+ let(:base) do
2042
+ Person.new
2043
+ end
2044
+
2045
+ let(:criteria) do
2046
+ association.criteria(base)
2047
+ end
2048
+
2049
+ it "does not include the type in the criteria" do
2050
+ expect(criteria.selector).to eq({ "person_id" => base.id })
2051
+ end
2052
+ end
2053
+ end
2054
+
2055
+ describe "#delete" do
2056
+
2057
+ let!(:person) do
2058
+ Person.create(username: 'arthurnn')
2059
+ end
2060
+
2061
+ context "when the document is found" do
2062
+
2063
+ context "when no dependent option is set" do
2064
+
2065
+ context "when we are assigning attributes" do
2066
+
2067
+ let!(:drug) do
2068
+ person.drugs.create
2069
+ end
2070
+
2071
+ before do
2072
+ Mongoid::Threaded.begin_execution(:assign)
2073
+ end
2074
+
2075
+ after do
2076
+ Mongoid::Threaded.exit_execution(:assign)
2077
+ end
2078
+
2079
+ let(:deleted) do
2080
+ person.drugs.delete(drug)
2081
+ end
2082
+
2083
+ it "does not cascade" do
2084
+ expect(deleted.changes.keys).to eq([ "person_id" ])
2085
+ end
2086
+ end
2087
+
2088
+ context "when the document is loaded" do
2089
+
2090
+ let!(:drug) do
2091
+ person.drugs.create
2092
+ end
2093
+
2094
+ let!(:deleted) do
2095
+ person.drugs.delete(drug)
2096
+ end
2097
+
2098
+ it "returns the document" do
2099
+ expect(deleted).to eq(drug)
2100
+ end
2101
+
2102
+ it "deletes the foreign key" do
2103
+ expect(drug.person_id).to be_nil
2104
+ end
2105
+
2106
+ it "removes the document from the association" do
2107
+ expect(person.drugs).to_not include(drug)
2108
+ end
2109
+ end
2110
+
2111
+ context "when the document is not loaded" do
2112
+
2113
+ let!(:drug) do
2114
+ Drug.create(person_id: person.username)
2115
+ end
2116
+
2117
+ let!(:deleted) do
2118
+ person.drugs.delete(drug)
2119
+ end
2120
+
2121
+ it "returns the document" do
2122
+ expect(deleted).to eq(drug)
2123
+ end
2124
+
2125
+ it "deletes the foreign key" do
2126
+ expect(drug.person_id).to be_nil
2127
+ end
2128
+
2129
+ it "removes the document from the association" do
2130
+ expect(person.drugs).to_not include(drug)
2131
+ end
2132
+ end
2133
+ end
2134
+
2135
+ context "when dependent is delete" do
2136
+
2137
+ context "when the document is loaded" do
2138
+
2139
+ let!(:post) do
2140
+ person.posts.create(title: "test")
2141
+ end
2142
+
2143
+ let!(:deleted) do
2144
+ person.posts.delete(post)
2145
+ end
2146
+
2147
+ it "returns the document" do
2148
+ expect(deleted).to eq(post)
2149
+ end
2150
+
2151
+ it "deletes the document" do
2152
+ expect(post).to be_destroyed
2153
+ end
2154
+
2155
+ it "removes the document from the association" do
2156
+ expect(person.posts).to_not include(post)
2157
+ end
2158
+ end
2159
+
2160
+ context "when the document is not loaded" do
2161
+
2162
+ let!(:post) do
2163
+ Post.create(title: "foo", person_id: person.id)
2164
+ end
2165
+
2166
+ let!(:deleted) do
2167
+ person.posts.delete(post)
2168
+ end
2169
+
2170
+ it "returns the document" do
2171
+ expect(deleted).to eq(post)
2172
+ end
2173
+
2174
+ it "deletes the document" do
2175
+ expect(post).to be_destroyed
2176
+ end
2177
+
2178
+ it "removes the document from the association" do
2179
+ expect(person.posts).to_not include(post)
2180
+ end
2181
+ end
2182
+ end
2183
+ end
2184
+
2185
+ context "when the document is not found" do
2186
+
2187
+ let!(:post) do
2188
+ Post.create(title: "foo")
2189
+ end
2190
+
2191
+ let!(:deleted) do
2192
+ person.posts.delete(post)
2193
+ end
2194
+
2195
+ it "returns nil" do
2196
+ expect(deleted).to be_nil
2197
+ end
2198
+
2199
+ it "does not delete the document" do
2200
+ expect(post).to be_persisted
2201
+ end
2202
+ end
2203
+ end
2204
+
2205
+ [ :delete_all, :destroy_all ].each do |method|
2206
+
2207
+ describe "##{method}" do
2208
+
2209
+ context "when the association is not polymorphic" do
2210
+
2211
+ context "when conditions are provided" do
2212
+
2213
+ let(:person) do
2214
+ Person.create(username: 'durran')
2215
+ end
2216
+
2217
+ before do
2218
+ person.posts.create(title: "Testing")
2219
+ person.posts.create(title: "Test")
2220
+ end
2221
+
2222
+ it "removes the correct posts" do
2223
+ person.posts.send(method, { title: "Testing" })
2224
+ expect(person.posts.count).to eq(1)
2225
+ expect(person.reload.posts_count).to eq(1) if method == :destroy_all
2226
+ end
2227
+
2228
+ it "deletes the documents from the database" do
2229
+ person.posts.send(method, { title: "Testing" })
2230
+ expect(Post.where(title: "Testing").count).to eq(0)
2231
+ end
2232
+
2233
+ it "returns the number of documents deleted" do
2234
+ expect(person.posts.send(method, { title: "Testing" })).to eq(1)
2235
+ end
2236
+ end
2237
+
2238
+ context "when conditions are not provided" do
2239
+
2240
+ let(:person) do
2241
+ Person.create
2242
+ end
2243
+
2244
+ before do
2245
+ person.posts.create(title: "Testing")
2246
+ person.posts.create(title: "Test")
2247
+ end
2248
+
2249
+ it "removes the correct posts" do
2250
+ person.posts.send(method)
2251
+ expect(person.posts.count).to eq(0)
2252
+ end
2253
+
2254
+ it "deletes the documents from the database" do
2255
+ person.posts.send(method)
2256
+ expect(Post.where(title: "Testing").count).to eq(0)
2257
+ end
2258
+
2259
+ it "returns the number of documents deleted" do
2260
+ expect(person.posts.send(method)).to eq(2)
2261
+ end
2262
+ end
2263
+ end
2264
+
2265
+ context "when the association is polymorphic" do
2266
+
2267
+ context "when conditions are provided" do
2268
+
2269
+ let(:movie) do
2270
+ Movie.create(title: "Bladerunner")
2271
+ end
2272
+
2273
+ before do
2274
+ movie.ratings.create(value: 1)
2275
+ movie.ratings.create(value: 2)
2276
+ end
2277
+
2278
+ it "removes the correct ratings" do
2279
+ movie.ratings.send(method, { value: 1 })
2280
+ expect(movie.ratings.count).to eq(1)
2281
+ end
2282
+
2283
+ it "deletes the documents from the database" do
2284
+ movie.ratings.send(method, { value: 1 })
2285
+ expect(Rating.where(value: 1).count).to eq(0)
2286
+ end
2287
+
2288
+ it "returns the number of documents deleted" do
2289
+ expect(movie.ratings.send(method, { value: 1 })).to eq(1)
2290
+ end
2291
+ end
2292
+
2293
+ context "when conditions are not provided" do
2294
+
2295
+ let(:movie) do
2296
+ Movie.create(title: "Bladerunner")
2297
+ end
2298
+
2299
+ before do
2300
+ movie.ratings.create(value: 1)
2301
+ movie.ratings.create(value: 2)
2302
+ end
2303
+
2304
+ it "removes the correct ratings" do
2305
+ movie.ratings.send(method)
2306
+ expect(movie.ratings.count).to eq(0)
2307
+ end
2308
+
2309
+ it "deletes the documents from the database" do
2310
+ movie.ratings.send(method)
2311
+ expect(Rating.where(value: 1).count).to eq(0)
2312
+ end
2313
+
2314
+ it "returns the number of documents deleted" do
2315
+ expect(movie.ratings.send(method)).to eq(2)
2316
+ end
2317
+ end
2318
+ end
2319
+ end
2320
+ end
2321
+
2322
+ describe ".embedded?" do
2323
+
2324
+ it "returns false" do
2325
+ expect(described_class).to_not be_embedded
2326
+ end
2327
+ end
2328
+
2329
+ describe "#exists?" do
2330
+
2331
+ let!(:person) do
2332
+ Person.create
2333
+ end
2334
+
2335
+ context "when documents exist in the database" do
2336
+
2337
+ before do
2338
+ person.posts.create
2339
+ end
2340
+
2341
+ it "returns true" do
2342
+ expect(person.posts.exists?).to be true
2343
+ end
2344
+
2345
+ context 'when association is not loaded' do
2346
+ it 'queries database on each call' do
2347
+ expect_query(1) do
2348
+ person.posts.exists?.should be true
2349
+ end
2350
+
2351
+ expect_query(1) do
2352
+ person.posts.exists?.should be true
2353
+ end
2354
+ end
2355
+ end
2356
+
2357
+ context 'when association is loaded' do
2358
+ it 'queries database on each call' do
2359
+ expect_query(1) do
2360
+ person.posts.exists?.should be true
2361
+ end
2362
+
2363
+ person.posts.to_a
2364
+
2365
+ expect_query(1) do
2366
+ person.posts.exists?.should be true
2367
+ end
2368
+ end
2369
+ end
2370
+ end
2371
+
2372
+ context "when documents exist in application but not in database" do
2373
+
2374
+ before do
2375
+ person.posts.build
2376
+ end
2377
+
2378
+ it "returns false" do
2379
+ expect(person.posts.exists?).to be false
2380
+ end
2381
+
2382
+ context 'when association is not loaded' do
2383
+ it 'queries database on each call' do
2384
+ expect_query(1) do
2385
+ person.posts.exists?.should be false
2386
+ end
2387
+
2388
+ expect_query(1) do
2389
+ person.posts.exists?.should be false
2390
+ end
2391
+ end
2392
+ end
2393
+
2394
+ context 'when association is loaded' do
2395
+ it 'queries database on each call' do
2396
+ expect_query(1) do
2397
+ person.posts.exists?.should be false
2398
+ end
2399
+
2400
+ person.posts.to_a
2401
+
2402
+ expect_query(1) do
2403
+ person.posts.exists?.should be false
2404
+ end
2405
+ end
2406
+ end
2407
+ end
2408
+
2409
+ context "when no documents exist" do
2410
+
2411
+ it "returns false" do
2412
+ expect(person.posts.exists?).to be false
2413
+ end
2414
+
2415
+ context 'when association is not loaded' do
2416
+ it 'queries database on each call' do
2417
+ expect_query(1) do
2418
+ person.posts.exists?.should be false
2419
+ end
2420
+
2421
+ expect_query(1) do
2422
+ person.posts.exists?.should be false
2423
+ end
2424
+ end
2425
+ end
2426
+
2427
+ context 'when association is loaded' do
2428
+ it 'queries database on each call' do
2429
+ expect_query(1) do
2430
+ person.posts.exists?.should be false
2431
+ end
2432
+
2433
+ person.posts.to_a
2434
+
2435
+ expect_query(1) do
2436
+ person.posts.exists?.should be false
2437
+ end
2438
+ end
2439
+ end
2440
+ end
2441
+ end
2442
+
2443
+ describe "#find" do
2444
+
2445
+ context "when iterating after the find" do
2446
+
2447
+ let(:person) do
2448
+ Person.create!
2449
+ end
2450
+
2451
+ let(:post_id) do
2452
+ person.posts.first.id
2453
+ end
2454
+
2455
+ before do
2456
+ 5.times { person.posts.create! }
2457
+ end
2458
+
2459
+ it "does not change the in memory size" do
2460
+ expect {
2461
+ person.posts.find(post_id)
2462
+ }.not_to change { person.posts.to_a.size }
2463
+ end
2464
+ end
2465
+
2466
+ context "when the association is not polymorphic" do
2467
+
2468
+ let(:person) do
2469
+ Person.create
2470
+ end
2471
+
2472
+ let!(:post_one) do
2473
+ person.posts.create(title: "Test")
2474
+ end
2475
+
2476
+ let!(:post_two) do
2477
+ person.posts.create(title: "OMG I has associations")
2478
+ end
2479
+
2480
+ context "when providing an id" do
2481
+
2482
+ context "when the id matches" do
2483
+
2484
+ let(:post) do
2485
+ person.posts.find(post_one.id)
2486
+ end
2487
+
2488
+ it "returns the matching document" do
2489
+ expect(post).to eq(post_one)
2490
+ end
2491
+ end
2492
+
2493
+ context "when the id matches but is not scoped to the association" do
2494
+
2495
+ let(:post) do
2496
+ Post.create(title: "Unscoped")
2497
+ end
2498
+
2499
+ it "raises an error" do
2500
+ expect {
2501
+ person.posts.find(post.id)
2502
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
2503
+ end
2504
+ end
2505
+
2506
+ context "when the id does not match" do
2507
+
2508
+ context "when config set to raise error" do
2509
+
2510
+ before do
2511
+ Mongoid.raise_not_found_error = true
2512
+ end
2513
+
2514
+ it "raises an error" do
2515
+ expect {
2516
+ person.posts.find(BSON::ObjectId.new)
2517
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
2518
+ end
2519
+ end
2520
+
2521
+ context "when config set not to raise error" do
2522
+
2523
+ let(:post) do
2524
+ person.posts.find(BSON::ObjectId.new)
2525
+ end
2526
+
2527
+ before do
2528
+ Mongoid.raise_not_found_error = false
2529
+ end
2530
+
2531
+ after do
2532
+ Mongoid.raise_not_found_error = true
2533
+ end
2534
+
2535
+ it "returns nil" do
2536
+ expect(post).to be_nil
2537
+ end
2538
+ end
2539
+ end
2540
+ end
2541
+
2542
+ context "when providing an array of ids" do
2543
+
2544
+ context "when the ids match" do
2545
+
2546
+ let(:posts) do
2547
+ person.posts.find([ post_one.id, post_two.id ])
2548
+ end
2549
+
2550
+ it "returns the matching documents" do
2551
+ expect(posts).to eq([ post_one, post_two ])
2552
+ end
2553
+ end
2554
+
2555
+ context "when the ids do not match" do
2556
+
2557
+ context "when config set to raise error" do
2558
+
2559
+ before do
2560
+ Mongoid.raise_not_found_error = true
2561
+ end
2562
+
2563
+ it "raises an error" do
2564
+ expect {
2565
+ person.posts.find([ BSON::ObjectId.new ])
2566
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
2567
+ end
2568
+ end
2569
+
2570
+ context "when config set not to raise error" do
2571
+
2572
+ let(:posts) do
2573
+ person.posts.find([ BSON::ObjectId.new ])
2574
+ end
2575
+
2576
+ before do
2577
+ Mongoid.raise_not_found_error = false
2578
+ end
2579
+
2580
+ after do
2581
+ Mongoid.raise_not_found_error = true
2582
+ end
2583
+
2584
+ it "returns an empty array" do
2585
+ expect(posts).to be_empty
2586
+ end
2587
+ end
2588
+ end
2589
+ end
2590
+ end
2591
+
2592
+ context "when the association is polymorphic" do
2593
+
2594
+ let(:movie) do
2595
+ Movie.create
2596
+ end
2597
+
2598
+ let!(:rating_one) do
2599
+ movie.ratings.create(value: 1)
2600
+ end
2601
+
2602
+ let!(:rating_two) do
2603
+ movie.ratings.create(value: 5)
2604
+ end
2605
+
2606
+ context "when providing an id" do
2607
+
2608
+ context "when the id matches" do
2609
+
2610
+ let(:rating) do
2611
+ movie.ratings.find(rating_one.id)
2612
+ end
2613
+
2614
+ it "returns the matching document" do
2615
+ expect(rating).to eq(rating_one)
2616
+ end
2617
+ end
2618
+
2619
+ context "when the id does not match" do
2620
+
2621
+ context "when config set to raise error" do
2622
+
2623
+ before do
2624
+ Mongoid.raise_not_found_error = true
2625
+ end
2626
+
2627
+ it "raises an error" do
2628
+ expect {
2629
+ movie.ratings.find(BSON::ObjectId.new)
2630
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
2631
+ end
2632
+ end
2633
+
2634
+ context "when config set not to raise error" do
2635
+
2636
+ let(:rating) do
2637
+ movie.ratings.find(BSON::ObjectId.new)
2638
+ end
2639
+
2640
+ before do
2641
+ Mongoid.raise_not_found_error = false
2642
+ end
2643
+
2644
+ after do
2645
+ Mongoid.raise_not_found_error = true
2646
+ end
2647
+
2648
+ it "returns nil" do
2649
+ expect(rating).to be_nil
2650
+ end
2651
+ end
2652
+ end
2653
+ end
2654
+
2655
+ context "when providing an array of ids" do
2656
+
2657
+ context "when the ids match" do
2658
+
2659
+ let(:ratings) do
2660
+ movie.ratings.find([ rating_one.id, rating_two.id ])
2661
+ end
2662
+
2663
+ it "returns the first matching document" do
2664
+ expect(ratings).to include(rating_one)
2665
+ end
2666
+
2667
+ it "returns the second matching document" do
2668
+ expect(ratings).to include(rating_two)
2669
+ end
2670
+
2671
+ it "returns the correct number of documents" do
2672
+ expect(ratings.size).to eq(2)
2673
+ end
2674
+ end
2675
+
2676
+ context "when the ids do not match" do
2677
+
2678
+ context "when config set to raise error" do
2679
+
2680
+ before do
2681
+ Mongoid.raise_not_found_error = true
2682
+ end
2683
+
2684
+ it "raises an error" do
2685
+ expect {
2686
+ movie.ratings.find([ BSON::ObjectId.new ])
2687
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
2688
+ end
2689
+ end
2690
+
2691
+ context "when config set not to raise error" do
2692
+
2693
+ let(:ratings) do
2694
+ movie.ratings.find([ BSON::ObjectId.new ])
2695
+ end
2696
+
2697
+ before do
2698
+ Mongoid.raise_not_found_error = false
2699
+ end
2700
+
2701
+ after do
2702
+ Mongoid.raise_not_found_error = true
2703
+ end
2704
+
2705
+ it "returns an empty array" do
2706
+ expect(ratings).to be_empty
2707
+ end
2708
+ end
2709
+ end
2710
+ end
2711
+ end
2712
+ end
2713
+
2714
+ describe "#find_or_create_by" do
2715
+
2716
+ context "when the association is not polymorphic" do
2717
+
2718
+ let(:person) do
2719
+ Person.create
2720
+ end
2721
+
2722
+ let!(:post) do
2723
+ person.posts.create(title: "Testing")
2724
+ end
2725
+
2726
+ context "when the document exists" do
2727
+
2728
+ let(:found) do
2729
+ person.posts.find_or_create_by(title: "Testing")
2730
+ end
2731
+
2732
+ it "returns the document" do
2733
+ expect(found).to eq(post)
2734
+ end
2735
+
2736
+ it "keeps the document in the association" do
2737
+ expect(found.person).to eq(person)
2738
+ end
2739
+ end
2740
+
2741
+ context "when the document does not exist" do
2742
+
2743
+ context "when there is no criteria attached" do
2744
+
2745
+ let(:found) do
2746
+ person.posts.find_or_create_by(title: "Test") do |post|
2747
+ post.content = "The Content"
2748
+ end
2749
+ end
2750
+
2751
+ it "sets the new document attributes" do
2752
+ expect(found.title).to eq("Test")
2753
+ end
2754
+
2755
+ it "returns a newly persisted document" do
2756
+ expect(found).to be_persisted
2757
+ end
2758
+
2759
+ it "calls the passed block" do
2760
+ expect(found.content).to eq("The Content")
2761
+ end
2762
+
2763
+ it "keeps the document in the association" do
2764
+ expect(found.person).to eq(person)
2765
+ end
2766
+ end
2767
+
2768
+ context "when a criteria is attached" do
2769
+
2770
+ let(:found) do
2771
+ person.posts.recent.find_or_create_by(title: "Test")
2772
+ end
2773
+
2774
+ it "sets the new document attributes" do
2775
+ expect(found.title).to eq("Test")
2776
+ end
2777
+
2778
+ it "returns a newly persisted document" do
2779
+ expect(found).to be_persisted
2780
+ end
2781
+
2782
+ it "keeps the document in the association" do
2783
+ expect(found.person).to eq(person)
2784
+ end
2785
+ end
2786
+ end
2787
+ end
2788
+
2789
+ context "when the association is polymorphic" do
2790
+
2791
+ let(:movie) do
2792
+ Movie.create
2793
+ end
2794
+
2795
+ let!(:rating) do
2796
+ movie.ratings.create(value: 1)
2797
+ end
2798
+
2799
+ context "when the document exists" do
2800
+
2801
+ let(:found) do
2802
+ movie.ratings.find_or_create_by(value: 1)
2803
+ end
2804
+
2805
+ it "returns the document" do
2806
+ expect(found).to eq(rating)
2807
+ end
2808
+
2809
+ it "keeps the document in the association" do
2810
+ expect(found.ratable).to eq(movie)
2811
+ end
2812
+ end
2813
+
2814
+ context "when the document does not exist" do
2815
+
2816
+ let(:found) do
2817
+ movie.ratings.find_or_create_by(value: 3)
2818
+ end
2819
+
2820
+ it "sets the new document attributes" do
2821
+ expect(found.value).to eq(3)
2822
+ end
2823
+
2824
+ it "returns a newly persisted document" do
2825
+ expect(found).to be_persisted
2826
+ end
2827
+
2828
+ it "keeps the document in the association" do
2829
+ expect(found.ratable).to eq(movie)
2830
+ end
2831
+ end
2832
+ end
2833
+ end
2834
+
2835
+ describe "#find_or_create_by!" do
2836
+
2837
+ context "when the association is not polymorphic" do
2838
+
2839
+ let(:person) do
2840
+ Person.create
2841
+ end
2842
+
2843
+ let!(:post) do
2844
+ person.posts.create(title: "Testing")
2845
+ end
2846
+
2847
+ context "when the document exists" do
2848
+
2849
+ let(:found) do
2850
+ person.posts.find_or_create_by!(title: "Testing")
2851
+ end
2852
+
2853
+ it "returns the document" do
2854
+ expect(found).to eq(post)
2855
+ end
2856
+
2857
+ it "keeps the document in the association" do
2858
+ expect(found.person).to eq(person)
2859
+ end
2860
+ end
2861
+
2862
+ context "when the document does not exist" do
2863
+
2864
+ context "when there is no criteria attached" do
2865
+
2866
+ let(:found) do
2867
+ person.posts.find_or_create_by!(title: "Test") do |post|
2868
+ post.content = "The Content"
2869
+ end
2870
+ end
2871
+
2872
+ it "sets the new document attributes" do
2873
+ expect(found.title).to eq("Test")
2874
+ end
2875
+
2876
+ it "returns a newly persisted document" do
2877
+ expect(found).to be_persisted
2878
+ end
2879
+
2880
+ it "calls the passed block" do
2881
+ expect(found.content).to eq("The Content")
2882
+ end
2883
+
2884
+ it "keeps the document in the association" do
2885
+ expect(found.person).to eq(person)
2886
+ end
2887
+ end
2888
+
2889
+ context "when a criteria is attached" do
2890
+
2891
+ let(:found) do
2892
+ person.posts.recent.find_or_create_by!(title: "Test")
2893
+ end
2894
+
2895
+ it "sets the new document attributes" do
2896
+ expect(found.title).to eq("Test")
2897
+ end
2898
+
2899
+ it "returns a newly persisted document" do
2900
+ expect(found).to be_persisted
2901
+ end
2902
+
2903
+ it "keeps the document in the association" do
2904
+ expect(found.person).to eq(person)
2905
+ end
2906
+ end
2907
+ end
2908
+ end
2909
+
2910
+ context "when the association is polymorphic" do
2911
+
2912
+ let(:movie) do
2913
+ Movie.create
2914
+ end
2915
+
2916
+ let!(:rating) do
2917
+ movie.ratings.create(value: 1)
2918
+ end
2919
+
2920
+ context "when the document exists" do
2921
+
2922
+ let(:found) do
2923
+ movie.ratings.find_or_create_by!(value: 1)
2924
+ end
2925
+
2926
+ it "returns the document" do
2927
+ expect(found).to eq(rating)
2928
+ end
2929
+
2930
+ it "keeps the document in the association" do
2931
+ expect(found.ratable).to eq(movie)
2932
+ end
2933
+ end
2934
+
2935
+ context "when the document does not exist" do
2936
+
2937
+ let(:found) do
2938
+ movie.ratings.find_or_create_by!(value: 3)
2939
+ end
2940
+
2941
+ it "sets the new document attributes" do
2942
+ expect(found.value).to eq(3)
2943
+ end
2944
+
2945
+ it "returns a newly persisted document" do
2946
+ expect(found).to be_persisted
2947
+ end
2948
+
2949
+ it "keeps the document in the association" do
2950
+ expect(found.ratable).to eq(movie)
2951
+ end
2952
+
2953
+ context "when validation fails" do
2954
+
2955
+ it "raises an error" do
2956
+ expect {
2957
+ movie.comments.find_or_create_by!(title: "")
2958
+ }.to raise_error(Mongoid::Errors::Validations)
2959
+ end
2960
+ end
2961
+ end
2962
+ end
2963
+ end
2964
+
2965
+ describe "#find_or_initialize_by" do
2966
+
2967
+ context "when the association is not polymorphic" do
2968
+
2969
+ let(:person) do
2970
+ Person.create
2971
+ end
2972
+
2973
+ let!(:post) do
2974
+ person.posts.create(title: "Testing")
2975
+ end
2976
+
2977
+ context "when the document exists" do
2978
+
2979
+ let(:found) do
2980
+ person.posts.find_or_initialize_by(title: "Testing")
2981
+ end
2982
+
2983
+ it "returns the document" do
2984
+ expect(found).to eq(post)
2985
+ end
2986
+ end
2987
+
2988
+ context "when the document does not exist" do
2989
+
2990
+ let(:found) do
2991
+ person.posts.find_or_initialize_by(title: "Test") do |post|
2992
+ post.content = "The Content"
2993
+ end
2994
+ end
2995
+
2996
+ it "sets the new document attributes" do
2997
+ expect(found.title).to eq("Test")
2998
+ end
2999
+
3000
+ it "returns a non persisted document" do
3001
+ expect(found).to_not be_persisted
3002
+ end
3003
+
3004
+ it "calls the passed block" do
3005
+ expect(found.content).to eq("The Content")
3006
+ end
3007
+ end
3008
+ end
3009
+
3010
+ context "when the association is polymorphic" do
3011
+
3012
+ let(:movie) do
3013
+ Movie.create
3014
+ end
3015
+
3016
+ let!(:rating) do
3017
+ movie.ratings.create(value: 1)
3018
+ end
3019
+
3020
+ context "when the document exists" do
3021
+
3022
+ let(:found) do
3023
+ movie.ratings.find_or_initialize_by(value: 1)
3024
+ end
3025
+
3026
+ it "returns the document" do
3027
+ expect(found).to eq(rating)
3028
+ end
3029
+ end
3030
+
3031
+ context "when the document does not exist" do
3032
+
3033
+ let(:found) do
3034
+ movie.ratings.find_or_initialize_by(value: 3)
3035
+ end
3036
+
3037
+ it "sets the new document attributes" do
3038
+ expect(found.value).to eq(3)
3039
+ end
3040
+
3041
+ it "returns a non persisted document" do
3042
+ expect(found).to_not be_persisted
3043
+ end
3044
+ end
3045
+ end
3046
+ end
3047
+
3048
+ describe "#initialize" do
3049
+
3050
+ context "when an illegal mixed association exists" do
3051
+
3052
+ let(:post) do
3053
+ Post.new
3054
+ end
3055
+
3056
+ it "raises an error" do
3057
+ expect {
3058
+ post.videos
3059
+ }.to raise_error(Mongoid::Errors::MixedRelations)
3060
+ end
3061
+ end
3062
+
3063
+ context "when a cyclic association exists" do
3064
+
3065
+ let(:post) do
3066
+ Post.new
3067
+ end
3068
+
3069
+ it "does not raise an error" do
3070
+ expect(post.roles).to be_empty
3071
+ end
3072
+ end
3073
+ end
3074
+
3075
+ describe "#last" do
3076
+
3077
+ let(:person) do
3078
+ Person.create!
3079
+ end
3080
+
3081
+ let!(:persisted_post) do
3082
+ person.posts.create!
3083
+ end
3084
+
3085
+ context "when a new document is added" do
3086
+
3087
+ let!(:new_post) do
3088
+ person.posts.new
3089
+ end
3090
+
3091
+ context "when the target is subsequently loaded" do
3092
+
3093
+ before do
3094
+ person.posts.entries
3095
+ end
3096
+
3097
+ it "returns the expected last document" do
3098
+ expect(person.posts.last).to eq(new_post)
3099
+ end
3100
+ end
3101
+ end
3102
+ end
3103
+
3104
+ describe "#max" do
3105
+
3106
+ let(:person) do
3107
+ Person.create
3108
+ end
3109
+
3110
+ let(:post_one) do
3111
+ Post.create(rating: 5)
3112
+ end
3113
+
3114
+ let(:post_two) do
3115
+ Post.create(rating: 10)
3116
+ end
3117
+
3118
+ before do
3119
+ person.posts.push(post_one, post_two)
3120
+ end
3121
+
3122
+ let(:max) do
3123
+ person.posts.max do |a,b|
3124
+ a.rating <=> b.rating
3125
+ end
3126
+ end
3127
+
3128
+ it "returns the document with the max value of the supplied field" do
3129
+ expect(max).to eq(post_two)
3130
+ end
3131
+ end
3132
+
3133
+ describe "#max_by" do
3134
+
3135
+ let(:person) do
3136
+ Person.create
3137
+ end
3138
+
3139
+ let(:post_one) do
3140
+ Post.create(rating: 5)
3141
+ end
3142
+
3143
+ let(:post_two) do
3144
+ Post.create(rating: 10)
3145
+ end
3146
+
3147
+ before do
3148
+ person.posts.push(post_one, post_two)
3149
+ end
3150
+
3151
+ let(:max) do
3152
+ person.posts.max_by(&:rating)
3153
+ end
3154
+
3155
+ it "returns the document with the max value of the supplied field" do
3156
+ expect(max).to eq(post_two)
3157
+ end
3158
+ end
3159
+
3160
+ describe "#method_missing" do
3161
+
3162
+ let!(:person) do
3163
+ Person.create
3164
+ end
3165
+
3166
+ let!(:post_one) do
3167
+ person.posts.create(title: "First", content: "Posting")
3168
+ end
3169
+
3170
+ let!(:post_two) do
3171
+ person.posts.create(title: "Second", content: "Testing")
3172
+ end
3173
+
3174
+ context "when providing a single criteria" do
3175
+
3176
+ let(:posts) do
3177
+ person.posts.where(title: "First")
3178
+ end
3179
+
3180
+ it "applies the criteria to the documents" do
3181
+ expect(posts).to eq([ post_one ])
3182
+ end
3183
+
3184
+ context 'when providing a collation' do
3185
+ min_server_version '3.4'
3186
+
3187
+ let(:posts) do
3188
+ person.posts.where(title: "FIRST").collation(locale: 'en_US', strength: 2)
3189
+ end
3190
+
3191
+ it "applies the collation option to the query" do
3192
+ expect(posts).to eq([ post_one ])
3193
+ end
3194
+ end
3195
+ end
3196
+
3197
+ context "when providing a criteria class method" do
3198
+
3199
+ let(:posts) do
3200
+ person.posts.posting
3201
+ end
3202
+
3203
+ it "applies the criteria to the documents" do
3204
+ expect(posts).to eq([ post_one ])
3205
+ end
3206
+ end
3207
+
3208
+ context "when chaining criteria" do
3209
+
3210
+ let(:posts) do
3211
+ person.posts.posting.where(:title.in => [ "First" ])
3212
+ end
3213
+
3214
+ it "applies the criteria to the documents" do
3215
+ expect(posts).to eq([ post_one ])
3216
+ end
3217
+ end
3218
+
3219
+ context "when delegating methods" do
3220
+
3221
+ describe "#distinct" do
3222
+
3223
+ let(:values) do
3224
+ person.posts.distinct(:title)
3225
+ end
3226
+
3227
+ it "returns the distinct values for the fields" do
3228
+ expect(values).to include("First")
3229
+ expect(values).to include("Second")
3230
+ end
3231
+ end
3232
+ end
3233
+ end
3234
+
3235
+ describe "#min" do
3236
+
3237
+ let(:person) do
3238
+ Person.create
3239
+ end
3240
+
3241
+ let(:post_one) do
3242
+ Post.create(rating: 5)
3243
+ end
3244
+
3245
+ let(:post_two) do
3246
+ Post.create(rating: 10)
3247
+ end
3248
+
3249
+ before do
3250
+ person.posts.push(post_one, post_two)
3251
+ end
3252
+
3253
+ let(:min) do
3254
+ person.posts.min do |a, b|
3255
+ a.rating <=> b.rating
3256
+ end
3257
+ end
3258
+
3259
+ it "returns the min value of the supplied field" do
3260
+ expect(min).to eq(post_one)
3261
+ end
3262
+ end
3263
+
3264
+ describe "#min_by" do
3265
+
3266
+ let(:person) do
3267
+ Person.create
3268
+ end
3269
+
3270
+ let(:post_one) do
3271
+ Post.create(rating: 5)
3272
+ end
3273
+
3274
+ let(:post_two) do
3275
+ Post.create(rating: 10)
3276
+ end
3277
+
3278
+ before do
3279
+ person.posts.push(post_one, post_two)
3280
+ end
3281
+
3282
+ let(:min) do
3283
+ person.posts.min_by(&:rating)
3284
+ end
3285
+
3286
+ it "returns the min value of the supplied field" do
3287
+ expect(min).to eq(post_one)
3288
+ end
3289
+ end
3290
+
3291
+ describe "#nullify_all" do
3292
+
3293
+ context "when the inverse has not been loaded" do
3294
+
3295
+ let(:person) do
3296
+ Person.create
3297
+ end
3298
+
3299
+ let!(:post_one) do
3300
+ person.posts.create(title: "One")
3301
+ end
3302
+
3303
+ let!(:post_two) do
3304
+ person.posts.create(title: "Two")
3305
+ end
3306
+
3307
+ let(:from_db) do
3308
+ Person.first
3309
+ end
3310
+
3311
+ before do
3312
+ from_db.posts.nullify_all
3313
+ end
3314
+
3315
+ it "loads the targets before nullifying" do
3316
+ expect(from_db.posts).to be_empty
3317
+ end
3318
+
3319
+ it "persists the base nullifications" do
3320
+ expect(Person.first.posts).to be_empty
3321
+ end
3322
+
3323
+ it "persists the inverse nullifications" do
3324
+ Post.all.each do |post|
3325
+ expect(post.person).to be_nil
3326
+ end
3327
+ end
3328
+ end
3329
+
3330
+ context "when the association is not polymorphic" do
3331
+
3332
+ let(:person) do
3333
+ Person.create
3334
+ end
3335
+
3336
+ let!(:post_one) do
3337
+ person.posts.create(title: "One")
3338
+ end
3339
+
3340
+ let!(:post_two) do
3341
+ person.posts.create(title: "Two")
3342
+ end
3343
+
3344
+ before do
3345
+ person.posts.nullify_all
3346
+ end
3347
+
3348
+ it "removes all the foreign keys from the target" do
3349
+ [ post_one, post_two ].each do |post|
3350
+ expect(post.person_id).to be_nil
3351
+ end
3352
+ end
3353
+
3354
+ it "removes all the references from the target" do
3355
+ [ post_one, post_two ].each do |post|
3356
+ expect(post.person).to be_nil
3357
+ end
3358
+ end
3359
+
3360
+ it "saves the documents" do
3361
+ expect(post_one.reload.person).to be_nil
3362
+ end
3363
+
3364
+ context "when adding a nullified document back to the association" do
3365
+
3366
+ before do
3367
+ person.posts.push(post_one)
3368
+ end
3369
+
3370
+ it "persists the association" do
3371
+ expect(person.posts(true)).to eq([ post_one ])
3372
+ end
3373
+ end
3374
+ end
3375
+
3376
+ context "when the association is polymorphic" do
3377
+
3378
+ let(:movie) do
3379
+ Movie.create(title: "Oldboy")
3380
+ end
3381
+
3382
+ let!(:rating_one) do
3383
+ movie.ratings.create(value: 10)
3384
+ end
3385
+
3386
+ let!(:rating_two) do
3387
+ movie.ratings.create(value: 9)
3388
+ end
3389
+
3390
+ before do
3391
+ movie.ratings.nullify_all
3392
+ end
3393
+
3394
+ it "removes all the foreign keys from the target" do
3395
+ [ rating_one, rating_two ].each do |rating|
3396
+ expect(rating.ratable_id).to be_nil
3397
+ end
3398
+ end
3399
+
3400
+ it "removes all the references from the target" do
3401
+ [ rating_one, rating_two ].each do |rating|
3402
+ expect(rating.ratable).to be_nil
3403
+ end
3404
+ end
3405
+ end
3406
+ end
3407
+
3408
+ describe "#respond_to?" do
3409
+
3410
+ let(:person) do
3411
+ Person.new
3412
+ end
3413
+
3414
+ let(:posts) do
3415
+ person.posts
3416
+ end
3417
+
3418
+ Array.public_instance_methods.each do |method|
3419
+
3420
+ context "when checking #{method}" do
3421
+
3422
+ it "returns true" do
3423
+ expect(posts.respond_to?(method)).to be true
3424
+ end
3425
+ end
3426
+ end
3427
+
3428
+ Mongoid::Association::Referenced::HasMany::Proxy.public_instance_methods.each do |method|
3429
+
3430
+ context "when checking #{method}" do
3431
+
3432
+ it "returns true" do
3433
+ expect(posts.respond_to?(method)).to be true
3434
+ end
3435
+ end
3436
+ end
3437
+
3438
+ Post.scopes.keys.each do |method|
3439
+
3440
+ context "when checking #{method}" do
3441
+
3442
+ it "returns true" do
3443
+ expect(posts.respond_to?(method)).to be true
3444
+ end
3445
+ end
3446
+ end
3447
+ end
3448
+
3449
+ describe "#scoped" do
3450
+
3451
+ let(:person) do
3452
+ Person.new
3453
+ end
3454
+
3455
+ let(:scoped) do
3456
+ person.posts.scoped
3457
+ end
3458
+
3459
+ it "returns the association criteria" do
3460
+ expect(scoped).to be_a(Mongoid::Criteria)
3461
+ end
3462
+
3463
+ it "returns with an empty selector" do
3464
+ expect(scoped.selector).to eq({ "person_id" => person.id })
3465
+ end
3466
+ end
3467
+
3468
+ [ :size, :length ].each do |method|
3469
+
3470
+ describe "##{method}" do
3471
+
3472
+ let(:movie) do
3473
+ Movie.create
3474
+ end
3475
+
3476
+ context "when documents have been persisted" do
3477
+
3478
+ let!(:rating) do
3479
+ movie.ratings.create(value: 1)
3480
+ end
3481
+
3482
+ it "returns 1" do
3483
+ expect(movie.ratings.send(method)).to eq(1)
3484
+ end
3485
+ end
3486
+
3487
+ context "when documents have not been persisted" do
3488
+
3489
+ before do
3490
+ movie.ratings.build(value: 1)
3491
+ movie.ratings.create(value: 2)
3492
+ end
3493
+
3494
+ it "returns the total number of documents" do
3495
+ expect(movie.ratings.send(method)).to eq(2)
3496
+ end
3497
+ end
3498
+ end
3499
+ end
3500
+
3501
+ describe "#unscoped" do
3502
+
3503
+ context "when the association has no default scope" do
3504
+
3505
+ let!(:person) do
3506
+ Person.create
3507
+ end
3508
+
3509
+ let!(:post_one) do
3510
+ person.posts.create(title: "first")
3511
+ end
3512
+
3513
+ let!(:post_two) do
3514
+ Post.create(title: "second")
3515
+ end
3516
+
3517
+ let(:unscoped) do
3518
+ person.posts.unscoped
3519
+ end
3520
+
3521
+ it "returns only the associated documents" do
3522
+ expect(unscoped).to eq([ post_one ])
3523
+ end
3524
+ end
3525
+
3526
+ context "when the association has a default scope" do
3527
+
3528
+ let!(:church) do
3529
+ Church.create
3530
+ end
3531
+
3532
+ let!(:acolyte_one) do
3533
+ church.acolytes.create(name: "first")
3534
+ end
3535
+
3536
+ let!(:acolyte_two) do
3537
+ Acolyte.create(name: "second")
3538
+ end
3539
+
3540
+ let(:unscoped) do
3541
+ church.acolytes.unscoped
3542
+ end
3543
+
3544
+ it "only returns associated documents" do
3545
+ expect(unscoped).to eq([ acolyte_one ])
3546
+ end
3547
+
3548
+ it "removes the default scoping options" do
3549
+ expect(unscoped.options).to eq({})
3550
+ end
3551
+ end
3552
+ end
3553
+
3554
+ context "when the association has an order defined" do
3555
+
3556
+ let(:person) do
3557
+ Person.create
3558
+ end
3559
+
3560
+ let(:post_one) do
3561
+ OrderedPost.create(rating: 10, title: '1')
3562
+ end
3563
+
3564
+ let(:post_two) do
3565
+ OrderedPost.create(rating: 20, title: '2')
3566
+ end
3567
+
3568
+ let(:post_three) do
3569
+ OrderedPost.create(rating: 20, title: '3')
3570
+ end
3571
+
3572
+ before do
3573
+ person.ordered_posts.nullify_all
3574
+ person.ordered_posts.push(post_one, post_two, post_three)
3575
+ end
3576
+
3577
+ it "order documents" do
3578
+ expect(person.ordered_posts(true)).to eq(
3579
+ [post_two, post_three, post_one]
3580
+ )
3581
+ end
3582
+
3583
+ it "chaining order criterias" do
3584
+ expect(person.ordered_posts.order_by(:title.desc).to_a).to eq(
3585
+ [post_three, post_two, post_one]
3586
+ )
3587
+ end
3588
+ end
3589
+
3590
+ context "when reloading the association" do
3591
+
3592
+ let!(:person) do
3593
+ Person.create
3594
+ end
3595
+
3596
+ let!(:post_one) do
3597
+ Post.create(title: "one")
3598
+ end
3599
+
3600
+ let!(:post_two) do
3601
+ Post.create(title: "two")
3602
+ end
3603
+
3604
+ before do
3605
+ person.posts << post_one
3606
+ end
3607
+
3608
+ context "when the association references the same documents" do
3609
+
3610
+ before do
3611
+ Post.collection.find({ _id: post_one.id }).
3612
+ update_one({ "$set" => { title: "reloaded" }})
3613
+ end
3614
+
3615
+ let(:reloaded) do
3616
+ person.posts(true)
3617
+ end
3618
+
3619
+ it "reloads the document from the database" do
3620
+ expect(reloaded.first.title).to eq("reloaded")
3621
+ end
3622
+ end
3623
+
3624
+ context "when the association references different documents" do
3625
+
3626
+ before do
3627
+ person.posts << post_two
3628
+ end
3629
+
3630
+ let(:reloaded) do
3631
+ person.posts(true)
3632
+ end
3633
+
3634
+ it "reloads the first document from the database" do
3635
+ expect(reloaded).to include(post_one)
3636
+ end
3637
+
3638
+ it "reloads the new document from the database" do
3639
+ expect(reloaded).to include(post_two)
3640
+ end
3641
+ end
3642
+ end
3643
+
3644
+ context "when the parent is using integer ids" do
3645
+
3646
+ let(:jar) do
3647
+ Jar.create do |doc|
3648
+ doc._id = 1
3649
+ end
3650
+ end
3651
+
3652
+ it "allows creation of the document" do
3653
+ expect(jar.id).to eq(1)
3654
+ end
3655
+ end
3656
+
3657
+ context "when adding a document" do
3658
+
3659
+ let(:person) do
3660
+ Person.new
3661
+ end
3662
+
3663
+ let(:post_one) do
3664
+ Post.new
3665
+ end
3666
+
3667
+ let(:first_add) do
3668
+ person.posts.push(post_one)
3669
+ end
3670
+
3671
+ context "when chaining a second add" do
3672
+
3673
+ let(:post_two) do
3674
+ Post.new
3675
+ end
3676
+
3677
+ let(:result) do
3678
+ first_add.push(post_two)
3679
+ end
3680
+
3681
+ it "adds both documents" do
3682
+ expect(result).to eq([ post_one, post_two ])
3683
+ end
3684
+ end
3685
+ end
3686
+
3687
+ context "when pushing with a before_add callback" do
3688
+
3689
+ let(:artist) do
3690
+ Artist.new
3691
+ end
3692
+
3693
+ let(:album) do
3694
+ Album.new
3695
+ end
3696
+
3697
+ context "when execution raises no errors" do
3698
+
3699
+ before do
3700
+ artist.albums << album
3701
+ end
3702
+
3703
+ it "it executes method callbacks" do
3704
+ expect(artist.before_add_referenced_called).to be true
3705
+ end
3706
+
3707
+ it "it executes proc callbacks" do
3708
+ expect(album.before_add_called).to be true
3709
+ end
3710
+
3711
+ it "adds the document to the association" do
3712
+ expect(artist.albums).to eq([ album ])
3713
+ end
3714
+ end
3715
+
3716
+ context "when execution raises errors" do
3717
+
3718
+ before do
3719
+ expect(artist).to receive(:before_add_album).and_raise
3720
+ begin; artist.albums << album; rescue; end
3721
+ end
3722
+
3723
+ it "does not add the document to the association" do
3724
+ expect(artist.albums).to be_empty
3725
+ end
3726
+ end
3727
+ end
3728
+
3729
+ context "when pushing with an after_add callback" do
3730
+
3731
+ let(:artist) do
3732
+ Artist.new
3733
+ end
3734
+
3735
+ let(:album) do
3736
+ Album.new
3737
+ end
3738
+
3739
+ it "executes the callback" do
3740
+ artist.albums << album
3741
+ expect(artist.after_add_referenced_called).to be true
3742
+ end
3743
+
3744
+ context "when execution raises errors" do
3745
+
3746
+ before do
3747
+ expect(artist).to receive(:after_add_album).and_raise
3748
+ begin; artist.albums << album; rescue; end
3749
+ end
3750
+
3751
+ it "adds the document to the association" do
3752
+ expect(artist.albums).to eq([ album ])
3753
+ end
3754
+ end
3755
+
3756
+ context 'when the association already exists' do
3757
+
3758
+ before do
3759
+ artist.albums << album
3760
+ album.save
3761
+ artist.save
3762
+ expect(artist).not_to receive(:after_add_album)
3763
+ end
3764
+
3765
+ let(:reloaded_album) do
3766
+ Album.where(artist_id: artist.id).first
3767
+ end
3768
+
3769
+ it 'does not execute the callback when the association is accessed' do
3770
+ expect(reloaded_album.artist.after_add_referenced_called).to be(nil)
3771
+ end
3772
+ end
3773
+ end
3774
+
3775
+ context "when #delete or #clear with before_remove callback" do
3776
+
3777
+ let(:artist) do
3778
+ Artist.new
3779
+ end
3780
+
3781
+ let(:album) do
3782
+ Album.new
3783
+ end
3784
+
3785
+ before do
3786
+ artist.albums << album
3787
+ end
3788
+
3789
+ context "when executing raises no errors" do
3790
+
3791
+ describe "#delete" do
3792
+
3793
+ before do
3794
+ artist.albums.delete album
3795
+ end
3796
+
3797
+ it "executes the callback" do
3798
+ expect(artist.before_remove_referenced_called).to be true
3799
+ end
3800
+
3801
+ it "removes the document from the association" do
3802
+ expect(artist.albums).to be_empty
3803
+ end
3804
+ end
3805
+
3806
+ describe "#clear" do
3807
+
3808
+ before do
3809
+ artist.albums.clear
3810
+ end
3811
+
3812
+ it "executes the callback" do
3813
+ expect(artist.before_remove_referenced_called).to be true
3814
+ end
3815
+
3816
+ it "clears the association" do
3817
+ expect(artist.albums).to be_empty
3818
+ end
3819
+ end
3820
+
3821
+ context "when execution raises errors" do
3822
+
3823
+ before do
3824
+ expect(artist).to receive(:before_remove_album).and_raise
3825
+ end
3826
+
3827
+ describe "#delete" do
3828
+
3829
+ before do
3830
+ begin; artist.albums.delete(album); rescue; end
3831
+ end
3832
+
3833
+ it "does not remove the document from the association" do
3834
+ expect(artist.albums).to eq([ album ])
3835
+ end
3836
+ end
3837
+
3838
+ describe "#clear" do
3839
+
3840
+ before do
3841
+ begin; artist.albums.clear; rescue; end
3842
+ end
3843
+
3844
+ it "does not clear the association" do
3845
+ expect(artist.albums).to eq([ album ])
3846
+ end
3847
+ end
3848
+ end
3849
+ end
3850
+ end
3851
+
3852
+ context "when #delete or #clear with after_remove callback" do
3853
+
3854
+ let(:artist) do
3855
+ Artist.new
3856
+ end
3857
+
3858
+ let(:album) do
3859
+ Album.new
3860
+ end
3861
+
3862
+ before do
3863
+ artist.albums << album
3864
+ end
3865
+
3866
+ context "without errors" do
3867
+
3868
+ describe "#delete" do
3869
+
3870
+ before do
3871
+ artist.albums.delete album
3872
+ end
3873
+
3874
+ it "executes the callback" do
3875
+ expect(artist.after_remove_referenced_called).to be true
3876
+ end
3877
+ end
3878
+
3879
+ describe "#clear" do
3880
+
3881
+ before do
3882
+ artist.albums.clear
3883
+ end
3884
+
3885
+ it "executes the callback" do
3886
+ artist.albums.clear
3887
+ expect(artist.after_remove_referenced_called).to be true
3888
+ end
3889
+ end
3890
+ end
3891
+
3892
+ context "when errors are raised" do
3893
+
3894
+ before do
3895
+ expect(artist).to receive(:after_remove_album).and_raise
3896
+ end
3897
+
3898
+ describe "#delete" do
3899
+
3900
+ before do
3901
+ begin; artist.albums.delete(album); rescue; end
3902
+ end
3903
+
3904
+ it "removes the documents from the association" do
3905
+ expect(artist.albums).to be_empty
3906
+ end
3907
+ end
3908
+
3909
+ describe "#clear" do
3910
+
3911
+ before do
3912
+ begin; artist.albums.clear; rescue; end
3913
+ end
3914
+
3915
+ it "removes the documents from the association" do
3916
+ expect(artist.albums).to be_empty
3917
+ end
3918
+ end
3919
+ end
3920
+ end
3921
+
3922
+ context "when executing a criteria call on an ordered association" do
3923
+
3924
+ let(:person) do
3925
+ Person.create
3926
+ end
3927
+
3928
+ let!(:post_one) do
3929
+ person.ordered_posts.create(rating: 1)
3930
+ end
3931
+
3932
+ let!(:post_two) do
3933
+ person.ordered_posts.create(rating: 5)
3934
+ end
3935
+
3936
+ let(:criteria) do
3937
+ person.ordered_posts.only(:_id, :rating)
3938
+ end
3939
+
3940
+ it "does not drop the ordering" do
3941
+ expect(criteria).to eq([ post_two, post_one ])
3942
+ end
3943
+ end
3944
+
3945
+ context "when accessing a scope named open" do
3946
+
3947
+ let(:person) do
3948
+ Person.create
3949
+ end
3950
+
3951
+ let!(:post) do
3952
+ person.posts.create(title: "open")
3953
+ end
3954
+
3955
+ it "returns the appropriate documents" do
3956
+ expect(person.posts.open).to eq([ post ])
3957
+ end
3958
+ end
3959
+
3960
+ context "when accessing a association named parent" do
3961
+
3962
+ let!(:parent) do
3963
+ Odd.create(name: "odd parent")
3964
+ end
3965
+
3966
+ let(:child) do
3967
+ Even.create(parent_id: parent.id, name: "original even child")
3968
+ end
3969
+
3970
+ it "updates the child after accessing the parent" do
3971
+ # Access parent association on the child to make sure it is loaded
3972
+ child.parent
3973
+
3974
+ new_child_name = "updated even child"
3975
+
3976
+ child.name = new_child_name
3977
+ child.save!
3978
+
3979
+ reloaded = Even.find(child.id)
3980
+ expect(reloaded.name).to eq(new_child_name)
3981
+ end
3982
+ end
3983
+
3984
+ context 'when a document has referenced and embedded associations' do
3985
+
3986
+ let(:agent) do
3987
+ Agent.new
3988
+ end
3989
+
3990
+ let(:basic) do
3991
+ Basic.new
3992
+ end
3993
+
3994
+ let(:address) do
3995
+ Address.new
3996
+ end
3997
+
3998
+ before do
3999
+ agent.basics << basic
4000
+ agent.address = address
4001
+ end
4002
+
4003
+ it 'saves the document correctly' do
4004
+ expect(agent.save).to be(true)
4005
+ end
4006
+ end
4007
+
4008
+ context 'when the two models use the same name to refer to the association' do
4009
+
4010
+ let(:agent) do
4011
+ Agent.new
4012
+ end
4013
+
4014
+ let(:band) do
4015
+ Band.new
4016
+ end
4017
+
4018
+ before do
4019
+ agent.same_name = band
4020
+ agent.save
4021
+ band.save
4022
+ band.reload
4023
+ end
4024
+
4025
+ it 'constructs the correct criteria' do
4026
+ expect(band.same_name).to eq([agent])
4027
+ end
4028
+ end
4029
+ end