mongoid 3.1.4 → 3.1.5

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