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,57 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ require "spec_helper"
5
+
6
+ describe Mongoid::Association::Embedded::EmbedsMany::Binding do
7
+
8
+ let(:person) do
9
+ Person.new
10
+ end
11
+
12
+ let(:address) do
13
+ Address.new
14
+ end
15
+
16
+ let(:target) do
17
+ [ address ]
18
+ end
19
+
20
+ let(:association) do
21
+ Person.relations["addresses"]
22
+ end
23
+
24
+ describe "#bind_one" do
25
+
26
+ let(:binding) do
27
+ described_class.new(person, target, association)
28
+ end
29
+
30
+ context "when the document is bindable" do
31
+
32
+ let(:address_two) do
33
+ Address.new
34
+ end
35
+
36
+ before do
37
+ binding.bind_one(address_two)
38
+ end
39
+
40
+ it "parentizes the document" do
41
+ expect(address_two._parent).to eq(person)
42
+ end
43
+
44
+ it "sets the inverse relation" do
45
+ expect(address_two.addressable).to eq(person)
46
+ end
47
+ end
48
+
49
+ context "when the document is not bindable" do
50
+
51
+ it "does nothing" do
52
+ expect(person.addresses).to receive(:<<).never
53
+ binding.bind_one(address)
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ require "spec_helper"
5
+
6
+ describe Mongoid::Association::Embedded::EmbedsMany::Buildable do
7
+
8
+ let(:base) do
9
+ double
10
+ end
11
+
12
+ let(:options) do
13
+ { }
14
+ end
15
+
16
+ describe "#build" do
17
+
18
+ let(:documents) do
19
+ association.build(base, object)
20
+ end
21
+
22
+ let(:association) do
23
+ Mongoid::Association::Embedded::EmbedsMany.new(Person, :addresses, options)
24
+ end
25
+
26
+ context "when passed an array of documents" do
27
+
28
+ let(:object) do
29
+ [ Address.new(city: "London") ]
30
+ end
31
+
32
+ it "returns an array of documents" do
33
+ expect(documents).to eq(object)
34
+ end
35
+ end
36
+
37
+ context "when the array is empty" do
38
+
39
+ let(:object) do
40
+ []
41
+ end
42
+
43
+ it "returns an empty array" do
44
+ expect(documents).to eq(object)
45
+ end
46
+ end
47
+
48
+ context "when passed nil" do
49
+
50
+ let(:object) do
51
+ nil
52
+ end
53
+
54
+ it "returns an empty array" do
55
+ expect(documents).to be_empty
56
+ end
57
+ end
58
+
59
+ context "when no type is in the object" do
60
+
61
+ let(:object) do
62
+ [ { "city" => "London" }, { "city" => "Shanghai" } ]
63
+ end
64
+
65
+ it "returns an array of documents" do
66
+ expect(documents).to be_a_kind_of(Array)
67
+ end
68
+
69
+ it "creates the correct type of documents" do
70
+ expect(documents[0]).to be_a_kind_of(Address)
71
+ end
72
+
73
+ it "sets the object on the documents" do
74
+ expect(documents[0].city).to eq("London")
75
+ expect(documents[1].city).to eq("Shanghai")
76
+ end
77
+ end
78
+
79
+ context "when a type is in the object" do
80
+
81
+ let(:association) do
82
+ Mongoid::Association::Embedded::EmbedsMany.new(Person, :shapes)
83
+ end
84
+
85
+ let(:object) do
86
+ [
87
+ { "_type" => "Circle", "radius" => 100 },
88
+ { "_type" => "Square", "width" => 50 }
89
+ ]
90
+ end
91
+
92
+ it "returns an array of documents" do
93
+ expect(documents).to be_a_kind_of(Array)
94
+ end
95
+
96
+ it "creates the correct type of document" do
97
+ expect(documents[0]).to be_a_kind_of(Circle)
98
+ expect(documents[1]).to be_a_kind_of(Square)
99
+ end
100
+
101
+ it "sets the object on the document" do
102
+ expect(documents[0].radius).to eq(100)
103
+ expect(documents[1].width).to eq(50)
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,4403 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ require "spec_helper"
5
+
6
+ describe Mongoid::Association::Embedded::EmbedsMany::Proxy do
7
+
8
+ [ :<<, :push ].each do |method|
9
+
10
+ describe "##{method}" do
11
+
12
+ context "when the parent is a new record" do
13
+
14
+ let(:person) do
15
+ Person.new
16
+ end
17
+
18
+ let(:address) do
19
+ Address.new
20
+ end
21
+
22
+ let!(:added) do
23
+ person.addresses.send(method, address)
24
+ end
25
+
26
+ it "appends to the target" do
27
+ expect(person.addresses).to eq([ address ])
28
+ end
29
+
30
+ it "sets the base on the inverse relation" do
31
+ expect(address.addressable).to eq(person)
32
+ end
33
+
34
+ it "sets the same instance on the inverse relation" do
35
+ expect(address.addressable).to eql(person)
36
+ end
37
+
38
+ it "does not save the new document" do
39
+ expect(address).to_not be_persisted
40
+ end
41
+
42
+ it "sets the parent on the child" do
43
+ expect(address._parent).to eq(person)
44
+ end
45
+
46
+ it "sets the association metadata on the child" do
47
+ expect(address._association).to_not be_nil
48
+ end
49
+
50
+ it "sets the index on the child" do
51
+ expect(address._index).to eq(0)
52
+ end
53
+
54
+ it "returns the relation" do
55
+ expect(added).to eq(person.addresses)
56
+ end
57
+
58
+ context 'when the child is already related to the parent' do
59
+
60
+ let(:message) do
61
+ Message.new(person: person)
62
+ end
63
+
64
+ before do
65
+ person.messages << message
66
+ end
67
+
68
+ it "appends only once to the target" do
69
+ expect(person.messages).to eq([ message ])
70
+ end
71
+ end
72
+
73
+ context "with a limiting default scope" do
74
+
75
+ context "when the document matches the scope" do
76
+
77
+ let(:active) do
78
+ Appointment.new
79
+ end
80
+
81
+ before do
82
+ person.appointments.send(method, active)
83
+ end
84
+
85
+ it "appends to the target" do
86
+ expect(person.appointments._target).to eq([ active ])
87
+ end
88
+
89
+ it "appends to the _unscoped" do
90
+ expect(person.appointments.send(:_unscoped)).to eq([ active ])
91
+ end
92
+ end
93
+
94
+ context "when the document does not match the scope" do
95
+
96
+ let(:inactive) do
97
+ Appointment.new(active: false)
98
+ end
99
+
100
+ before do
101
+ person.appointments.send(method, inactive)
102
+ end
103
+
104
+ it "doesn't append to the target" do
105
+ expect(person.appointments._target).to_not eq([ inactive ])
106
+ end
107
+
108
+ it "appends to the _unscoped" do
109
+ expect(person.appointments.send(:_unscoped)).to eq([ inactive ])
110
+ end
111
+ end
112
+ end
113
+ end
114
+
115
+ context "when the parent is not a new record" do
116
+
117
+ let(:person) do
118
+ Person.create
119
+ end
120
+
121
+ let(:address) do
122
+ Address.new
123
+ end
124
+
125
+ before do
126
+ person.addresses.send(method, address)
127
+ end
128
+
129
+ it "saves the new document" do
130
+ expect(address).to be_persisted
131
+ end
132
+ end
133
+
134
+ context "when appending more than one document at once" do
135
+
136
+ let(:person) do
137
+ Person.create
138
+ end
139
+
140
+ let(:address_one) do
141
+ Address.new
142
+ end
143
+
144
+ let(:address_two) do
145
+ Address.new
146
+ end
147
+
148
+ let!(:added) do
149
+ person.addresses.send(method, [ address_one, address_two ])
150
+ end
151
+
152
+ it "saves the first document" do
153
+ expect(address_one).to be_persisted
154
+ end
155
+
156
+ it "saves the second document" do
157
+ expect(address_two).to be_persisted
158
+ end
159
+
160
+ it "returns the relation" do
161
+ expect(added).to eq(person.addresses)
162
+ end
163
+ end
164
+
165
+ context "when the parent and child have a cyclic relation" do
166
+
167
+ context "when the parent is a new record" do
168
+
169
+ let(:parent_role) do
170
+ Role.new
171
+ end
172
+
173
+ let(:child_role) do
174
+ Role.new
175
+ end
176
+
177
+ before do
178
+ parent_role.child_roles.send(method, child_role)
179
+ end
180
+
181
+ it "appends to the target" do
182
+ expect(parent_role.child_roles).to eq([ child_role ])
183
+ end
184
+
185
+ it "sets the base on the inverse relation" do
186
+ expect(child_role.parent_role).to eq(parent_role)
187
+ end
188
+
189
+ it "sets the same instance on the inverse relation" do
190
+ expect(child_role.parent_role).to eql(parent_role)
191
+ end
192
+
193
+ it "does not save the new document" do
194
+ expect(child_role).to_not be_persisted
195
+ end
196
+
197
+ it "sets the parent on the child" do
198
+ expect(child_role._parent).to eq(parent_role)
199
+ end
200
+
201
+ it "sets the association metadata on the child" do
202
+ expect(child_role._association).to_not be_nil
203
+ end
204
+
205
+ it "sets the index on the child" do
206
+ expect(child_role._index).to eq(0)
207
+ end
208
+ end
209
+
210
+ context "when the parent is not a new record" do
211
+
212
+ let(:parent_role) do
213
+ Role.create(name: "CEO")
214
+ end
215
+
216
+ let(:child_role) do
217
+ Role.new(name: "COO")
218
+ end
219
+
220
+ before do
221
+ parent_role.child_roles.send(method, child_role)
222
+ end
223
+
224
+ it "saves the new document" do
225
+ expect(child_role).to be_persisted
226
+ end
227
+ end
228
+ end
229
+
230
+ context "when the child has one sided many to many relation" do
231
+ let(:person) do
232
+ Person.create
233
+ end
234
+
235
+ let(:message) do
236
+ Message.new
237
+ end
238
+
239
+ context "assign parent first" do
240
+ before do
241
+ message.person = person
242
+ message.receivers.send(method, person)
243
+ end
244
+
245
+ it "appends to the relation array" do
246
+ expect(message.receivers).to include(person)
247
+ end
248
+ end
249
+
250
+ context "not assign parent" do
251
+ before do
252
+ message.receivers.send(method, person)
253
+ end
254
+
255
+ it "appends to the relation array" do
256
+ expect(message.receivers).to include(person)
257
+ end
258
+ end
259
+ end
260
+ end
261
+ end
262
+
263
+ describe "#=" do
264
+
265
+ context "when the parent is a new record" do
266
+
267
+ let(:person) do
268
+ Person.new
269
+ end
270
+
271
+ let(:address) do
272
+ Address.new
273
+ end
274
+
275
+ before do
276
+ person.addresses = [ address ]
277
+ end
278
+
279
+ it "sets the target of the relation" do
280
+ expect(person.addresses).to eq([ address ])
281
+ end
282
+
283
+ it "sets the _unscoped of the relation" do
284
+ expect(person.addresses.send(:_unscoped)).to eq([ address ])
285
+ end
286
+
287
+ it "sets the base on the inverse relation" do
288
+ expect(address.addressable).to eq(person)
289
+ end
290
+
291
+ it "sets the same instance on the inverse relation" do
292
+ expect(address.addressable).to eql(person)
293
+ end
294
+
295
+ it "does not save the target" do
296
+ expect(address).to_not be_persisted
297
+ end
298
+
299
+ it "sets the parent on the child" do
300
+ expect(address._parent).to eq(person)
301
+ end
302
+
303
+ it "sets the association metadata on the child" do
304
+ expect(address._association).to_not be_nil
305
+ end
306
+
307
+ it "sets the index on the child" do
308
+ expect(address._index).to eq(0)
309
+ end
310
+ end
311
+
312
+ context "when the parent is not a new record" do
313
+
314
+ let(:person) do
315
+ Person.create
316
+ end
317
+
318
+ let(:address) do
319
+ Address.new
320
+ end
321
+
322
+ context "when setting directly" do
323
+
324
+ before do
325
+ person.addresses = [ address ]
326
+ end
327
+
328
+ it "saves the target" do
329
+ expect(address).to be_persisted
330
+ end
331
+ end
332
+
333
+ context "when setting via an overridden method from the parent" do
334
+
335
+ let!(:person) do
336
+ Person.create
337
+ end
338
+
339
+ let!(:address) do
340
+ person.addresses.create(street: "Alt Treptow")
341
+ end
342
+
343
+ let!(:new_address) do
344
+ Address.new(street: "Tempelhofer Damm")
345
+ end
346
+
347
+ before do
348
+ person.update_attributes(set_addresses: [ new_address ])
349
+ end
350
+
351
+ it "overwrites the existing addresses" do
352
+ expect(person.reload.addresses).to eq([ new_address ])
353
+ end
354
+ end
355
+
356
+ context "when setting via the parent attributes" do
357
+
358
+ before do
359
+ person.attributes = { addresses: [ address ] }
360
+ end
361
+
362
+ it "sets the relation" do
363
+ expect(person.addresses).to eq([ address ])
364
+ end
365
+
366
+ it "does not save the target" do
367
+ expect(address).to_not be_persisted
368
+ end
369
+
370
+ context "when setting the relation multiple times" do
371
+
372
+ let(:address_two) do
373
+ Address.new(street: "kudamm")
374
+ end
375
+
376
+ before do
377
+ person.addresses = [ address_two ]
378
+ person.save
379
+ end
380
+
381
+ it "sets the new documents" do
382
+ expect(person.addresses).to eq([ address_two ])
383
+ end
384
+
385
+ it "persits only the new documents" do
386
+ expect(person.reload.addresses).to eq([ address_two ])
387
+ end
388
+ end
389
+ end
390
+ end
391
+
392
+ context "when setting for inherited docs" do
393
+
394
+ context "when the parent collection is already accessed" do
395
+
396
+ before do
397
+ Person.collection
398
+ end
399
+
400
+ context "when setting via the subclass" do
401
+
402
+ let(:doctor) do
403
+ Doctor.new
404
+ end
405
+
406
+ let(:address_one) do
407
+ Address.new(street: "tauentzien")
408
+ end
409
+
410
+ before do
411
+ doctor.addresses = [ address_one ]
412
+ doctor.save
413
+ end
414
+
415
+ it "sets the documents" do
416
+ expect(doctor.addresses).to eq([ address_one ])
417
+ end
418
+
419
+ it "persists the document" do
420
+ expect(doctor.reload.addresses).to eq([ address_one ])
421
+ end
422
+
423
+ context "when setting the relation multiple times" do
424
+
425
+ let(:address_two) do
426
+ Address.new(street: "kudamm")
427
+ end
428
+
429
+ before do
430
+ doctor.addresses = [ address_two ]
431
+ doctor.save
432
+ end
433
+
434
+ it "sets the new documents" do
435
+ expect(doctor.addresses).to eq([ address_two ])
436
+ end
437
+
438
+ it "persits only the new documents" do
439
+ expect(doctor.reload.addresses).to eq([ address_two ])
440
+ end
441
+ end
442
+ end
443
+ end
444
+ end
445
+
446
+ context "when replacing an existing relation" do
447
+
448
+ let(:person) do
449
+ Person.create(addresses: addresses)
450
+ end
451
+
452
+ let(:addresses) do
453
+ [
454
+ Address.new(street: "1st St"),
455
+ Address.new(street: "2nd St")
456
+ ]
457
+ end
458
+
459
+ let(:address) do
460
+ Address.new(street: "3rd St")
461
+ end
462
+
463
+ context "when the replaced relation is different from the existing relation" do
464
+
465
+ before do
466
+ person.addresses = [ address ]
467
+ end
468
+
469
+ it "deletes the old documents" do
470
+ expect(person.reload.addresses).to eq([ address ])
471
+ end
472
+ end
473
+
474
+ context "when the replaced relation is identical to the existing relation" do
475
+
476
+ before do
477
+ person.addresses = addresses
478
+ end
479
+
480
+ it "does nothing" do
481
+ expect(person.reload.addresses).to eq(addresses)
482
+ end
483
+ end
484
+ end
485
+
486
+ context "when the relation has an unusual name" do
487
+
488
+ module MyCompany
489
+ module Model
490
+ class TrackingId
491
+ include Mongoid::Document
492
+ include Mongoid::Timestamps
493
+ store_in collection: "tracking_ids"
494
+ embeds_many \
495
+ :validation_history,
496
+ class_name: "MyCompany::Model::TrackingIdValidationHistory"
497
+ end
498
+
499
+ class TrackingIdValidationHistory
500
+ include Mongoid::Document
501
+ field :old_state, type: String
502
+ field :new_state, type: String
503
+ field :when_changed, type: DateTime
504
+ embedded_in :tracking_id, class_name: "MyCompany::Model::TrackingId"
505
+ end
506
+ end
507
+ end
508
+
509
+ let(:tracking_id) do
510
+ MyCompany::Model::TrackingId.create
511
+ end
512
+
513
+ let(:history) do
514
+ MyCompany::Model::TrackingIdValidationHistory.new(old_state: "Test")
515
+ end
516
+
517
+ before do
518
+ tracking_id.validation_history << history
519
+ end
520
+
521
+ it "allows creation of the embedded document" do
522
+ expect(tracking_id.validation_history.size).to eq(1)
523
+ end
524
+
525
+ it "saves the relation" do
526
+ expect(history).to be_persisted
527
+ end
528
+
529
+ it "remains on reload" do
530
+ expect(tracking_id.reload.validation_history.size).to eq(1)
531
+ end
532
+ end
533
+
534
+ context "when the relation has address in the name" do
535
+
536
+ let(:slave) do
537
+ Slave.new(first_name: "Test")
538
+ end
539
+
540
+ before do
541
+ ActiveSupport::Inflector.inflections do |inflect|
542
+ inflect.singular("address_numbers", "address_number")
543
+ end
544
+ slave.address_numbers << AddressNumber.new(country_code: 1)
545
+ slave.save
546
+ end
547
+
548
+ it "requires an inflection to determine the class" do
549
+ expect(slave.reload.address_numbers.size).to eq(1)
550
+ end
551
+ end
552
+
553
+ context "when setting the entire tree via a hash" do
554
+
555
+ let(:person) do
556
+ Person.create
557
+ end
558
+
559
+ let!(:address_one) do
560
+ person.addresses.create(street: "Tauentzienstr")
561
+ end
562
+
563
+ let!(:address_two) do
564
+ person.addresses.create(street: "Kudamm")
565
+ end
566
+
567
+ let(:attributes) do
568
+ person.as_document.dup
569
+ end
570
+
571
+ context "when the attributes have changed" do
572
+
573
+ before do
574
+ attributes["addresses"][0]["city"] = "Berlin"
575
+ person.update_attributes(attributes)
576
+ end
577
+
578
+ it "sets the new attributes" do
579
+ expect(person.addresses.first.city).to eq("Berlin")
580
+ end
581
+
582
+ it "persists the changes" do
583
+ expect(person.reload.addresses.first.city).to eq("Berlin")
584
+ end
585
+ end
586
+ end
587
+
588
+ context "when setting an embedded sub-document tree via a hash" do
589
+
590
+ let(:person) do
591
+ Person.create
592
+ end
593
+
594
+ let!(:address_one) do
595
+ person.addresses.create(street: "Tauentzienstr")
596
+ end
597
+
598
+ let!(:location_one) do
599
+ person.addresses.first.locations.create(name: "Work")
600
+ end
601
+
602
+ let(:attributes) do
603
+ person.addresses.first.as_document.dup
604
+ end
605
+
606
+ context "when the attributes have changed" do
607
+
608
+ before do
609
+ attributes["city"] = "Berlin"
610
+ attributes["locations"][0]["name"] = "Home"
611
+ person.addresses.first.update_attributes(attributes)
612
+ end
613
+
614
+ it "sets the new attributes on the address" do
615
+ expect(person.addresses.first.city).to eq("Berlin")
616
+ end
617
+
618
+ it "sets the new attributes on the location" do
619
+ expect(person.addresses.first.locations.first.name).to eq("Home")
620
+ end
621
+
622
+ it "persists the changes to the address" do
623
+ expect(person.reload.addresses.first.city).to eq("Berlin")
624
+ end
625
+
626
+ it "persists the changes to the location" do
627
+ expect(person.reload.addresses.first.locations.first.name).to eq("Home")
628
+ end
629
+
630
+ it "does not persist the locations collection to the person document" do
631
+ expect(person.reload[:locations]).to be_nil
632
+ end
633
+ end
634
+ end
635
+
636
+ context "when the parent and child have a cyclic relation" do
637
+
638
+ context "when the parent is a new record" do
639
+
640
+ let(:parent_role) do
641
+ Role.new
642
+ end
643
+
644
+ let(:child_role) do
645
+ Role.new
646
+ end
647
+
648
+ before do
649
+ parent_role.child_roles = [ child_role ]
650
+ end
651
+
652
+ it "sets the target of the relation" do
653
+ expect(parent_role.child_roles).to eq([ child_role ])
654
+ end
655
+
656
+ it "sets the base on the inverse relation" do
657
+ expect(child_role.parent_role).to eq(parent_role)
658
+ end
659
+
660
+ it "sets the same instance on the inverse relation" do
661
+ expect(child_role.parent_role).to eql(parent_role)
662
+ end
663
+
664
+ it "does not save the target" do
665
+ expect(child_role).to_not be_persisted
666
+ end
667
+
668
+ it "sets the parent on the child" do
669
+ expect(child_role._parent).to eq(parent_role)
670
+ end
671
+
672
+ it "sets the association metadata on the child" do
673
+ expect(child_role._association).to_not be_nil
674
+ end
675
+
676
+ it "sets the index on the child" do
677
+ expect(child_role._index).to eq(0)
678
+ end
679
+ end
680
+
681
+ context "when the parent is not a new record" do
682
+
683
+ let(:parent_role) do
684
+ Role.create(name: "CTO")
685
+ end
686
+
687
+ let(:child_role) do
688
+ Role.new
689
+ end
690
+
691
+ before do
692
+ parent_role.child_roles = [ child_role ]
693
+ end
694
+
695
+ it "saves the target" do
696
+ expect(child_role).to be_persisted
697
+ end
698
+ end
699
+ end
700
+ end
701
+
702
+ describe "#= nil" do
703
+
704
+ context "when the relationship is polymorphic" do
705
+
706
+ context "when the parent is a new record" do
707
+
708
+ let(:person) do
709
+ Person.new
710
+ end
711
+
712
+ let(:address) do
713
+ Address.new
714
+ end
715
+
716
+ before do
717
+ person.addresses = [ address ]
718
+ person.addresses = nil
719
+ end
720
+
721
+ it "sets the relation to empty" do
722
+ expect(person.addresses).to be_empty
723
+ end
724
+
725
+ it "sets the unscoped to empty" do
726
+ expect(person.addresses.send(:_unscoped)).to be_empty
727
+ end
728
+
729
+ it "removes the inverse relation" do
730
+ expect(address.addressable).to be_nil
731
+ end
732
+ end
733
+
734
+ context "when the inverse is already nil" do
735
+
736
+ let(:person) do
737
+ Person.new
738
+ end
739
+
740
+ before do
741
+ person.addresses = nil
742
+ end
743
+
744
+ it "sets the relation to empty" do
745
+ expect(person.addresses).to be_empty
746
+ end
747
+ end
748
+
749
+ context "when the parent is persisted" do
750
+
751
+ let(:person) do
752
+ Person.create
753
+ end
754
+
755
+ let(:address) do
756
+ Address.new
757
+ end
758
+
759
+ context "when setting directly" do
760
+
761
+ before do
762
+ person.addresses = [ address ]
763
+ person.addresses = nil
764
+ end
765
+
766
+ it "sets the relation to empty" do
767
+ expect(person.addresses).to be_empty
768
+ end
769
+
770
+ it "sets the relation to empty in the database" do
771
+ expect(person.reload.addresses).to be_empty
772
+ end
773
+
774
+ it "removed the inverse relation" do
775
+ expect(address.addressable).to be_nil
776
+ end
777
+
778
+ it "deletes the child document" do
779
+ expect(address).to be_destroyed
780
+ end
781
+ end
782
+
783
+ context "when setting via attributes" do
784
+
785
+ before do
786
+ person.addresses = [ address ]
787
+ person.attributes = { addresses: nil }
788
+ end
789
+
790
+ it "sets the relation to empty" do
791
+ expect(person.addresses).to be_empty
792
+ end
793
+
794
+ it "deletes the child document" do
795
+ expect(address).to be_destroyed
796
+ end
797
+
798
+ context "when saving the parent" do
799
+
800
+ before do
801
+ person.save
802
+ person.reload
803
+ end
804
+
805
+ it "persists the deletion" do
806
+ expect(person.addresses).to be_empty
807
+ end
808
+ end
809
+ end
810
+ end
811
+
812
+ context "when setting on a reload" do
813
+
814
+ let(:person) do
815
+ Person.create
816
+ end
817
+
818
+ let(:address) do
819
+ Address.new
820
+ end
821
+
822
+ let(:reloaded) do
823
+ person.reload
824
+ end
825
+
826
+ before do
827
+ person.reload.addresses = [ address ]
828
+ person.reload.addresses = nil
829
+ end
830
+
831
+ it "sets the relation to empty" do
832
+ expect(person.addresses).to be_empty
833
+ end
834
+
835
+ it "sets the relation to empty in the database" do
836
+ expect(reloaded.addresses).to be_empty
837
+ end
838
+ end
839
+ end
840
+
841
+ context "when the relationship is cyclic" do
842
+
843
+ context "when the parent is a new record" do
844
+
845
+ let(:parent_role) do
846
+ Role.new
847
+ end
848
+
849
+ let(:child_role) do
850
+ Role.new
851
+ end
852
+
853
+ before do
854
+ parent_role.child_roles = [ child_role ]
855
+ parent_role.child_roles = nil
856
+ end
857
+
858
+ it "sets the relation to empty" do
859
+ expect(parent_role.child_roles).to be_empty
860
+ end
861
+
862
+ it "removes the inverse relation" do
863
+ expect(child_role.parent_role).to be_nil
864
+ end
865
+ end
866
+
867
+ context "when the inverse is already nil" do
868
+
869
+ let(:parent_role) do
870
+ Role.new
871
+ end
872
+
873
+ before do
874
+ parent_role.child_roles = nil
875
+ end
876
+
877
+ it "sets the relation to empty" do
878
+ expect(parent_role.child_roles).to be_empty
879
+ end
880
+ end
881
+
882
+ context "when the documents are not new records" do
883
+
884
+ let(:parent_role) do
885
+ Role.create
886
+ end
887
+
888
+ let(:child_role) do
889
+ Role.new
890
+ end
891
+
892
+ before do
893
+ parent_role.child_roles = [ child_role ]
894
+ parent_role.child_roles = nil
895
+ end
896
+
897
+ it "sets the relation to empty" do
898
+ expect(parent_role.child_roles).to be_empty
899
+ end
900
+
901
+ it "removed the inverse relation" do
902
+ expect(child_role.parent_role).to be_nil
903
+ end
904
+
905
+ it "deletes the child document" do
906
+ expect(child_role).to be_destroyed
907
+ end
908
+ end
909
+ end
910
+ end
911
+
912
+ describe "#as_document" do
913
+
914
+ let!(:person) do
915
+ Person.create
916
+ end
917
+
918
+ context 'when a string is used to access an attribute' do
919
+
920
+ let!(:address) do
921
+ person.addresses.create(street: "one")
922
+ end
923
+
924
+ let(:document) do
925
+ person.reload.addresses.as_document.first
926
+ end
927
+
928
+ it "returns the attribute value" do
929
+ expect(document['street']).to eq('one')
930
+ end
931
+ end
932
+
933
+ context 'when a symbol is used to access an attribute' do
934
+
935
+ let!(:address) do
936
+ person.addresses.create(street: "one")
937
+ end
938
+
939
+ let(:document) do
940
+ person.reload.addresses.as_document.first
941
+ end
942
+
943
+ it "returns the attribute value" do
944
+ expect(document[:street]).to eq('one')
945
+ end
946
+ end
947
+
948
+ context "when the relation has no default scope" do
949
+
950
+ let!(:address) do
951
+ person.addresses.create(street: "one")
952
+ end
953
+
954
+ let(:document) do
955
+ person.reload.addresses.as_document
956
+ end
957
+
958
+ it "returns the documents as an array of hashes" do
959
+ expect(document).to eq([ address.as_document ])
960
+ end
961
+ end
962
+
963
+ context "when the relation has a default scope" do
964
+
965
+ context "when the default scope sorts" do
966
+
967
+ let(:cough) do
968
+ Symptom.new(name: "cough")
969
+ end
970
+
971
+ let(:headache) do
972
+ Symptom.new(name: "headache")
973
+ end
974
+
975
+ before do
976
+ person.symptoms.concat([ headache, cough ])
977
+ end
978
+
979
+ let(:document) do
980
+ person.reload.symptoms.as_document
981
+ end
982
+
983
+ it "returns the unscoped documents as an array of hashes" do
984
+ expect(document).to eq([ headache.as_document, cough.as_document ])
985
+ end
986
+ end
987
+
988
+ context "when the default scope limits" do
989
+
990
+ let(:active) do
991
+ Appointment.new
992
+ end
993
+
994
+ let(:inactive) do
995
+ Appointment.new(active: false)
996
+ end
997
+
998
+ before do
999
+ person.appointments.concat([ active, inactive ])
1000
+ end
1001
+
1002
+ let(:document) do
1003
+ person.reload.appointments.as_document
1004
+ end
1005
+
1006
+ it "returns the unscoped documents as an array of hashes" do
1007
+ expect(document).to eq([ active.as_document, inactive.as_document ])
1008
+ end
1009
+ end
1010
+ end
1011
+ end
1012
+
1013
+ [ :build, :new ].each do |method|
1014
+
1015
+ describe "#build" do
1016
+
1017
+ context "when the relation is not cyclic" do
1018
+
1019
+ let(:person) do
1020
+ Person.new
1021
+ end
1022
+
1023
+ let(:address) do
1024
+ person.addresses.send(method, street: "Bond") do |address|
1025
+ address.state = "CA"
1026
+ end
1027
+ end
1028
+
1029
+ it "appends to the target" do
1030
+ expect(person.addresses).to eq([ address ])
1031
+ end
1032
+
1033
+ it "appends to the unscoped" do
1034
+ expect(person.addresses.send(:_unscoped)).to eq([ address ])
1035
+ end
1036
+
1037
+ it "sets the base on the inverse relation" do
1038
+ expect(address.addressable).to eq(person)
1039
+ end
1040
+
1041
+ it "does not save the new document" do
1042
+ expect(address).to_not be_persisted
1043
+ end
1044
+
1045
+ it "sets the parent on the child" do
1046
+ expect(address._parent).to eq(person)
1047
+ end
1048
+
1049
+ it "sets the association metadata on the child" do
1050
+ expect(address._association).to_not be_nil
1051
+ end
1052
+
1053
+ it "sets the index on the child" do
1054
+ expect(address._index).to eq(0)
1055
+ end
1056
+
1057
+ it "writes to the attributes" do
1058
+ expect(address.street).to eq("Bond")
1059
+ end
1060
+
1061
+ it "calls the passed block" do
1062
+ expect(address.state).to eq("CA")
1063
+ end
1064
+ end
1065
+
1066
+ context "when the relation is cyclic" do
1067
+
1068
+ let(:parent_role) do
1069
+ Role.new
1070
+ end
1071
+
1072
+ let(:child_role) do
1073
+ parent_role.child_roles.send(method, name: "CTO")
1074
+ end
1075
+
1076
+ it "appends to the target" do
1077
+ expect(parent_role.child_roles).to eq([ child_role ])
1078
+ end
1079
+
1080
+ it "sets the base on the inverse relation" do
1081
+ expect(child_role.parent_role).to eq(parent_role)
1082
+ end
1083
+
1084
+ it "does not save the new document" do
1085
+ expect(child_role).to_not be_persisted
1086
+ end
1087
+
1088
+ it "sets the parent on the child" do
1089
+ expect(child_role._parent).to eq(parent_role)
1090
+ end
1091
+
1092
+ it "sets the association metadata on the child" do
1093
+ expect(child_role._association).to_not be_nil
1094
+ end
1095
+
1096
+ it "sets the index on the child" do
1097
+ expect(child_role._index).to eq(0)
1098
+ end
1099
+
1100
+ it "writes to the attributes" do
1101
+ expect(child_role.name).to eq("CTO")
1102
+ end
1103
+ end
1104
+
1105
+ context "when providing nested attributes" do
1106
+
1107
+ let(:person) do
1108
+ Person.create
1109
+ end
1110
+
1111
+ let(:address) do
1112
+ person.addresses.send(
1113
+ method,
1114
+ street: "Bond",
1115
+ locations_attributes: { "1" => { "name" => "Home" } }
1116
+ )
1117
+ end
1118
+
1119
+ context "when followed by a save" do
1120
+
1121
+ before do
1122
+ address.save
1123
+ end
1124
+
1125
+ let(:location) do
1126
+ person.reload.addresses.first.locations.first
1127
+ end
1128
+
1129
+ it "persists the deeply embedded document" do
1130
+ expect(location.name).to eq("Home")
1131
+ end
1132
+ end
1133
+ end
1134
+ end
1135
+ end
1136
+
1137
+ describe "#clear" do
1138
+
1139
+ context "when the parent has been persisted" do
1140
+
1141
+ let(:person) do
1142
+ Person.create
1143
+ end
1144
+
1145
+ context "when the children are persisted" do
1146
+
1147
+ let!(:address) do
1148
+ person.addresses.create(street: "High St")
1149
+ end
1150
+
1151
+ let!(:relation) do
1152
+ person.addresses.clear
1153
+ end
1154
+
1155
+ it "clears out the relation" do
1156
+ expect(person.addresses).to be_empty
1157
+ end
1158
+
1159
+ it "clears the unscoped" do
1160
+ expect(person.addresses.send(:_unscoped)).to be_empty
1161
+ end
1162
+
1163
+ it "marks the documents as deleted" do
1164
+ expect(address).to be_destroyed
1165
+ end
1166
+
1167
+ it "deletes the documents from the db" do
1168
+ expect(person.reload.addresses).to be_empty
1169
+ end
1170
+
1171
+ it "returns the relation" do
1172
+ expect(relation).to be_empty
1173
+ end
1174
+ end
1175
+
1176
+ context "when the children are not persisted" do
1177
+
1178
+ let!(:address) do
1179
+ person.addresses.build(street: "High St")
1180
+ end
1181
+
1182
+ let!(:relation) do
1183
+ person.addresses.clear
1184
+ end
1185
+
1186
+ it "clears out the relation" do
1187
+ expect(person.addresses).to be_empty
1188
+ end
1189
+ end
1190
+ end
1191
+
1192
+ context "when the parent is not persisted" do
1193
+
1194
+ let(:person) do
1195
+ Person.new
1196
+ end
1197
+
1198
+ let!(:address) do
1199
+ person.addresses.build(street: "High St")
1200
+ end
1201
+
1202
+ let!(:relation) do
1203
+ person.addresses.clear
1204
+ end
1205
+
1206
+ it "clears out the relation" do
1207
+ expect(person.addresses).to be_empty
1208
+ end
1209
+ end
1210
+ end
1211
+
1212
+ describe "#concat" do
1213
+
1214
+ context "when the parent is a new record" do
1215
+
1216
+ let(:person) do
1217
+ Person.new
1218
+ end
1219
+
1220
+ let(:address) do
1221
+ Address.new
1222
+ end
1223
+
1224
+ before do
1225
+ person.addresses.concat([ address ])
1226
+ end
1227
+
1228
+ it "appends to the target" do
1229
+ expect(person.addresses).to eq([ address ])
1230
+ end
1231
+
1232
+ it "appends to the unscoped" do
1233
+ expect(person.addresses.send(:_unscoped)).to eq([ address ])
1234
+ end
1235
+
1236
+ it "sets the base on the inverse relation" do
1237
+ expect(address.addressable).to eq(person)
1238
+ end
1239
+
1240
+ it "sets the same instance on the inverse relation" do
1241
+ expect(address.addressable).to eql(person)
1242
+ end
1243
+
1244
+ it "does not save the new document" do
1245
+ expect(address).to_not be_persisted
1246
+ end
1247
+
1248
+ it "sets the parent on the child" do
1249
+ expect(address._parent).to eq(person)
1250
+ end
1251
+
1252
+ it "sets the association metadata on the child" do
1253
+ expect(address._association).to_not be_nil
1254
+ end
1255
+
1256
+ it "sets the index on the child" do
1257
+ expect(address._index).to eq(0)
1258
+ end
1259
+ end
1260
+
1261
+ context "when the parent is not a new record" do
1262
+
1263
+ let(:person) do
1264
+ Person.create
1265
+ end
1266
+
1267
+ let(:address) do
1268
+ Address.new
1269
+ end
1270
+
1271
+ before do
1272
+ person.addresses.concat([ address ])
1273
+ end
1274
+
1275
+ it "saves the new document" do
1276
+ expect(address).to be_persisted
1277
+ end
1278
+ end
1279
+
1280
+ context "when concatenating an empty array" do
1281
+
1282
+ let(:person) do
1283
+ Person.create
1284
+ end
1285
+
1286
+ before do
1287
+ expect(person.addresses).to_not receive(:batch_insert)
1288
+ person.addresses.concat([])
1289
+ end
1290
+
1291
+ it "doesn't update the target" do
1292
+ expect(person.addresses).to be_empty
1293
+ end
1294
+ end
1295
+
1296
+ context "when appending more than one document at once" do
1297
+
1298
+ let(:person) do
1299
+ Person.create
1300
+ end
1301
+
1302
+ let(:address_one) do
1303
+ Address.new
1304
+ end
1305
+
1306
+ let(:address_two) do
1307
+ Address.new
1308
+ end
1309
+
1310
+ before do
1311
+ person.addresses.concat([ address_one, address_two ])
1312
+ end
1313
+
1314
+ it "saves the first document" do
1315
+ expect(address_one).to be_persisted
1316
+ end
1317
+
1318
+ it "saves the second document" do
1319
+ expect(address_two).to be_persisted
1320
+ end
1321
+ end
1322
+
1323
+ context "when the parent and child have a cyclic relation" do
1324
+
1325
+ context "when the parent is a new record" do
1326
+
1327
+ let(:parent_role) do
1328
+ Role.new
1329
+ end
1330
+
1331
+ let(:child_role) do
1332
+ Role.new
1333
+ end
1334
+
1335
+ before do
1336
+ parent_role.child_roles.concat([ child_role ])
1337
+ end
1338
+
1339
+ it "appends to the target" do
1340
+ expect(parent_role.child_roles).to eq([ child_role ])
1341
+ end
1342
+
1343
+ it "sets the base on the inverse relation" do
1344
+ expect(child_role.parent_role).to eq(parent_role)
1345
+ end
1346
+
1347
+ it "sets the same instance on the inverse relation" do
1348
+ expect(child_role.parent_role).to eql(parent_role)
1349
+ end
1350
+
1351
+ it "does not save the new document" do
1352
+ expect(child_role).to_not be_persisted
1353
+ end
1354
+
1355
+ it "sets the parent on the child" do
1356
+ expect(child_role._parent).to eq(parent_role)
1357
+ end
1358
+
1359
+ it "sets the association metadata on the child" do
1360
+ expect(child_role._association).to_not be_nil
1361
+ end
1362
+
1363
+ it "sets the index on the child" do
1364
+ expect(child_role._index).to eq(0)
1365
+ end
1366
+ end
1367
+
1368
+ context "when the parent is not a new record" do
1369
+
1370
+ let(:parent_role) do
1371
+ Role.create(name: "CEO")
1372
+ end
1373
+
1374
+ let(:child_role) do
1375
+ Role.new(name: "COO")
1376
+ end
1377
+
1378
+ before do
1379
+ parent_role.child_roles.concat([ child_role ])
1380
+ end
1381
+
1382
+ it "saves the new document" do
1383
+ expect(child_role).to be_persisted
1384
+ end
1385
+ end
1386
+ end
1387
+ end
1388
+
1389
+ describe "#count" do
1390
+
1391
+ let(:person) do
1392
+ Person.create
1393
+ end
1394
+
1395
+ before do
1396
+ person.addresses.create(street: "Upper")
1397
+ person.addresses.build(street: "Bond")
1398
+ end
1399
+
1400
+ it "returns the number of persisted documents" do
1401
+ expect(person.addresses.count).to eq(1)
1402
+ end
1403
+ end
1404
+
1405
+ describe "#any?" do
1406
+
1407
+ let(:person) do
1408
+ Person.create
1409
+ end
1410
+
1411
+ context "when documents are persisted" do
1412
+ before do
1413
+ person.addresses.create(street: "Upper")
1414
+ end
1415
+
1416
+ it "returns true" do
1417
+ expect(person.addresses.any?).to be true
1418
+ end
1419
+ end
1420
+
1421
+ context "when documents are not persisted" do
1422
+ before do
1423
+ person.addresses.build(street: "Bond")
1424
+ end
1425
+
1426
+ it "returns true" do
1427
+ expect(person.addresses.any?).to be true
1428
+ end
1429
+ end
1430
+
1431
+ context "when documents are not created" do
1432
+ it "returns false" do
1433
+ expect(person.addresses.any?).to be false
1434
+ end
1435
+ end
1436
+ end
1437
+
1438
+ describe "#create" do
1439
+
1440
+ context "when providing multiple attributes" do
1441
+
1442
+ let(:person) do
1443
+ Person.create
1444
+ end
1445
+
1446
+ let!(:addresses) do
1447
+ person.addresses.create([{ street: "Bond" }, { street: "Upper" }])
1448
+ end
1449
+
1450
+ it "creates multiple documents" do
1451
+ expect(addresses.size).to eq(2)
1452
+ end
1453
+
1454
+ it "sets the first attributes" do
1455
+ expect(addresses.first.street).to eq("Bond")
1456
+ end
1457
+
1458
+ it "sets the second attributes" do
1459
+ expect(addresses.last.street).to eq("Upper")
1460
+ end
1461
+
1462
+ it "persists the children" do
1463
+ expect(person.addresses.count).to eq(2)
1464
+ end
1465
+ end
1466
+
1467
+ context "when the relation is not cyclic" do
1468
+
1469
+ let(:person) do
1470
+ Person.create
1471
+ end
1472
+
1473
+ let!(:address) do
1474
+ person.addresses.create(street: "Bond") do |address|
1475
+ address.state = "CA"
1476
+ end
1477
+ end
1478
+
1479
+ it "appends to the target" do
1480
+ expect(person.reload.addresses).to eq([ address ])
1481
+ end
1482
+
1483
+ it "appends to the unscoped" do
1484
+ expect(person.reload.addresses.send(:_unscoped)).to eq([ address ])
1485
+ end
1486
+
1487
+ it "sets the base on the inverse relation" do
1488
+ expect(address.addressable).to eq(person)
1489
+ end
1490
+
1491
+ it "saves the document" do
1492
+ expect(address).to be_persisted
1493
+ end
1494
+
1495
+ it "sets the parent on the child" do
1496
+ expect(address._parent).to eq(person)
1497
+ end
1498
+
1499
+ it "sets the association metadata on the child" do
1500
+ expect(address._association).to_not be_nil
1501
+ end
1502
+
1503
+ it "sets the index on the child" do
1504
+ expect(address._index).to eq(0)
1505
+ end
1506
+
1507
+ it "writes to the attributes" do
1508
+ expect(address.street).to eq("Bond")
1509
+ end
1510
+
1511
+ it "calls the passed block" do
1512
+ expect(address.state).to eq("CA")
1513
+ end
1514
+
1515
+ context "when embedding a multi word named document" do
1516
+
1517
+ let!(:component) do
1518
+ person.address_components.create(street: "Test")
1519
+ end
1520
+
1521
+ it "saves the embedded document" do
1522
+ expect(person.reload.address_components.first).to eq(component)
1523
+ end
1524
+ end
1525
+ end
1526
+
1527
+ context "when the relation is cyclic" do
1528
+
1529
+ let!(:entry) do
1530
+ Entry.create(title: "hi")
1531
+ end
1532
+
1533
+ let!(:child_entry) do
1534
+ entry.child_entries.create(title: "hello")
1535
+ end
1536
+
1537
+ it "creates a new child" do
1538
+ expect(child_entry).to be_persisted
1539
+ end
1540
+ end
1541
+ end
1542
+
1543
+ describe "#create!" do
1544
+
1545
+ let(:person) do
1546
+ Person.create
1547
+ end
1548
+
1549
+ context "when providing multiple attributes" do
1550
+
1551
+ let!(:addresses) do
1552
+ person.addresses.create!([{ street: "Bond" }, { street: "Upper" }])
1553
+ end
1554
+
1555
+ it "creates multiple documents" do
1556
+ expect(addresses.size).to eq(2)
1557
+ end
1558
+
1559
+ it "sets the first attributes" do
1560
+ expect(addresses.first.street).to eq("Bond")
1561
+ end
1562
+
1563
+ it "sets the second attributes" do
1564
+ expect(addresses.last.street).to eq("Upper")
1565
+ end
1566
+
1567
+ it "persists the children" do
1568
+ expect(person.addresses.count).to eq(2)
1569
+ end
1570
+ end
1571
+
1572
+ context "when validation passes" do
1573
+
1574
+ let(:address) do
1575
+ person.addresses.create!(street: "Bond")
1576
+ end
1577
+
1578
+ it "appends to the target" do
1579
+ expect(person.addresses).to eq([ address ])
1580
+ end
1581
+
1582
+ it "appends to the unscoped" do
1583
+ expect(person.addresses.send(:_unscoped)).to eq([ address ])
1584
+ end
1585
+
1586
+ it "sets the base on the inverse relation" do
1587
+ expect(address.addressable).to eq(person)
1588
+ end
1589
+
1590
+ it "saves the document" do
1591
+ expect(address).to be_persisted
1592
+ end
1593
+
1594
+ it "sets the parent on the child" do
1595
+ expect(address._parent).to eq(person)
1596
+ end
1597
+
1598
+ it "sets the association metadata on the child" do
1599
+ expect(address._association).to_not be_nil
1600
+ end
1601
+
1602
+ it "sets the index on the child" do
1603
+ expect(address._index).to eq(0)
1604
+ end
1605
+
1606
+ it "writes to the attributes" do
1607
+ expect(address.street).to eq("Bond")
1608
+ end
1609
+ end
1610
+
1611
+ context "when validation fails" do
1612
+
1613
+ it "raises an error" do
1614
+ expect {
1615
+ person.addresses.create!(street: "1")
1616
+ }.to raise_error(Mongoid::Errors::Validations)
1617
+ end
1618
+
1619
+ context 'when the presence of the embedded relation is validated' do
1620
+
1621
+ around do |example|
1622
+ Book.validates :pages, presence: true
1623
+ example.run
1624
+ Book.reset_callbacks(:validate)
1625
+ end
1626
+
1627
+ let(:book) do
1628
+ Book.new.tap do |b|
1629
+ b.pages = [Page.new]
1630
+ b.save!
1631
+ end
1632
+ end
1633
+
1634
+ let(:num_pages) do
1635
+ book.pages.size
1636
+ end
1637
+
1638
+ let(:reloaded) do
1639
+ book.reload
1640
+ end
1641
+
1642
+ before do
1643
+ begin; book.update_attributes!({"pages"=>nil}); rescue; end
1644
+ end
1645
+
1646
+ it 'does not delete the embedded relation' do
1647
+ expect(reloaded.pages.size).to eq(num_pages)
1648
+ end
1649
+ end
1650
+ end
1651
+ end
1652
+
1653
+ describe "#delete" do
1654
+
1655
+ let(:person) do
1656
+ Person.new
1657
+ end
1658
+
1659
+ let(:address_one) do
1660
+ Address.new(street: "first")
1661
+ end
1662
+
1663
+ let(:address_two) do
1664
+ Address.new(street: "second")
1665
+ end
1666
+
1667
+ before do
1668
+ person.addresses << [ address_one, address_two ]
1669
+ end
1670
+
1671
+ context "when the document exists in the relation" do
1672
+
1673
+ let!(:deleted) do
1674
+ person.addresses.delete(address_one)
1675
+ end
1676
+
1677
+ it "deletes the document" do
1678
+ expect(person.addresses).to eq([ address_two ])
1679
+ end
1680
+
1681
+ it "deletes the document from the unscoped" do
1682
+ expect(person.addresses.send(:_unscoped)).to eq([ address_two ])
1683
+ end
1684
+
1685
+ it "reindexes the relation" do
1686
+ expect(address_two._index).to eq(0)
1687
+ end
1688
+
1689
+ it "returns the document" do
1690
+ expect(deleted).to eq(address_one)
1691
+ end
1692
+ end
1693
+
1694
+ context "when the document does not exist" do
1695
+
1696
+ it "returns nil" do
1697
+ expect(person.addresses.delete(Address.new)).to be_nil
1698
+ end
1699
+ end
1700
+ end
1701
+
1702
+ describe "#delete_if" do
1703
+
1704
+ let(:person) do
1705
+ Person.create
1706
+ end
1707
+
1708
+ context "when the documents are new" do
1709
+
1710
+ let!(:address_one) do
1711
+ person.addresses.build(street: "Bond")
1712
+ end
1713
+
1714
+ let!(:address_two) do
1715
+ person.addresses.build(street: "Upper")
1716
+ end
1717
+
1718
+ context "when a block is provided" do
1719
+
1720
+ let!(:deleted) do
1721
+ person.addresses.delete_if do |doc|
1722
+ doc.street == "Bond"
1723
+ end
1724
+ end
1725
+
1726
+ it "removes the matching documents" do
1727
+ expect(person.addresses.size).to eq(1)
1728
+ end
1729
+
1730
+ it "removes from the unscoped" do
1731
+ expect(person.addresses.send(:_unscoped).size).to eq(1)
1732
+ end
1733
+
1734
+ it "returns the relation" do
1735
+ expect(deleted).to eq(person.addresses)
1736
+ end
1737
+ end
1738
+
1739
+ context "when no block is provided" do
1740
+
1741
+ let!(:deleted) do
1742
+ person.addresses.delete_if
1743
+ end
1744
+
1745
+ it "returns an enumerator" do
1746
+ expect(deleted).to be_a(Enumerator)
1747
+ end
1748
+ end
1749
+ end
1750
+
1751
+ context "when the documents persisted" do
1752
+
1753
+ let!(:address_one) do
1754
+ person.addresses.create(street: "Bond")
1755
+ end
1756
+
1757
+ let!(:address_two) do
1758
+ person.addresses.create(street: "Upper")
1759
+ end
1760
+
1761
+ context "when a block is provided" do
1762
+
1763
+ let!(:deleted) do
1764
+ person.addresses.delete_if do |doc|
1765
+ doc.street == "Bond"
1766
+ end
1767
+ end
1768
+
1769
+ it "deletes the matching documents" do
1770
+ expect(person.addresses.count).to eq(1)
1771
+ end
1772
+
1773
+ it "deletes the matching documents from the db" do
1774
+ expect(person.reload.addresses.count).to eq(1)
1775
+ end
1776
+
1777
+ it "returns the relation" do
1778
+ expect(deleted).to eq(person.addresses)
1779
+ end
1780
+ end
1781
+ end
1782
+
1783
+ context "when the documents are empty" do
1784
+
1785
+ context "when a block is provided" do
1786
+
1787
+ let!(:deleted) do
1788
+ person.addresses.delete_if do |doc|
1789
+ doc.street == "Bond"
1790
+ end
1791
+ end
1792
+
1793
+ it "deletes the matching documents" do
1794
+ expect(person.addresses.count).to eq(0)
1795
+ end
1796
+
1797
+ it "deletes all the documents from the db" do
1798
+ expect(person.reload.addresses.count).to eq(0)
1799
+ end
1800
+
1801
+ it "returns the relation" do
1802
+ expect(deleted).to eq(person.addresses)
1803
+ end
1804
+ end
1805
+ end
1806
+ end
1807
+
1808
+ [ :delete_all, :destroy_all ].each do |method|
1809
+
1810
+ describe "##{method}" do
1811
+
1812
+ let(:person) do
1813
+ Person.create
1814
+ end
1815
+
1816
+ context "when the documents are new" do
1817
+
1818
+ let!(:address_one) do
1819
+ person.addresses.build(street: "Bond")
1820
+ end
1821
+
1822
+ let!(:address_two) do
1823
+ person.addresses.build(street: "Upper")
1824
+ end
1825
+
1826
+ context "when conditions are provided" do
1827
+
1828
+ let!(:deleted) do
1829
+ person.addresses.send(
1830
+ method,
1831
+ { street: "Bond" }
1832
+ )
1833
+ end
1834
+
1835
+ it "removes the matching documents" do
1836
+ expect(person.addresses.size).to eq(1)
1837
+ end
1838
+
1839
+ it "removes from the unscoped" do
1840
+ expect(person.addresses.send(:_unscoped).size).to eq(1)
1841
+ end
1842
+
1843
+ it "returns the number deleted" do
1844
+ expect(deleted).to eq(1)
1845
+ end
1846
+ end
1847
+
1848
+ context "when conditions are not provided" do
1849
+
1850
+ let!(:deleted) do
1851
+ person.addresses.send(method)
1852
+ end
1853
+
1854
+ it "removes all documents" do
1855
+ expect(person.addresses.size).to eq(0)
1856
+ end
1857
+
1858
+ it "returns the number deleted" do
1859
+ expect(deleted).to eq(2)
1860
+ end
1861
+ end
1862
+ end
1863
+
1864
+ context "when the documents persisted" do
1865
+
1866
+ let!(:address_one) do
1867
+ person.addresses.create(street: "Bond")
1868
+ end
1869
+
1870
+ let!(:address_two) do
1871
+ person.addresses.create(street: "Upper")
1872
+ end
1873
+
1874
+ context "when conditions are provided" do
1875
+
1876
+ let!(:deleted) do
1877
+ person.addresses.send(
1878
+ method,
1879
+ { street: "Bond" }
1880
+ )
1881
+ end
1882
+
1883
+ it "deletes the matching documents" do
1884
+ expect(person.addresses.count).to eq(1)
1885
+ end
1886
+
1887
+ it "deletes the matching documents from the db" do
1888
+ expect(person.reload.addresses.count).to eq(1)
1889
+ end
1890
+
1891
+ it "returns the number deleted" do
1892
+ expect(deleted).to eq(1)
1893
+ end
1894
+ end
1895
+
1896
+ context "when conditions are not provided" do
1897
+
1898
+ let!(:deleted) do
1899
+ person.addresses.send(method)
1900
+ end
1901
+
1902
+ it "deletes all the documents" do
1903
+ expect(person.addresses.count).to eq(0)
1904
+ end
1905
+
1906
+ it "deletes all the documents from the db" do
1907
+ expect(person.reload.addresses.count).to eq(0)
1908
+ end
1909
+
1910
+ it "returns the number deleted" do
1911
+ expect(deleted).to eq(2)
1912
+ end
1913
+ end
1914
+
1915
+ context "when removing and resaving" do
1916
+
1917
+ let(:owner) do
1918
+ PetOwner.create(title: "AKC")
1919
+ end
1920
+
1921
+ before do
1922
+ owner.pet = Pet.new(name: "Fido")
1923
+ owner.pet.vet_visits << VetVisit.new(date: Date.today)
1924
+ owner.save!
1925
+ owner.pet.vet_visits.destroy_all
1926
+ end
1927
+
1928
+ it "removes the documents" do
1929
+ expect(owner.pet.vet_visits).to be_empty
1930
+ end
1931
+
1932
+ it "allows addition and a resave" do
1933
+ owner.pet.vet_visits << VetVisit.new(date: Date.today)
1934
+ owner.save!
1935
+ expect(owner.pet.vet_visits.first).to be_persisted
1936
+ end
1937
+ end
1938
+ end
1939
+
1940
+ context "when the documents empty" do
1941
+
1942
+ context "when scoped" do
1943
+ let!(:deleted) do
1944
+ person.addresses.without_postcode.send(method)
1945
+ end
1946
+
1947
+ it "deletes all the documents" do
1948
+ expect(person.addresses.count).to eq(0)
1949
+ end
1950
+
1951
+ it "deletes all the documents from the db" do
1952
+ expect(person.reload.addresses.count).to eq(0)
1953
+ end
1954
+
1955
+ it "returns the number deleted" do
1956
+ expect(deleted).to eq(0)
1957
+ end
1958
+ end
1959
+
1960
+ context "when conditions are provided" do
1961
+
1962
+ let!(:deleted) do
1963
+ person.addresses.send(
1964
+ method,
1965
+ conditions: { street: "Bond" }
1966
+ )
1967
+ end
1968
+
1969
+ it "deletes all the documents" do
1970
+ expect(person.addresses.count).to eq(0)
1971
+ end
1972
+
1973
+ it "deletes all the documents from the db" do
1974
+ expect(person.reload.addresses.count).to eq(0)
1975
+ end
1976
+
1977
+ it "returns the number deleted" do
1978
+ expect(deleted).to eq(0)
1979
+ end
1980
+ end
1981
+
1982
+ context "when conditions are not provided" do
1983
+
1984
+ let!(:deleted) do
1985
+ person.addresses.send(method)
1986
+ end
1987
+
1988
+ it "deletes all the documents" do
1989
+ expect(person.addresses.count).to eq(0)
1990
+ end
1991
+
1992
+ it "deletes all the documents from the db" do
1993
+ expect(person.reload.addresses.count).to eq(0)
1994
+ end
1995
+
1996
+ it "returns the number deleted" do
1997
+ expect(deleted).to eq(0)
1998
+ end
1999
+ end
2000
+ end
2001
+ end
2002
+ end
2003
+
2004
+ describe ".embedded?" do
2005
+
2006
+ it "returns true" do
2007
+ expect(described_class).to be_embedded
2008
+ end
2009
+ end
2010
+
2011
+ describe "#exists?" do
2012
+
2013
+ let!(:person) do
2014
+ Person.create
2015
+ end
2016
+
2017
+ context "when documents exist in the database" do
2018
+
2019
+ before do
2020
+ person.addresses.create(street: "Bond St")
2021
+ end
2022
+
2023
+ it "returns true" do
2024
+ expect(person.addresses.exists?).to be true
2025
+ end
2026
+ end
2027
+
2028
+ context "when no documents exist in the database" do
2029
+
2030
+ before do
2031
+ person.addresses.build(street: "Hyde Park Dr")
2032
+ end
2033
+
2034
+ it "returns false" do
2035
+ expect(person.addresses.exists?).to be false
2036
+ end
2037
+ end
2038
+ end
2039
+
2040
+ describe "#find" do
2041
+
2042
+ let(:person) do
2043
+ Person.new
2044
+ end
2045
+
2046
+ let!(:address_one) do
2047
+ person.addresses.build(street: "Bond", city: "London")
2048
+ end
2049
+
2050
+ let!(:address_two) do
2051
+ person.addresses.build(street: "Upper", city: "London")
2052
+ end
2053
+
2054
+ context "when providing an id" do
2055
+
2056
+ context "when the id matches" do
2057
+
2058
+ let(:address) do
2059
+ person.addresses.find(address_one.id)
2060
+ end
2061
+
2062
+ it "returns the matching document" do
2063
+ expect(address).to eq(address_one)
2064
+ end
2065
+ end
2066
+
2067
+ context "when the id does not match" do
2068
+
2069
+ context "when config set to raise error" do
2070
+
2071
+ before do
2072
+ Mongoid.raise_not_found_error = true
2073
+ end
2074
+
2075
+ it "raises an error" do
2076
+ expect {
2077
+ person.addresses.find(BSON::ObjectId.new)
2078
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
2079
+ end
2080
+ end
2081
+
2082
+ context "when config set not to raise error" do
2083
+
2084
+ let(:address) do
2085
+ person.addresses.find(BSON::ObjectId.new)
2086
+ end
2087
+
2088
+ before do
2089
+ Mongoid.raise_not_found_error = false
2090
+ end
2091
+
2092
+ after do
2093
+ Mongoid.raise_not_found_error = true
2094
+ end
2095
+
2096
+ it "returns nil" do
2097
+ expect(address).to be_nil
2098
+ end
2099
+ end
2100
+ end
2101
+ end
2102
+
2103
+ context "when providing an array of ids" do
2104
+
2105
+ context "when the ids match" do
2106
+
2107
+ let(:addresses) do
2108
+ person.addresses.find([ address_one.id, address_two.id ])
2109
+ end
2110
+
2111
+ it "returns the matching documents" do
2112
+ expect(addresses).to eq([ address_one, address_two ])
2113
+ end
2114
+ end
2115
+
2116
+ context "when the ids do not match" do
2117
+
2118
+ context "when config set to raise error" do
2119
+
2120
+ before do
2121
+ Mongoid.raise_not_found_error = true
2122
+ end
2123
+
2124
+ it "raises an error" do
2125
+ expect {
2126
+ person.addresses.find([ BSON::ObjectId.new ])
2127
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
2128
+ end
2129
+ end
2130
+
2131
+ context "when config set not to raise error" do
2132
+
2133
+ let(:addresses) do
2134
+ person.addresses.find([ BSON::ObjectId.new ])
2135
+ end
2136
+
2137
+ before do
2138
+ Mongoid.raise_not_found_error = false
2139
+ end
2140
+
2141
+ after do
2142
+ Mongoid.raise_not_found_error = true
2143
+ end
2144
+
2145
+ it "returns an empty array" do
2146
+ expect(addresses).to be_empty
2147
+ end
2148
+ end
2149
+ end
2150
+ end
2151
+ end
2152
+
2153
+ describe "#find_or_create_by" do
2154
+
2155
+ let(:person) do
2156
+ Person.create
2157
+ end
2158
+
2159
+ let!(:address) do
2160
+ person.addresses.build(street: "Bourke", city: "Melbourne")
2161
+ end
2162
+
2163
+ context "when the document exists" do
2164
+
2165
+ let(:found) do
2166
+ person.addresses.find_or_create_by(street: "Bourke")
2167
+ end
2168
+
2169
+ it "returns the document" do
2170
+ expect(found).to eq(address)
2171
+ end
2172
+ end
2173
+
2174
+ context "when the document does not exist" do
2175
+
2176
+ let(:found) do
2177
+ person.addresses.find_or_create_by(street: "King") do |address|
2178
+ address.state = "CA"
2179
+ end
2180
+ end
2181
+
2182
+ it "sets the new document attributes" do
2183
+ expect(found.street).to eq("King")
2184
+ end
2185
+
2186
+ it "returns a newly persisted document" do
2187
+ expect(found).to be_persisted
2188
+ end
2189
+
2190
+ it "calls the passed block" do
2191
+ expect(found.state).to eq("CA")
2192
+ end
2193
+ end
2194
+
2195
+ # todo: why should this pass?
2196
+ # context "when the child belongs to another document" do
2197
+ #
2198
+ # let(:product) do
2199
+ # Product.create
2200
+ # end
2201
+ #
2202
+ # let(:purchase) do
2203
+ # Purchase.create
2204
+ # end
2205
+ #
2206
+ # let(:line_item) do
2207
+ # purchase.line_items.find_or_create_by(
2208
+ # product_id: product.id,
2209
+ # product_type: product.class.name
2210
+ # )
2211
+ # end
2212
+ #
2213
+ # it "properly creates the document" do
2214
+ # expect(line_item.product).to eq(product)
2215
+ # end
2216
+ # end
2217
+ end
2218
+
2219
+ describe "#find_or_create_by!" do
2220
+
2221
+ let(:person) do
2222
+ Person.create
2223
+ end
2224
+
2225
+ let!(:address) do
2226
+ person.addresses.build(street: "Bourke", city: "Melbourne")
2227
+ end
2228
+
2229
+ context "when the document exists" do
2230
+
2231
+ let(:found) do
2232
+ person.addresses.find_or_create_by!(street: "Bourke")
2233
+ end
2234
+
2235
+ it "returns the document" do
2236
+ expect(found).to eq(address)
2237
+ end
2238
+ end
2239
+
2240
+ context "when the document does not exist" do
2241
+
2242
+ let(:found) do
2243
+ person.addresses.find_or_create_by!(street: "King") do |address|
2244
+ address.state = "CA"
2245
+ end
2246
+ end
2247
+
2248
+ it "sets the new document attributes" do
2249
+ expect(found.street).to eq("King")
2250
+ end
2251
+
2252
+ it "returns a newly persisted document" do
2253
+ expect(found).to be_persisted
2254
+ end
2255
+
2256
+ it "calls the passed block" do
2257
+ expect(found.state).to eq("CA")
2258
+ end
2259
+
2260
+ context "when validation fails" do
2261
+
2262
+ it "raises an error" do
2263
+ expect {
2264
+ person.addresses.find_or_create_by!(street: "1")
2265
+ }.to raise_error(Mongoid::Errors::Validations)
2266
+ end
2267
+ end
2268
+ end
2269
+
2270
+ # todo: why should this pass?
2271
+ # context "when the child belongs to another document" do
2272
+ #
2273
+ # let(:product) do
2274
+ # Product.create
2275
+ # end
2276
+ #
2277
+ # let(:purchase) do
2278
+ # Purchase.create
2279
+ # end
2280
+ #
2281
+ # let(:line_item) do
2282
+ # purchase.line_items.find_or_create_by(
2283
+ # product_id: product.id,
2284
+ # product_type: product.class.name
2285
+ # )
2286
+ # end
2287
+ #
2288
+ # it "properly creates the document" do
2289
+ # expect(line_item.product).to eq(product)
2290
+ # end
2291
+ # end
2292
+ end
2293
+
2294
+ describe "#find_or_initialize_by" do
2295
+
2296
+ let(:person) do
2297
+ Person.new
2298
+ end
2299
+
2300
+ let!(:address) do
2301
+ person.addresses.build(street: "Bourke", city: "Melbourne")
2302
+ end
2303
+
2304
+ context "when the document exists" do
2305
+
2306
+ let(:found) do
2307
+ person.addresses.find_or_initialize_by(street: "Bourke")
2308
+ end
2309
+
2310
+ it "returns the document" do
2311
+ expect(found).to eq(address)
2312
+ end
2313
+ end
2314
+
2315
+ context "when the document does not exist" do
2316
+
2317
+ let(:found) do
2318
+ person.addresses.find_or_initialize_by(street: "King") do |address|
2319
+ address.state = "CA"
2320
+ end
2321
+ end
2322
+
2323
+ it "sets the new document attributes" do
2324
+ expect(found.street).to eq("King")
2325
+ end
2326
+
2327
+ it "returns a non persisted document" do
2328
+ expect(found).to_not be_persisted
2329
+ end
2330
+
2331
+ it "calls the passed block" do
2332
+ expect(found.state).to eq("CA")
2333
+ end
2334
+ end
2335
+ end
2336
+
2337
+ describe "#max" do
2338
+
2339
+ let(:person) do
2340
+ Person.new
2341
+ end
2342
+
2343
+ let(:address_one) do
2344
+ Address.new(number: 5)
2345
+ end
2346
+
2347
+ let(:address_two) do
2348
+ Address.new(number: 10)
2349
+ end
2350
+
2351
+ before do
2352
+ person.addresses.push(address_one, address_two)
2353
+ end
2354
+
2355
+ let(:max) do
2356
+ person.addresses.max do |a,b|
2357
+ a.number <=> b.number
2358
+ end
2359
+ end
2360
+
2361
+ it "returns the document with the max value of the supplied field" do
2362
+ expect(max).to eq(address_two)
2363
+ end
2364
+ end
2365
+
2366
+ describe "#max_by" do
2367
+
2368
+ let(:person) do
2369
+ Person.new
2370
+ end
2371
+
2372
+ let(:address_one) do
2373
+ Address.new(number: 5)
2374
+ end
2375
+
2376
+ let(:address_two) do
2377
+ Address.new(number: 10)
2378
+ end
2379
+
2380
+ before do
2381
+ person.addresses.push(address_one, address_two)
2382
+ end
2383
+
2384
+ let(:max) do
2385
+ person.addresses.max_by(&:number)
2386
+ end
2387
+
2388
+ it "returns the document with the max value of the supplied field" do
2389
+ expect(max).to eq(address_two)
2390
+ end
2391
+ end
2392
+
2393
+ describe "#method_missing" do
2394
+
2395
+ let!(:person) do
2396
+ Person.create
2397
+ end
2398
+
2399
+ let!(:address_one) do
2400
+ person.addresses.create(
2401
+ street: "Market",
2402
+ state: "CA",
2403
+ services: [ "1", "2" ]
2404
+ )
2405
+ end
2406
+
2407
+ let!(:address_two) do
2408
+ person.addresses.create(
2409
+ street: "Madison",
2410
+ state: "NY",
2411
+ services: [ "1", "2" ]
2412
+ )
2413
+ end
2414
+
2415
+ context "when providing a single criteria" do
2416
+
2417
+ context "when using a simple criteria" do
2418
+
2419
+ let(:addresses) do
2420
+ person.addresses.where(state: "CA")
2421
+ end
2422
+
2423
+ it "applies the criteria to the documents" do
2424
+ expect(addresses).to eq([ address_one ])
2425
+ end
2426
+ end
2427
+
2428
+ context "when using an $or criteria" do
2429
+
2430
+ let(:addresses) do
2431
+ person.addresses.any_of({ state: "CA" }, { state: "NY" })
2432
+ end
2433
+
2434
+ it "applies the criteria to the documents" do
2435
+ expect(addresses).to eq([ address_one, address_two ])
2436
+ end
2437
+ end
2438
+
2439
+ context "when using array comparison" do
2440
+
2441
+ let(:addresses) do
2442
+ person.addresses.where(services: [ "1", "2" ])
2443
+ end
2444
+
2445
+ it "applies the criteria to the documents" do
2446
+ expect(addresses).to eq([ address_one, address_two ])
2447
+ end
2448
+ end
2449
+ end
2450
+
2451
+ context "when providing a criteria class method" do
2452
+ context "without keyword arguments" do
2453
+
2454
+ let(:addresses) do
2455
+ person.addresses.california
2456
+ end
2457
+
2458
+ it "applies the criteria to the documents" do
2459
+ expect(addresses).to eq([ address_one ])
2460
+ end
2461
+ end
2462
+
2463
+ context "with keyword arguments" do
2464
+
2465
+ let(:addresses) do
2466
+ person.addresses.city_and_state(city: "Sacramento", state: "CA")
2467
+ end
2468
+
2469
+ it "applies the criteria to the documents" do
2470
+ expect(addresses).to eq([])
2471
+ end
2472
+ end
2473
+ end
2474
+
2475
+ context "when chaining criteria" do
2476
+
2477
+ let(:addresses) do
2478
+ person.addresses.california.where(:street.in => [ "Market" ])
2479
+ end
2480
+
2481
+ it "applies the criteria to the documents" do
2482
+ expect(addresses).to eq([ address_one ])
2483
+ end
2484
+ end
2485
+
2486
+ context "when delegating methods" do
2487
+
2488
+ describe "#distinct" do
2489
+
2490
+ it "returns the distinct values for the fields" do
2491
+ expect(person.addresses.distinct(:street)).to eq([ "Market", "Madison"])
2492
+ end
2493
+ end
2494
+ end
2495
+ end
2496
+
2497
+ describe "#min" do
2498
+
2499
+ let(:person) do
2500
+ Person.new
2501
+ end
2502
+
2503
+ let(:address_one) do
2504
+ Address.new(number: 5)
2505
+ end
2506
+
2507
+ let(:address_two) do
2508
+ Address.new(number: 10)
2509
+ end
2510
+
2511
+ before do
2512
+ person.addresses.push(address_one, address_two)
2513
+ end
2514
+
2515
+ let(:min) do
2516
+ person.addresses.min do |a,b|
2517
+ a.number <=> b.number
2518
+ end
2519
+ end
2520
+
2521
+ it "returns the min value of the supplied field" do
2522
+ expect(min).to eq(address_one)
2523
+ end
2524
+ end
2525
+
2526
+ describe "#min_by" do
2527
+
2528
+ let(:person) do
2529
+ Person.new
2530
+ end
2531
+
2532
+ let(:address_one) do
2533
+ Address.new(number: 5)
2534
+ end
2535
+
2536
+ let(:address_two) do
2537
+ Address.new(number: 10)
2538
+ end
2539
+
2540
+ before do
2541
+ person.addresses.push(address_one, address_two)
2542
+ end
2543
+
2544
+ let(:min) do
2545
+ person.addresses.min_by(&:number)
2546
+ end
2547
+
2548
+ it "returns the min value of the supplied field" do
2549
+ expect(min).to eq(address_one)
2550
+ end
2551
+ end
2552
+
2553
+ describe "#pop" do
2554
+
2555
+ let(:person) do
2556
+ Person.create
2557
+ end
2558
+
2559
+ context "when no argument is provided" do
2560
+
2561
+ let!(:address_one) do
2562
+ person.addresses.create(street: "sonnenallee")
2563
+ end
2564
+
2565
+ let!(:address_two) do
2566
+ person.addresses.create(street: "hermannstr")
2567
+ end
2568
+
2569
+ let!(:popped) do
2570
+ person.addresses.pop
2571
+ end
2572
+
2573
+ it "returns the popped document" do
2574
+ expect(popped).to eq(address_two)
2575
+ end
2576
+
2577
+ it "removes the document from the relation" do
2578
+ expect(person.addresses).to eq([ address_one ])
2579
+ end
2580
+
2581
+ it "persists the pop" do
2582
+ expect(person.reload.addresses).to eq([ address_one ])
2583
+ end
2584
+ end
2585
+
2586
+ context "when an integer is provided" do
2587
+
2588
+ let!(:address_one) do
2589
+ person.addresses.create(street: "sonnenallee")
2590
+ end
2591
+
2592
+ let!(:address_two) do
2593
+ person.addresses.create(street: "hermannstr")
2594
+ end
2595
+
2596
+ context "when the number is zero" do
2597
+
2598
+ let!(:popped) do
2599
+ person.addresses.pop(0)
2600
+ end
2601
+
2602
+ it "returns an empty array" do
2603
+ expect(popped).to eq([])
2604
+ end
2605
+
2606
+ it "does not remove the document from the relation" do
2607
+ expect(person.addresses).to eq([ address_one, address_two ])
2608
+ end
2609
+
2610
+ it "does not persist the pop" do
2611
+ expect(person.reload.addresses).to eq([ address_one, address_two ])
2612
+ end
2613
+ end
2614
+
2615
+ context "when the number is not larger than the relation" do
2616
+
2617
+ let!(:popped) do
2618
+ person.addresses.pop(2)
2619
+ end
2620
+
2621
+ it "returns the popped documents" do
2622
+ expect(popped).to eq([ address_one, address_two ])
2623
+ end
2624
+
2625
+ it "removes the document from the relation" do
2626
+ expect(person.addresses).to be_empty
2627
+ end
2628
+
2629
+ it "persists the pop" do
2630
+ expect(person.reload.addresses).to be_empty
2631
+ end
2632
+ end
2633
+
2634
+ context "when the number is larger than the relation" do
2635
+
2636
+ let!(:popped) do
2637
+ person.addresses.pop(4)
2638
+ end
2639
+
2640
+ it "returns the popped documents" do
2641
+ expect(popped).to eq([ address_one, address_two ])
2642
+ end
2643
+
2644
+ it "removes the document from the relation" do
2645
+ expect(person.addresses).to be_empty
2646
+ end
2647
+
2648
+ it "persists the pop" do
2649
+ expect(person.reload.addresses).to be_empty
2650
+ end
2651
+ end
2652
+ end
2653
+
2654
+ context "when the relation is empty" do
2655
+
2656
+ context "when providing no number" do
2657
+
2658
+ it "returns nil" do
2659
+ expect(person.addresses.pop).to be_nil
2660
+ end
2661
+ end
2662
+
2663
+ context "when providing a number" do
2664
+
2665
+ it "returns nil" do
2666
+ expect(person.addresses.pop(2)).to be_nil
2667
+ end
2668
+ end
2669
+ end
2670
+ end
2671
+
2672
+ describe "#shift" do
2673
+
2674
+ let(:person) do
2675
+ Person.create
2676
+ end
2677
+
2678
+ context "when no argument is provided" do
2679
+
2680
+ let!(:address_one) do
2681
+ person.addresses.create(street: "sonnenallee")
2682
+ end
2683
+
2684
+ let!(:address_two) do
2685
+ person.addresses.create(street: "hermannstr")
2686
+ end
2687
+
2688
+ let!(:shifted) do
2689
+ person.addresses.shift
2690
+ end
2691
+
2692
+ it "returns the shifted document" do
2693
+ expect(shifted).to eq(address_one)
2694
+ end
2695
+
2696
+ it "removes the document from the relation" do
2697
+ expect(person.addresses).to eq([ address_two ])
2698
+ end
2699
+
2700
+ it "persists the shift" do
2701
+ expect(person.reload.addresses).to eq([ address_two ])
2702
+ end
2703
+ end
2704
+
2705
+ context "when an integer is provided" do
2706
+
2707
+ let!(:address_one) do
2708
+ person.addresses.create(street: "sonnenallee")
2709
+ end
2710
+
2711
+ let!(:address_two) do
2712
+ person.addresses.create(street: "hermannstr")
2713
+ end
2714
+
2715
+ context "when the number is zero" do
2716
+
2717
+ let!(:shifted) do
2718
+ person.addresses.shift(0)
2719
+ end
2720
+
2721
+ it "returns an empty array" do
2722
+ expect(shifted).to eq([])
2723
+ end
2724
+
2725
+ it "does not remove the document from the relation" do
2726
+ expect(person.addresses).to eq([ address_one, address_two ])
2727
+ end
2728
+
2729
+ it "does not persist the shift" do
2730
+ expect(person.reload.addresses).to eq([ address_one, address_two ])
2731
+ end
2732
+ end
2733
+
2734
+ context "when the number is not larger than the relation" do
2735
+
2736
+ let!(:shifted) do
2737
+ person.addresses.shift(2)
2738
+ end
2739
+
2740
+ it "returns the shifted documents" do
2741
+ expect(shifted).to eq([ address_one, address_two ])
2742
+ end
2743
+
2744
+ it "removes the document from the relation" do
2745
+ expect(person.addresses).to be_empty
2746
+ end
2747
+
2748
+ it "persists the shift" do
2749
+ expect(person.reload.addresses).to be_empty
2750
+ end
2751
+ end
2752
+
2753
+ context "when the number is larger than the relation" do
2754
+
2755
+ let!(:shifted) do
2756
+ person.addresses.shift(4)
2757
+ end
2758
+
2759
+ it "returns the shifted documents" do
2760
+ expect(shifted).to eq([ address_one, address_two ])
2761
+ end
2762
+
2763
+ it "removes the document from the relation" do
2764
+ expect(person.addresses).to be_empty
2765
+ end
2766
+
2767
+ it "persists the shift" do
2768
+ expect(person.reload.addresses).to be_empty
2769
+ end
2770
+ end
2771
+ end
2772
+
2773
+ context "when the relation is empty" do
2774
+
2775
+ context "when providing no number" do
2776
+
2777
+ it "returns nil" do
2778
+ expect(person.addresses.shift).to be_nil
2779
+ end
2780
+ end
2781
+
2782
+ context "when providing a number" do
2783
+
2784
+ it "returns nil" do
2785
+ expect(person.addresses.shift(2)).to be_nil
2786
+ end
2787
+ end
2788
+ end
2789
+ end
2790
+
2791
+ describe "#scoped" do
2792
+
2793
+ let(:person) do
2794
+ Person.new
2795
+ end
2796
+
2797
+ let(:scoped) do
2798
+ person.addresses.scoped
2799
+ end
2800
+
2801
+ it "returns the relation criteria" do
2802
+ expect(scoped).to be_a(Mongoid::Criteria)
2803
+ end
2804
+
2805
+ it "returns with an empty selector" do
2806
+ expect(scoped.selector).to be_empty
2807
+ end
2808
+ end
2809
+
2810
+ describe "#respond_to?" do
2811
+
2812
+ let(:person) do
2813
+ Person.new
2814
+ end
2815
+
2816
+ let(:addresses) do
2817
+ person.addresses
2818
+ end
2819
+
2820
+ Array.public_instance_methods.each do |method|
2821
+
2822
+ context "when checking #{method}" do
2823
+
2824
+ it "returns true" do
2825
+ expect(addresses.respond_to?(method)).to be true
2826
+ end
2827
+ end
2828
+ end
2829
+
2830
+ Mongoid::Association::Embedded::EmbedsMany::Proxy.public_instance_methods.each do |method|
2831
+
2832
+ context "when checking #{method}" do
2833
+
2834
+ it "returns true" do
2835
+ expect(addresses.respond_to?(method)).to be true
2836
+ end
2837
+ end
2838
+ end
2839
+
2840
+ Address.scopes.keys.each do |method|
2841
+
2842
+ context "when checking #{method}" do
2843
+
2844
+ it "returns true" do
2845
+ expect(addresses.respond_to?(method)).to be true
2846
+ end
2847
+ end
2848
+ end
2849
+
2850
+ it "supports 'include_private = boolean'" do
2851
+ expect { addresses.respond_to?(:Rational, true) }.not_to raise_error
2852
+ end
2853
+ end
2854
+
2855
+ [ :size, :length ].each do |method|
2856
+
2857
+ describe "##{method}" do
2858
+
2859
+ let(:person) do
2860
+ Person.create
2861
+ end
2862
+
2863
+ before do
2864
+ person.addresses.create(street: "Upper")
2865
+ person.addresses.build(street: "Bond")
2866
+ end
2867
+
2868
+ it "returns the number of persisted documents" do
2869
+ expect(person.addresses.send(method)).to eq(2)
2870
+ end
2871
+ end
2872
+ end
2873
+
2874
+ describe "#unscoped" do
2875
+
2876
+ let(:person) do
2877
+ Person.new
2878
+ end
2879
+
2880
+ let(:unscoped) do
2881
+ person.videos.unscoped
2882
+ end
2883
+
2884
+ it "returns the relation criteria" do
2885
+ expect(unscoped).to be_a(Mongoid::Criteria)
2886
+ end
2887
+
2888
+ it "returns with empty options" do
2889
+ expect(unscoped.options).to be_empty
2890
+ end
2891
+
2892
+ it "returns with an empty selector" do
2893
+ expect(unscoped.selector).to be_empty
2894
+ end
2895
+ end
2896
+
2897
+ describe "#update_all" do
2898
+
2899
+ context "when there are no documents present" do
2900
+
2901
+ let(:person) do
2902
+ Person.create
2903
+ end
2904
+
2905
+ it "updates nothing" do
2906
+ expect(person.addresses.update_all(street: "test")).to be false
2907
+ end
2908
+ end
2909
+
2910
+ context "when documents are present" do
2911
+
2912
+ let(:person) do
2913
+ Person.create
2914
+ end
2915
+
2916
+ let!(:address) do
2917
+ person.addresses.create(street: "Hobrecht", number: 27)
2918
+ end
2919
+
2920
+ context "when updating with a where clause" do
2921
+
2922
+ before do
2923
+ person.addresses.
2924
+ where(street: "Hobrecht").
2925
+ update_all(number: 26, post_code: "12437")
2926
+ end
2927
+
2928
+ it "resets the matching dirty flags" do
2929
+ expect(address).to_not be_changed
2930
+ end
2931
+
2932
+ it "updates the first field" do
2933
+ expect(address.reload.number).to eq(26)
2934
+ end
2935
+
2936
+ it "updates the second field" do
2937
+ expect(address.reload.post_code).to eq("12437")
2938
+ end
2939
+
2940
+ it "does not wipe out other fields" do
2941
+ expect(address.reload.street).to eq("Hobrecht")
2942
+ end
2943
+ end
2944
+ end
2945
+ end
2946
+
2947
+ context "when deeply embedding documents" do
2948
+
2949
+ context "when updating the bottom level" do
2950
+
2951
+ let!(:person) do
2952
+ Person.create
2953
+ end
2954
+
2955
+ let!(:address) do
2956
+ person.addresses.create(street: "Joachimstr")
2957
+ end
2958
+
2959
+ let!(:location) do
2960
+ address.locations.create(name: "vacation", number: 0)
2961
+ address.locations.create(name: "work", number: 3)
2962
+ end
2963
+
2964
+ context "when updating with replacement of embedded array" do
2965
+
2966
+ context "when updating with a hash" do
2967
+
2968
+ before do
2969
+ address.update_attributes(locations: [{ name: "home" }])
2970
+ end
2971
+
2972
+ it "updates the attributes" do
2973
+ expect(address.locations.first.name).to eq("home")
2974
+ end
2975
+
2976
+ it "overwrites the existing documents" do
2977
+ expect(address.locations.count).to eq(1)
2978
+ end
2979
+
2980
+ it "persists the changes" do
2981
+ expect(address.reload.locations.count).to eq(1)
2982
+ end
2983
+ end
2984
+ end
2985
+
2986
+ context "when updating a field in a document of the embedded array" do
2987
+
2988
+ before do
2989
+ location.number = 7
2990
+ location.save
2991
+ end
2992
+
2993
+ let(:updated_location_number) do
2994
+ person.reload.addresses.first.locations.find(location.id).number
2995
+ end
2996
+
2997
+ let(:updated_location_name) do
2998
+ person.reload.addresses.first.locations.find(location.id).name
2999
+ end
3000
+
3001
+ it "the change is persisted" do
3002
+ expect(updated_location_number).to eq(7)
3003
+ end
3004
+
3005
+ it "the other field remains unaffected" do
3006
+ expect(updated_location_name).to eq("work")
3007
+ end
3008
+
3009
+ end
3010
+ end
3011
+
3012
+ context "when building the tree through hashes" do
3013
+
3014
+ let(:circus) do
3015
+ Circus.new(hash)
3016
+ end
3017
+
3018
+ let(:animal) do
3019
+ circus.animals.first
3020
+ end
3021
+
3022
+ let(:animal_name) do
3023
+ "Lion"
3024
+ end
3025
+
3026
+ let(:tag_list) do
3027
+ "tigers, bears, oh my"
3028
+ end
3029
+
3030
+ context "when the hash uses stringified keys" do
3031
+
3032
+ let(:hash) do
3033
+ { 'animals' => [{ 'name' => animal_name, 'tag_list' => tag_list }] }
3034
+ end
3035
+
3036
+ it "sets up the hierarchy" do
3037
+ expect(animal.circus).to eq(circus)
3038
+ end
3039
+
3040
+ it "assigns the attributes" do
3041
+ expect(animal.name).to eq(animal_name)
3042
+ end
3043
+
3044
+ it "uses custom writer methods" do
3045
+ expect(animal.tag_list).to eq(tag_list)
3046
+ end
3047
+ end
3048
+
3049
+ context "when the hash uses symbolized keys" do
3050
+
3051
+ let(:hash) do
3052
+ { animals: [{ name: animal_name, tag_list: tag_list }] }
3053
+ end
3054
+
3055
+ it "sets up the hierarchy" do
3056
+ expect(animal.circus).to eq(circus)
3057
+ end
3058
+
3059
+ it "assigns the attributes" do
3060
+ expect(animal.name).to eq(animal_name)
3061
+ end
3062
+
3063
+ it "uses custom writer methods" do
3064
+ expect(animal.tag_list).to eq(tag_list)
3065
+ end
3066
+ end
3067
+ end
3068
+
3069
+ context "when building the tree through pushes" do
3070
+
3071
+ let(:quiz) do
3072
+ Quiz.new
3073
+ end
3074
+
3075
+ let(:page) do
3076
+ Page.new
3077
+ end
3078
+
3079
+ let(:page_question) do
3080
+ PageQuestion.new
3081
+ end
3082
+
3083
+ before do
3084
+ quiz.pages << page
3085
+ page.page_questions << page_question
3086
+ end
3087
+
3088
+ let(:question) do
3089
+ quiz.pages.first.page_questions.first
3090
+ end
3091
+
3092
+ it "sets up the hierarchy" do
3093
+ expect(question).to eq(page_question)
3094
+ end
3095
+ end
3096
+
3097
+ context "when building the tree through builds" do
3098
+
3099
+ let!(:quiz) do
3100
+ Quiz.new
3101
+ end
3102
+
3103
+ let!(:page) do
3104
+ quiz.pages.build
3105
+ end
3106
+
3107
+ let!(:page_question) do
3108
+ page.page_questions.build
3109
+ end
3110
+
3111
+ let(:question) do
3112
+ quiz.pages.first.page_questions.first
3113
+ end
3114
+
3115
+ it "sets up the hierarchy" do
3116
+ expect(question).to eq(page_question)
3117
+ end
3118
+ end
3119
+
3120
+ context "when creating a persisted tree" do
3121
+
3122
+ let(:quiz) do
3123
+ Quiz.create
3124
+ end
3125
+
3126
+ let(:page) do
3127
+ Page.new
3128
+ end
3129
+
3130
+ let(:page_question) do
3131
+ PageQuestion.new
3132
+ end
3133
+
3134
+ let(:question) do
3135
+ quiz.pages.first.page_questions.first
3136
+ end
3137
+
3138
+ before do
3139
+ quiz.pages << page
3140
+ page.page_questions << page_question
3141
+ end
3142
+
3143
+ it "sets up the hierarchy" do
3144
+ expect(question).to eq(page_question)
3145
+ end
3146
+
3147
+ context "when reloading" do
3148
+
3149
+ let(:from_db) do
3150
+ quiz.reload
3151
+ end
3152
+
3153
+ let(:reloaded_question) do
3154
+ from_db.pages.first.page_questions.first
3155
+ end
3156
+
3157
+ it "reloads the entire tree" do
3158
+ expect(reloaded_question).to eq(question)
3159
+ end
3160
+ end
3161
+ end
3162
+ end
3163
+
3164
+ context "when deeply nesting documents" do
3165
+
3166
+ context "when all documents are new" do
3167
+
3168
+ let(:person) do
3169
+ Person.new
3170
+ end
3171
+
3172
+ let(:address) do
3173
+ Address.new
3174
+ end
3175
+
3176
+ let(:location) do
3177
+ Location.new
3178
+ end
3179
+
3180
+ before do
3181
+ address.locations << location
3182
+ person.addresses << address
3183
+ end
3184
+
3185
+ context "when saving the root" do
3186
+
3187
+ before do
3188
+ person.save
3189
+ end
3190
+
3191
+ it "persists the first level document" do
3192
+ expect(person.reload.addresses.first).to eq(address)
3193
+ end
3194
+
3195
+ it "persists the second level document" do
3196
+ expect(person.reload.addresses[0].locations).to eq([ location ])
3197
+ end
3198
+ end
3199
+ end
3200
+ end
3201
+
3202
+ context "when attempting nil pushes and substitutes" do
3203
+
3204
+ let(:home_phone) do
3205
+ Phone.new(number: "555-555-5555")
3206
+ end
3207
+
3208
+ let(:office_phone) do
3209
+ Phone.new(number: "666-666-6666")
3210
+ end
3211
+
3212
+ describe "replacing the entire embedded list" do
3213
+
3214
+ context "when an embeds many relationship contains a nil as the first item" do
3215
+
3216
+ let(:person) do
3217
+ Person.create!
3218
+ end
3219
+
3220
+ let(:phone_list) do
3221
+ [nil, home_phone, office_phone]
3222
+ end
3223
+
3224
+ before do
3225
+ person.phone_numbers = phone_list
3226
+ person.save!
3227
+ end
3228
+
3229
+ it "ignores the nil and persist the remaining items" do
3230
+ reloaded = Person.find(person.id)
3231
+ expect(reloaded.phone_numbers).to eq([ home_phone, office_phone ])
3232
+ end
3233
+ end
3234
+
3235
+ context "when an embeds many relationship contains a nil in the middle of the list" do
3236
+
3237
+ let(:person) do
3238
+ Person.create!
3239
+ end
3240
+
3241
+ let(:phone_list) do
3242
+ [home_phone, nil, office_phone]
3243
+ end
3244
+
3245
+ before do
3246
+ person.phone_numbers = phone_list
3247
+ person.save!
3248
+ end
3249
+
3250
+ it "ignores the nil and persist the remaining items" do
3251
+ reloaded = Person.find(person.id)
3252
+ expect(reloaded.phone_numbers).to eq([ home_phone, office_phone ])
3253
+ end
3254
+ end
3255
+
3256
+ context "when an embeds many relationship contains a nil at the end of the list" do
3257
+
3258
+ let(:person) do
3259
+ Person.create!
3260
+ end
3261
+
3262
+ let(:phone_list) do
3263
+ [home_phone, office_phone, nil]
3264
+ end
3265
+
3266
+ before do
3267
+ person.phone_numbers = phone_list
3268
+ person.save!
3269
+ end
3270
+
3271
+ it "ignores the nil and persist the remaining items" do
3272
+ reloaded = Person.find(person.id)
3273
+ expect(reloaded.phone_numbers).to eq([ home_phone, office_phone ])
3274
+ end
3275
+ end
3276
+ end
3277
+
3278
+ describe "appending to the embedded list" do
3279
+
3280
+ context "when appending a nil to the first position in an embedded list" do
3281
+
3282
+ let(:person) do
3283
+ Person.create! phone_numbers: []
3284
+ end
3285
+
3286
+ before do
3287
+ person.phone_numbers << nil
3288
+ person.phone_numbers << home_phone
3289
+ person.phone_numbers << office_phone
3290
+ person.save!
3291
+ end
3292
+
3293
+ it "ignores the nil and persist the remaining items" do
3294
+ reloaded = Person.find(person.id)
3295
+ expect(reloaded.phone_numbers).to eq(person.phone_numbers)
3296
+ end
3297
+ end
3298
+
3299
+ context "when appending a nil into the middle of an embedded list" do
3300
+
3301
+ let(:person) do
3302
+ Person.create! phone_numbers: []
3303
+ end
3304
+
3305
+ before do
3306
+ person.phone_numbers << home_phone
3307
+ person.phone_numbers << nil
3308
+ person.phone_numbers << office_phone
3309
+ person.save!
3310
+ end
3311
+
3312
+ it "ignores the nil and persist the remaining items" do
3313
+ reloaded = Person.find(person.id)
3314
+ expect(reloaded.phone_numbers).to eq(person.phone_numbers)
3315
+ end
3316
+ end
3317
+
3318
+ context "when appending a nil to the end of an embedded list" do
3319
+
3320
+ let(:person) do
3321
+ Person.create! phone_numbers: []
3322
+ end
3323
+
3324
+ before do
3325
+ person.phone_numbers << home_phone
3326
+ person.phone_numbers << office_phone
3327
+ person.phone_numbers << nil
3328
+ person.save!
3329
+ end
3330
+
3331
+ it "ignores the nil and persist the remaining items" do
3332
+ reloaded = Person.find(person.id)
3333
+ expect(reloaded.phone_numbers).to eq(person.phone_numbers)
3334
+ end
3335
+ end
3336
+ end
3337
+ end
3338
+
3339
+ context "when accessing the parent in a destroy callback" do
3340
+
3341
+ let!(:league) do
3342
+ League.create
3343
+ end
3344
+
3345
+ let!(:division) do
3346
+ league.divisions.create
3347
+ end
3348
+
3349
+ before do
3350
+ league.destroy
3351
+ end
3352
+
3353
+ it "retains the reference to the parent" do
3354
+ expect(league.name).to eq("Destroyed")
3355
+ end
3356
+ end
3357
+
3358
+ context "when updating the parent with all attributes" do
3359
+
3360
+ let!(:person) do
3361
+ Person.create
3362
+ end
3363
+
3364
+ let!(:address) do
3365
+ person.addresses.create
3366
+ end
3367
+
3368
+ before do
3369
+ person.update_attributes(person.attributes)
3370
+ end
3371
+
3372
+ it "does not duplicate the embedded documents" do
3373
+ expect(person.addresses).to eq([ address ])
3374
+ end
3375
+
3376
+ it "does not persist duplicate embedded documents" do
3377
+ expect(person.reload.addresses).to eq([ address ])
3378
+ end
3379
+ end
3380
+
3381
+ context "when embedding children named versions" do
3382
+
3383
+ let(:acolyte) do
3384
+ Acolyte.create(name: "test")
3385
+ end
3386
+
3387
+ context "when creating a child" do
3388
+
3389
+ let(:version) do
3390
+ acolyte.versions.create(number: 1)
3391
+ end
3392
+
3393
+ it "allows the operation" do
3394
+ expect(version.number).to eq(1)
3395
+ end
3396
+
3397
+ context "when reloading the parent" do
3398
+
3399
+ let(:from_db) do
3400
+ acolyte.reload
3401
+ end
3402
+
3403
+ it "saves the child versions" do
3404
+ expect(from_db.versions).to eq([ version ])
3405
+ end
3406
+ end
3407
+ end
3408
+ end
3409
+
3410
+ context "when validating the parent before accessing the child" do
3411
+
3412
+ let!(:account) do
3413
+ Account.new(name: "Testing").tap do |acct|
3414
+ acct.memberships.build
3415
+ acct.save
3416
+ end
3417
+ end
3418
+
3419
+ let(:from_db) do
3420
+ Account.first
3421
+ end
3422
+
3423
+ context "when saving" do
3424
+
3425
+ before do
3426
+ account.name = ""
3427
+ account.save
3428
+ end
3429
+
3430
+ it "does not lose the parent reference" do
3431
+ expect(from_db.memberships.first.account).to eq(account)
3432
+ end
3433
+ end
3434
+
3435
+ context "when updating attributes" do
3436
+
3437
+ before do
3438
+ from_db.update_attributes(name: "")
3439
+ end
3440
+
3441
+ it "does not lose the parent reference" do
3442
+ expect(from_db.memberships.first.account).to eq(account)
3443
+ end
3444
+ end
3445
+ end
3446
+
3447
+ context "when moving an embedded document from one parent to another" do
3448
+
3449
+ let!(:person_one) do
3450
+ Person.create
3451
+ end
3452
+
3453
+ let!(:person_two) do
3454
+ Person.create
3455
+ end
3456
+
3457
+ let!(:address) do
3458
+ person_one.addresses.create(street: "Kudamm")
3459
+ end
3460
+
3461
+ before do
3462
+ person_two.addresses << address
3463
+ end
3464
+
3465
+ it "adds the document to the new paarent" do
3466
+ expect(person_two.addresses).to eq([ address ])
3467
+ end
3468
+
3469
+ it "sets the new parent on the document" do
3470
+ expect(address._parent).to eq(person_two)
3471
+ end
3472
+
3473
+ context "when reloading the documents" do
3474
+
3475
+ before do
3476
+ person_one.reload
3477
+ person_two.reload
3478
+ end
3479
+
3480
+ it "persists the change to the new parent" do
3481
+ expect(person_two.addresses).to eq([ address ])
3482
+ end
3483
+
3484
+ it "keeps the address on the previous document" do
3485
+ expect(person_one.addresses).to eq([ address ])
3486
+ end
3487
+ end
3488
+ end
3489
+
3490
+ context "when the relation has a default scope" do
3491
+
3492
+ let!(:person) do
3493
+ Person.create
3494
+ end
3495
+
3496
+ context "when the default scope is a sort" do
3497
+
3498
+ let(:cough) do
3499
+ Symptom.new(name: "cough")
3500
+ end
3501
+
3502
+ let(:headache) do
3503
+ Symptom.new(name: "headache")
3504
+ end
3505
+
3506
+ let(:nausea) do
3507
+ Symptom.new(name: "nausea")
3508
+ end
3509
+
3510
+ before do
3511
+ person.symptoms.concat([ nausea, cough, headache ])
3512
+ end
3513
+
3514
+ context "when accessing the relation" do
3515
+
3516
+ let(:symptoms) do
3517
+ person.reload.symptoms
3518
+ end
3519
+
3520
+ it "applies the default scope" do
3521
+ expect(symptoms).to eq([ cough, headache, nausea ])
3522
+ end
3523
+ end
3524
+
3525
+ context "when modifying the relation" do
3526
+
3527
+ let(:constipation) do
3528
+ Symptom.new(name: "constipation")
3529
+ end
3530
+
3531
+ before do
3532
+ person.symptoms.push(constipation)
3533
+ end
3534
+
3535
+ context "when reloading" do
3536
+
3537
+ let(:symptoms) do
3538
+ person.reload.symptoms
3539
+ end
3540
+
3541
+ it "applies the default scope" do
3542
+ expect(symptoms).to eq([ constipation, cough, headache, nausea ])
3543
+ end
3544
+ end
3545
+ end
3546
+
3547
+ context "when unscoping the relation" do
3548
+
3549
+ let(:unscoped) do
3550
+ person.reload.symptoms.unscoped
3551
+ end
3552
+
3553
+ it "removes the default scope" do
3554
+ expect(unscoped).to eq([ nausea, cough, headache ])
3555
+ end
3556
+ end
3557
+ end
3558
+ end
3559
+
3560
+ context "when indexing the documents" do
3561
+
3562
+ let!(:person) do
3563
+ Person.create
3564
+ end
3565
+
3566
+ context "when the documents have a limiting default scope" do
3567
+
3568
+ let(:active) do
3569
+ Appointment.new
3570
+ end
3571
+
3572
+ let(:inactive) do
3573
+ Appointment.new(active: false)
3574
+ end
3575
+
3576
+ before do
3577
+ person.appointments.concat([ inactive, active ])
3578
+ end
3579
+
3580
+ let(:relation) do
3581
+ person.reload.appointments
3582
+ end
3583
+
3584
+ it "retains the unscoped index for the excluded document" do
3585
+ expect(relation.send(:_unscoped).first._index).to eq(0)
3586
+ end
3587
+
3588
+ it "retains the unscoped index for the included document" do
3589
+ expect(relation.first._index).to eq(1)
3590
+ end
3591
+
3592
+ context "when a reindexing operation occurs" do
3593
+
3594
+ before do
3595
+ relation.send(:reindex)
3596
+ end
3597
+
3598
+ it "retains the unscoped index for the excluded document" do
3599
+ expect(relation.send(:_unscoped).first._index).to eq(0)
3600
+ end
3601
+
3602
+ it "retains the unscoped index for the included document" do
3603
+ expect(relation.first._index).to eq(1)
3604
+ end
3605
+ end
3606
+ end
3607
+ end
3608
+
3609
+ context "when the embedded document has an array field" do
3610
+
3611
+ let!(:person) do
3612
+ Person.create
3613
+ end
3614
+
3615
+ let!(:video) do
3616
+ person.videos.create
3617
+ end
3618
+
3619
+ context "when saving the array on a persisted document" do
3620
+
3621
+ before do
3622
+ video.genres = [ "horror", "scifi" ]
3623
+ video.save
3624
+ end
3625
+
3626
+ it "sets the value" do
3627
+ expect(video.genres).to eq([ "horror", "scifi" ])
3628
+ end
3629
+
3630
+ it "persists the value" do
3631
+ expect(video.reload.genres).to eq([ "horror", "scifi" ])
3632
+ end
3633
+
3634
+ context "when reloading the parent" do
3635
+
3636
+ let!(:loaded_person) do
3637
+ Person.find(person.id)
3638
+ end
3639
+
3640
+ let!(:loaded_video) do
3641
+ loaded_person.videos.find(video.id)
3642
+ end
3643
+
3644
+ context "when writing a new array value" do
3645
+
3646
+ before do
3647
+ loaded_video.genres = [ "comedy" ]
3648
+ loaded_video.save
3649
+ end
3650
+
3651
+ it "sets the new value" do
3652
+ expect(loaded_video.genres).to eq([ "comedy" ])
3653
+ end
3654
+
3655
+ it "persists the new value" do
3656
+ expect(loaded_video.reload.genres).to eq([ "comedy" ])
3657
+ end
3658
+ end
3659
+ end
3660
+ end
3661
+ end
3662
+
3663
+ context "when destroying an embedded document" do
3664
+
3665
+ let(:person) do
3666
+ Person.create
3667
+ end
3668
+
3669
+ let!(:address_one) do
3670
+ person.addresses.create(street: "hobrecht")
3671
+ end
3672
+
3673
+ let!(:address_two) do
3674
+ person.addresses.create(street: "maybachufer")
3675
+ end
3676
+
3677
+ before do
3678
+ address_one.destroy
3679
+ end
3680
+
3681
+ it "destroys the document" do
3682
+ expect(address_one).to be_destroyed
3683
+ end
3684
+
3685
+ it "reindexes the relation" do
3686
+ expect(address_two._index).to eq(0)
3687
+ end
3688
+
3689
+ it "removes the document from the unscoped" do
3690
+ expect(person.addresses.send(:_unscoped)).to_not include(address_one)
3691
+ end
3692
+
3693
+ context "when subsequently updating the next document" do
3694
+
3695
+ before do
3696
+ address_two.update_attribute(:number, 10)
3697
+ end
3698
+
3699
+ let(:addresses) do
3700
+ person.reload.addresses
3701
+ end
3702
+
3703
+ it "updates the correct document" do
3704
+ expect(addresses.first.number).to eq(10)
3705
+ end
3706
+
3707
+ it "does not add additional documents" do
3708
+ expect(addresses.count).to eq(1)
3709
+ end
3710
+ end
3711
+ end
3712
+
3713
+ context "when adding a document" do
3714
+
3715
+ let(:person) do
3716
+ Person.new
3717
+ end
3718
+
3719
+ let(:address_one) do
3720
+ Address.new(street: "hobrecht")
3721
+ end
3722
+
3723
+ let(:first_add) do
3724
+ person.addresses.push(address_one)
3725
+ end
3726
+
3727
+ context "when chaining a second add" do
3728
+
3729
+ let(:address_two) do
3730
+ Address.new(street: "friedel")
3731
+ end
3732
+
3733
+ let(:result) do
3734
+ first_add.push(address_two)
3735
+ end
3736
+
3737
+ it "adds both documents" do
3738
+ expect(result).to eq([ address_one, address_two ])
3739
+ end
3740
+ end
3741
+ end
3742
+
3743
+ context "when the association has an order defined" do
3744
+
3745
+ let(:person) do
3746
+ Person.create
3747
+ end
3748
+
3749
+ let(:message_one) do
3750
+ Message.new(priority: 5, body: 'This is a test')
3751
+ end
3752
+
3753
+ let(:message_two) do
3754
+ Message.new(priority: 10, body: 'This is a test')
3755
+ end
3756
+
3757
+ let(:message_three) do
3758
+ Message.new(priority: 20, body: 'Zee test')
3759
+ end
3760
+
3761
+ before do
3762
+ person.messages.push(message_one, message_two, message_three)
3763
+ end
3764
+
3765
+ let(:criteria) do
3766
+ person.messages.order_by(:body.asc, :priority.desc)
3767
+ end
3768
+
3769
+ it "properly orders the related objects" do
3770
+ expect(criteria.to_a).to eq([message_two, message_one, message_three])
3771
+ end
3772
+
3773
+ context "when the field to order on is an array of documents" do
3774
+
3775
+ before do
3776
+ person.aliases = [ { name: "A", priority: 3 }, { name: "B", priority: 4 }]
3777
+ person.save
3778
+ end
3779
+
3780
+ let!(:person2) do
3781
+ Person.create( aliases: [ { name: "C", priority: 1 }, { name: "D", priority: 2 }])
3782
+ end
3783
+
3784
+ it "allows ordering on a key of an embedded document" do
3785
+ expect(Person.all.order_by("aliases.0.priority" => 1).first).to eq(person2)
3786
+ end
3787
+ end
3788
+ end
3789
+
3790
+ context "when using dot notation in a criteria" do
3791
+
3792
+ let(:person) do
3793
+ Person.new
3794
+ end
3795
+
3796
+ let!(:address) do
3797
+ person.addresses.build(street: "hobrecht")
3798
+ end
3799
+
3800
+ let!(:location) do
3801
+ address.locations.build(number: 5)
3802
+ end
3803
+
3804
+ let(:criteria) do
3805
+ person.addresses.where("locations.number" => { "$gt" => 3 })
3806
+ end
3807
+
3808
+ it "allows the dot notation criteria" do
3809
+ expect(criteria).to eq([ address ])
3810
+ end
3811
+ end
3812
+
3813
+ context "when updating multiple levels in one update" do
3814
+
3815
+ let!(:person) do
3816
+ Person.create(
3817
+ addresses: [
3818
+ { locations: [{ name: "home" }]}
3819
+ ]
3820
+ )
3821
+ end
3822
+
3823
+ context "when updating with hashes" do
3824
+
3825
+ let(:from_db) do
3826
+ Person.find(person.id)
3827
+ end
3828
+
3829
+ before do
3830
+ from_db.update_attributes(
3831
+ addresses: [
3832
+ { locations: [{ name: "work" }]}
3833
+ ]
3834
+ )
3835
+ end
3836
+
3837
+ let(:updated) do
3838
+ person.reload.addresses.first.locations.first
3839
+ end
3840
+
3841
+ it "updates the nested document" do
3842
+ expect(updated.name).to eq("work")
3843
+ end
3844
+ end
3845
+ end
3846
+
3847
+ context "when the embedded relation sorts on a boolean" do
3848
+
3849
+ let(:circuit) do
3850
+ Circuit.create
3851
+ end
3852
+
3853
+ let!(:bus_one) do
3854
+ circuit.buses.create(saturday: true)
3855
+ end
3856
+
3857
+ let!(:bus_two) do
3858
+ circuit.buses.create(saturday: false)
3859
+ end
3860
+
3861
+ it "orders properly with the boolean" do
3862
+ expect(circuit.reload.buses).to eq([ bus_two, bus_one ])
3863
+ end
3864
+ end
3865
+
3866
+ context "when batch replacing multiple relations in a single update" do
3867
+
3868
+ let(:document) do
3869
+ Person.create
3870
+ end
3871
+
3872
+ let(:person) do
3873
+ Person.find(document.id)
3874
+ end
3875
+
3876
+ let!(:symptom_one) do
3877
+ person.symptoms.create
3878
+ end
3879
+
3880
+ let!(:symptom_two) do
3881
+ person.symptoms.create
3882
+ end
3883
+
3884
+ let!(:appointment_one) do
3885
+ person.appointments.create
3886
+ end
3887
+
3888
+ let!(:appointment_two) do
3889
+ person.appointments.create
3890
+ end
3891
+
3892
+ before do
3893
+ person.update_attributes(
3894
+ appointments: [ appointment_one.as_document, appointment_two.as_document ],
3895
+ symptoms: [ symptom_one.as_document, symptom_two.as_document ]
3896
+ )
3897
+ end
3898
+
3899
+ it "does not duplicate the first relation" do
3900
+ expect(person.reload.symptoms.count).to eq(2)
3901
+ end
3902
+
3903
+ it "does not duplicate the second relation" do
3904
+ expect(person.reload.appointments.count).to eq(2)
3905
+ end
3906
+ end
3907
+
3908
+ context "when pushing with a before_add callback" do
3909
+
3910
+ let(:artist) do
3911
+ Artist.new
3912
+ end
3913
+
3914
+ let(:song) do
3915
+ Song.new
3916
+ end
3917
+
3918
+ context "when no errors are raised" do
3919
+
3920
+ before do
3921
+ artist.songs << song
3922
+ end
3923
+
3924
+ it "executes the callback" do
3925
+ expect(artist.before_add_called).to be true
3926
+ end
3927
+
3928
+ it "executes the callback as proc" do
3929
+ expect(song.before_add_called).to be true
3930
+ end
3931
+
3932
+ it "adds the document to the relation" do
3933
+ expect(artist.songs).to eq([song])
3934
+ end
3935
+ end
3936
+
3937
+ context "with errors" do
3938
+
3939
+ before do
3940
+ expect(artist).to receive(:before_add_song).and_raise
3941
+ begin; artist.songs << song; rescue; end
3942
+ end
3943
+
3944
+ it "does not add the document to the relation" do
3945
+ expect(artist.songs).to be_empty
3946
+ end
3947
+ end
3948
+ end
3949
+
3950
+ context "when pushing with an after_add callback" do
3951
+
3952
+ let(:artist) do
3953
+ Artist.new
3954
+ end
3955
+
3956
+ let(:label) do
3957
+ Label.new
3958
+ end
3959
+
3960
+ it "executes the callback" do
3961
+ artist.labels << label
3962
+ expect(artist.after_add_called).to be true
3963
+ end
3964
+
3965
+ context "when errors are raised" do
3966
+
3967
+ before do
3968
+ expect(artist).to receive(:after_add_label).and_raise
3969
+ begin; artist.labels << label; rescue; end
3970
+ end
3971
+
3972
+ it "adds the document to the relation" do
3973
+ expect(artist.labels).to eq([ label ])
3974
+ end
3975
+ end
3976
+ end
3977
+
3978
+ context "#delete, or #clear, or #pop, or #shift with before_remove callback" do
3979
+
3980
+ let(:artist) do
3981
+ Artist.new
3982
+ end
3983
+
3984
+ let(:song) do
3985
+ Song.new
3986
+ end
3987
+
3988
+ before do
3989
+ artist.songs << song
3990
+ end
3991
+
3992
+ context "when no errors are raised" do
3993
+
3994
+ describe "#delete" do
3995
+
3996
+ before do
3997
+ artist.songs.delete(song)
3998
+ end
3999
+
4000
+ it "executes the callback" do
4001
+ expect(artist.before_remove_embedded_called).to be true
4002
+ end
4003
+
4004
+ it "removes the document from the relation" do
4005
+ expect(artist.songs).to be_empty
4006
+ end
4007
+ end
4008
+
4009
+ describe "#clear" do
4010
+
4011
+ before do
4012
+ artist.songs.clear
4013
+ end
4014
+
4015
+ it "executes the callback" do
4016
+ expect(artist.before_remove_embedded_called).to be true
4017
+ end
4018
+
4019
+ it "shoud clear the relation" do
4020
+ expect(artist.songs).to be_empty
4021
+ end
4022
+ end
4023
+
4024
+ describe "#pop" do
4025
+
4026
+ before do
4027
+ artist.songs.pop
4028
+ end
4029
+
4030
+ it "executes the callback" do
4031
+ artist.songs.pop
4032
+ expect(artist.before_remove_embedded_called).to be true
4033
+ end
4034
+ end
4035
+
4036
+ describe "#shift" do
4037
+
4038
+ before do
4039
+ artist.songs.shift
4040
+ end
4041
+
4042
+ it "executes the callback" do
4043
+ artist.songs.shift
4044
+ expect(artist.before_remove_embedded_called).to be true
4045
+ end
4046
+ end
4047
+ end
4048
+
4049
+ context "when errors are raised" do
4050
+
4051
+ before do
4052
+ expect(artist).to receive(:before_remove_song).and_raise
4053
+ end
4054
+
4055
+ describe "#delete" do
4056
+
4057
+ it "does not remove the document from the relation" do
4058
+ begin; artist.songs.delete(song); rescue; end
4059
+ expect(artist.songs).to eq([ song ])
4060
+ end
4061
+ end
4062
+
4063
+ describe "#clear" do
4064
+
4065
+ before do
4066
+ begin; artist.songs.clear; rescue; end
4067
+ end
4068
+
4069
+ it "removes the documents from the relation" do
4070
+ expect(artist.songs).to eq([ song ])
4071
+ end
4072
+ end
4073
+
4074
+ describe "#pop" do
4075
+
4076
+ before do
4077
+ begin; artist.songs.pop; rescue; end
4078
+ end
4079
+
4080
+ it "should remove from collection" do
4081
+ expect(artist.songs).to eq([ song ])
4082
+ end
4083
+ end
4084
+
4085
+ describe "#shift" do
4086
+
4087
+ before do
4088
+ begin; artist.songs.shift; rescue; end
4089
+ end
4090
+
4091
+ it "should remove from collection" do
4092
+ expect(artist.songs).to eq([ song ])
4093
+ end
4094
+ end
4095
+ end
4096
+ end
4097
+
4098
+ context "#delete, or #clear, or #pop, or #shift with after_remove callback" do
4099
+
4100
+ let(:artist) do
4101
+ Artist.new
4102
+ end
4103
+
4104
+ let(:label) do
4105
+ Label.new
4106
+ end
4107
+
4108
+ before do
4109
+ artist.labels << label
4110
+ end
4111
+
4112
+ context "when no errors are raised" do
4113
+
4114
+ describe "#delete" do
4115
+ before do
4116
+ artist.labels.delete(label)
4117
+ end
4118
+
4119
+ it "executes the callback" do
4120
+ expect(artist.after_remove_embedded_called).to be true
4121
+ end
4122
+ end
4123
+
4124
+ describe "#clear" do
4125
+
4126
+ before do
4127
+ artist.labels.clear
4128
+ end
4129
+
4130
+ it "executes the callback" do
4131
+ artist.labels.clear
4132
+ expect(artist.after_remove_embedded_called).to be true
4133
+ end
4134
+ end
4135
+
4136
+ describe "#pop" do
4137
+
4138
+ before do
4139
+ artist.labels.pop
4140
+ end
4141
+
4142
+ it "executes the callback" do
4143
+ artist.labels.pop
4144
+ expect(artist.after_remove_embedded_called).to be true
4145
+ end
4146
+ end
4147
+
4148
+ describe "#shift" do
4149
+
4150
+ before do
4151
+ artist.labels.shift
4152
+ end
4153
+
4154
+ it "executes the callback" do
4155
+ artist.labels.shift
4156
+ expect(artist.after_remove_embedded_called).to be true
4157
+ end
4158
+ end
4159
+ end
4160
+
4161
+ context "when errors are raised" do
4162
+
4163
+ before do
4164
+ expect(artist).to receive(:after_remove_label).and_raise
4165
+ end
4166
+
4167
+ describe "#delete" do
4168
+
4169
+ before do
4170
+ begin; artist.labels.delete(label); rescue; end
4171
+ end
4172
+
4173
+ it "removes the document from the relation" do
4174
+ expect(artist.labels).to be_empty
4175
+ end
4176
+ end
4177
+
4178
+ describe "#clear" do
4179
+
4180
+ before do
4181
+ begin; artist.labels.clear; rescue; end
4182
+ end
4183
+
4184
+ it "should remove from collection" do
4185
+ expect(artist.labels).to be_empty
4186
+ end
4187
+ end
4188
+
4189
+ describe "#pop" do
4190
+
4191
+ before do
4192
+ begin; artist.labels.pop; rescue; end
4193
+ end
4194
+
4195
+ it "should remove from collection" do
4196
+ expect(artist.labels).to be_empty
4197
+ end
4198
+ end
4199
+
4200
+ describe "#shift" do
4201
+
4202
+ before do
4203
+ begin; artist.labels.shift; rescue; end
4204
+ end
4205
+
4206
+ it "should remove from collection" do
4207
+ expect(artist.labels).to be_empty
4208
+ end
4209
+ end
4210
+ end
4211
+ end
4212
+
4213
+ context "when saving at the parent level" do
4214
+
4215
+ let!(:server) do
4216
+ Server.new(name: "staging")
4217
+ end
4218
+
4219
+ let!(:filesystem) do
4220
+ server.filesystems.build
4221
+ end
4222
+
4223
+ context "when the parent has an after create callback" do
4224
+
4225
+ before do
4226
+ server.save
4227
+ end
4228
+
4229
+ it "does not push the embedded documents twice" do
4230
+ expect(server.reload.filesystems.count).to eq(1)
4231
+ end
4232
+ end
4233
+ end
4234
+
4235
+ context "when embedded documents are stored without ids" do
4236
+
4237
+ let!(:band) do
4238
+ Band.create(name: "Moderat")
4239
+ end
4240
+
4241
+ before do
4242
+ band.collection.
4243
+ find(_id: band.id).
4244
+ update_one("$set" => { records: [{ name: "Moderat" }]})
4245
+ end
4246
+
4247
+ context "when loading the documents" do
4248
+
4249
+ before do
4250
+ band.reload
4251
+ end
4252
+
4253
+ let(:record) do
4254
+ band.records.first
4255
+ end
4256
+
4257
+ it "creates proper documents from the db" do
4258
+ expect(record.name).to eq("Moderat")
4259
+ end
4260
+
4261
+ it "assigns ids to the documents" do
4262
+ expect(record.id).to_not be_nil
4263
+ end
4264
+
4265
+ context "when subsequently updating the documents" do
4266
+
4267
+ before do
4268
+ record.update_attribute(:name, "Apparat")
4269
+ end
4270
+
4271
+ it "updates the document" do
4272
+ expect(record.name).to eq("Apparat")
4273
+ end
4274
+
4275
+ it "persists the change" do
4276
+ expect(record.reload.name).to eq("Apparat")
4277
+ end
4278
+ end
4279
+ end
4280
+ end
4281
+
4282
+ context "deleting embedded documents" do
4283
+
4284
+ it "able to delete embedded documents upon condition" do
4285
+ company = Company.new
4286
+ 4.times { |i| company.staffs << Staff.new(age: 50 + i)}
4287
+ 2.times { |i| company.staffs << Staff.new(age: 40)}
4288
+ company.save
4289
+ company.staffs.delete_if {|x| x.age >= 50}
4290
+ expect(company.staffs.count).to eq(2)
4291
+ end
4292
+ end
4293
+
4294
+ context "when substituting polymorphic documents" do
4295
+
4296
+ before(:all) do
4297
+ class DNS; end
4298
+
4299
+ class DNS::Zone
4300
+ include Mongoid::Document
4301
+ embeds_many :rrsets, class_name: 'DNS::RRSet', inverse_of: :zone
4302
+ embeds_one :soa, class_name: 'DNS::Record', as: :container
4303
+ end
4304
+
4305
+ class DNS::RRSet
4306
+ include Mongoid::Document
4307
+ embedded_in :zone, class_name: 'DNS::Zone', inverse_of: :rrsets
4308
+ embeds_many :records, class_name: 'DNS::Record', as: :container
4309
+ end
4310
+
4311
+ class DNS::Record
4312
+ include Mongoid::Document
4313
+ embedded_in :container, polymorphic: true
4314
+ end
4315
+ end
4316
+
4317
+ after(:all) do
4318
+ Object.send(:remove_const, :DNS)
4319
+ end
4320
+
4321
+ context "when the parent is new" do
4322
+
4323
+ let(:zone) do
4324
+ DNS::Zone.new
4325
+ end
4326
+
4327
+ let(:soa_1) do
4328
+ DNS::Record.new
4329
+ end
4330
+
4331
+ context "when replacing the set document" do
4332
+
4333
+ let(:soa_2) do
4334
+ DNS::Record.new
4335
+ end
4336
+
4337
+ before do
4338
+ zone.soa = soa_1
4339
+ end
4340
+
4341
+ it "properly sets the association metadata" do
4342
+ expect(zone.soa = soa_2).to eq(soa_2)
4343
+ end
4344
+ end
4345
+
4346
+ context "when deleting the set document" do
4347
+
4348
+ let(:soa_2) do
4349
+ DNS::Record.new
4350
+ end
4351
+
4352
+ before do
4353
+ zone.soa = soa_1
4354
+ end
4355
+
4356
+ it "properly sets the association metadata" do
4357
+ expect(zone.soa.delete).to be true
4358
+ end
4359
+ end
4360
+ end
4361
+
4362
+ context "when the parent is persisted" do
4363
+
4364
+ let(:zone) do
4365
+ DNS::Zone.create
4366
+ end
4367
+
4368
+ let(:soa_1) do
4369
+ DNS::Record.new
4370
+ end
4371
+
4372
+ context "when replacing the set document" do
4373
+
4374
+ let(:soa_2) do
4375
+ DNS::Record.new
4376
+ end
4377
+
4378
+ before do
4379
+ zone.soa = soa_1
4380
+ end
4381
+
4382
+ it "properly sets the association" do
4383
+ expect(zone.soa = soa_2).to eq(soa_2)
4384
+ end
4385
+ end
4386
+
4387
+ context "when deleting the set document" do
4388
+
4389
+ let(:soa_2) do
4390
+ DNS::Record.new
4391
+ end
4392
+
4393
+ before do
4394
+ zone.soa = soa_1
4395
+ end
4396
+
4397
+ it "properly sets the association" do
4398
+ expect(zone.soa.delete).to be true
4399
+ end
4400
+ end
4401
+ end
4402
+ end
4403
+ end