mongoid 6.4.8 → 7.5.4

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