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,3632 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Relations::Referenced::Many do
4
+
5
+ before :all do
6
+ Mongoid.raise_not_found_error = true
7
+
8
+ Drug.belongs_to :person, primary_key: :username
9
+ Person.has_many :drugs, validate: false, primary_key: :username
10
+ end
11
+
12
+ after :all do
13
+ Drug.belongs_to :person, counter_cache: true
14
+ Person.has_many :drugs, validate: false
15
+ end
16
+
17
+ [ :<<, :push ].each do |method|
18
+
19
+ describe "##{method}" do
20
+
21
+ context "when the relations are not polymorphic" do
22
+
23
+ context "when the parent is a new record" do
24
+
25
+ let(:person) do
26
+ Person.new
27
+ end
28
+
29
+ context "when the child is new" do
30
+
31
+ let(:post) do
32
+ Post.new
33
+ end
34
+
35
+ let!(:added) do
36
+ person.posts.send(method, post)
37
+ end
38
+
39
+ it "sets the foreign key on the relation" do
40
+ post.person_id.should eq(person.id)
41
+ end
42
+
43
+ it "sets the base on the inverse relation" do
44
+ post.person.should eq(person)
45
+ end
46
+
47
+ it "sets the same instance on the inverse relation" do
48
+ post.person.should eql(person)
49
+ end
50
+
51
+ it "does not save the target" do
52
+ post.should be_new_record
53
+ end
54
+
55
+ it "adds the document to the target" do
56
+ person.posts.size.should eq(1)
57
+ end
58
+
59
+ it "returns the relation" do
60
+ added.should eq(person.posts)
61
+ end
62
+ end
63
+
64
+ context "when the child is persisted" do
65
+
66
+ let(:post) do
67
+ Post.create
68
+ end
69
+
70
+ before do
71
+ person.posts.send(method, post)
72
+ end
73
+
74
+ it "sets the foreign key on the relation" do
75
+ post.person_id.should eq(person.id)
76
+ end
77
+
78
+ it "sets the base on the inverse relation" do
79
+ post.person.should eq(person)
80
+ end
81
+
82
+ it "sets the same instance on the inverse relation" do
83
+ post.person.should eql(person)
84
+ end
85
+
86
+ it "does not save the parent" do
87
+ person.should be_new_record
88
+ end
89
+
90
+ it "adds the document to the target" do
91
+ person.posts.size.should eq(1)
92
+ end
93
+
94
+ context "when subsequently saving the parent" do
95
+
96
+ before do
97
+ person.save
98
+ post.save
99
+ end
100
+
101
+ it "returns the correct count of the relation" do
102
+ person.posts.count.should eq(1)
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ context "when appending in a parent create block" do
109
+
110
+ let!(:post) do
111
+ Post.create(title: "testing")
112
+ end
113
+
114
+ let!(:person) do
115
+ Person.create do |doc|
116
+ doc.posts << post
117
+ end
118
+ end
119
+
120
+ it "adds the documents to the relation" do
121
+ person.posts.should eq([ post ])
122
+ end
123
+
124
+ it "sets the foreign key on the inverse relation" do
125
+ post.person_id.should eq(person.id)
126
+ end
127
+
128
+ it "saves the target" do
129
+ post.should be_persisted
130
+ end
131
+
132
+ it "adds the correct number of documents" do
133
+ person.posts.size.should eq(1)
134
+ end
135
+
136
+ it "persists the link" do
137
+ person.reload.posts.should eq([ post ])
138
+ end
139
+ end
140
+
141
+ context "when the parent is not a new record" do
142
+
143
+ let(:person) do
144
+ Person.create
145
+ end
146
+
147
+ let(:post) do
148
+ Post.new
149
+ end
150
+
151
+ before do
152
+ person.posts.send(method, post)
153
+ end
154
+
155
+ it "sets the foreign key on the relation" do
156
+ post.person_id.should eq(person.id)
157
+ end
158
+
159
+ it "sets the base on the inverse relation" do
160
+ post.person.should eq(person)
161
+ end
162
+
163
+ it "sets the same instance on the inverse relation" do
164
+ post.person.should eql(person)
165
+ end
166
+
167
+ it "saves the target" do
168
+ post.should be_persisted
169
+ end
170
+
171
+ it "adds the document to the target" do
172
+ person.posts.count.should eq(1)
173
+ end
174
+
175
+ it "increments the counter cache" do
176
+ person.reload.posts_count.should eq(1)
177
+ end
178
+
179
+ context "when documents already exist on the relation" do
180
+
181
+ let(:post_two) do
182
+ Post.new(title: "Test")
183
+ end
184
+
185
+ before do
186
+ person.posts.send(method, post_two)
187
+ end
188
+
189
+ it "sets the foreign key on the relation" do
190
+ post_two.person_id.should eq(person.id)
191
+ end
192
+
193
+ it "sets the base on the inverse relation" do
194
+ post_two.person.should eq(person)
195
+ end
196
+
197
+ it "sets the same instance on the inverse relation" do
198
+ post_two.person.should eql(person)
199
+ end
200
+
201
+ it "saves the target" do
202
+ post_two.should be_persisted
203
+ end
204
+
205
+ it "adds the document to the target" do
206
+ person.posts.count.should eq(2)
207
+ end
208
+
209
+ it "increments the counter cache" do
210
+ person.reload.posts_count.should eq(2)
211
+ end
212
+
213
+ it "contains the initial document in the target" do
214
+ person.posts.should include(post)
215
+ end
216
+
217
+ it "contains the added document in the target" do
218
+ person.posts.should include(post_two)
219
+ end
220
+ end
221
+ end
222
+ end
223
+
224
+ context "when.with(safe: true).adding to the relation" do
225
+
226
+ let(:person) do
227
+ Person.create
228
+ end
229
+
230
+ context "when the operation succeeds" do
231
+
232
+ let(:post) do
233
+ Post.new
234
+ end
235
+
236
+ before do
237
+ person.posts.with(safe: true).send(method, post)
238
+ end
239
+
240
+ it "adds the document to the relation" do
241
+ person.posts.should eq([ post ])
242
+ end
243
+ end
244
+
245
+ context "when the operation fails" do
246
+
247
+ let!(:existing) do
248
+ Post.create
249
+ end
250
+
251
+ let(:post) do
252
+ Post.new do |doc|
253
+ doc._id = existing.id
254
+ end
255
+ end
256
+
257
+ it "raises an error" do
258
+ expect {
259
+ person.posts.with(safe: true).send(method, post)
260
+ }.to raise_error(Moped::Errors::OperationFailure)
261
+ end
262
+ end
263
+ end
264
+
265
+ context "when the relations are polymorphic" do
266
+
267
+ context "when the parent is a new record" do
268
+
269
+ let(:movie) do
270
+ Movie.new
271
+ end
272
+
273
+ let(:rating) do
274
+ Rating.new
275
+ end
276
+
277
+ before do
278
+ movie.ratings.send(method, rating)
279
+ end
280
+
281
+ it "sets the foreign key on the relation" do
282
+ rating.ratable_id.should eq(movie.id)
283
+ end
284
+
285
+ it "does not set the inverse field on the relation" do
286
+ rating.ratable_field.should be_nil
287
+ end
288
+
289
+ it "sets the base on the inverse relation" do
290
+ rating.ratable.should eq(movie)
291
+ end
292
+
293
+ it "does not save the target" do
294
+ rating.should be_new_record
295
+ end
296
+
297
+ it "adds the document to the target" do
298
+ movie.ratings.size.should eq(1)
299
+ end
300
+ end
301
+
302
+ context "when the parent is not a new record" do
303
+
304
+ let(:movie) do
305
+ Movie.create
306
+ end
307
+
308
+ let(:rating) do
309
+ Rating.new
310
+ end
311
+
312
+ before do
313
+ movie.ratings.send(method, rating)
314
+ end
315
+
316
+ it "sets the foreign key on the relation" do
317
+ rating.ratable_id.should eq(movie.id)
318
+ end
319
+
320
+ it "does not set the inverse field on the relation" do
321
+ rating.ratable_field.should be_nil
322
+ end
323
+
324
+ it "sets the base on the inverse relation" do
325
+ rating.ratable.should eq(movie)
326
+ end
327
+
328
+ it "saves the target" do
329
+ rating.should be_persisted
330
+ end
331
+
332
+ it "adds the document to the target" do
333
+ movie.ratings.count.should eq(1)
334
+ end
335
+ end
336
+ end
337
+ end
338
+ end
339
+
340
+ describe "#=" do
341
+
342
+ context "when the relation is not polymorphic" do
343
+
344
+ context "when the parent is a new record" do
345
+
346
+ let(:person) do
347
+ Person.new
348
+ end
349
+
350
+ let(:post) do
351
+ Post.new
352
+ end
353
+
354
+ before do
355
+ person.posts = [ post ]
356
+ end
357
+
358
+ it "sets the target of the relation" do
359
+ person.posts.target.should eq([ post ])
360
+ end
361
+
362
+ it "sets the foreign key on the relation" do
363
+ post.person_id.should eq(person.id)
364
+ end
365
+
366
+ it "sets the base on the inverse relation" do
367
+ post.person.should eq(person)
368
+ end
369
+
370
+ it "does not save the target" do
371
+ post.should_not be_persisted
372
+ end
373
+ end
374
+
375
+ context "when the parent is not a new record" do
376
+
377
+ let(:person) do
378
+ Person.create
379
+ end
380
+
381
+ let(:post) do
382
+ Post.new
383
+ end
384
+
385
+ before do
386
+ person.posts = [ post ]
387
+ end
388
+
389
+ it "sets the target of the relation" do
390
+ person.posts.target.should eq([ post ])
391
+ end
392
+
393
+ it "sets the foreign key of the relation" do
394
+ post.person_id.should eq(person.id)
395
+ end
396
+
397
+ it "sets the base on the inverse relation" do
398
+ post.person.should eq(person)
399
+ end
400
+
401
+ it "saves the target" do
402
+ post.should be_persisted
403
+ end
404
+
405
+ context "when replacing the relation with the same documents" do
406
+
407
+ context "when using the same in memory instance" do
408
+
409
+ before do
410
+ person.posts = [ post ]
411
+ end
412
+
413
+ it "keeps the relation intact" do
414
+ person.posts.should eq([ post ])
415
+ end
416
+
417
+ it "does not delete the relation" do
418
+ person.reload.posts.should eq([ post ])
419
+ end
420
+ end
421
+
422
+ context "when using a new instance" do
423
+
424
+ let(:from_db) do
425
+ Person.find(person.id)
426
+ end
427
+
428
+ before do
429
+ from_db.posts = [ post ]
430
+ end
431
+
432
+ it "keeps the relation intact" do
433
+ from_db.posts.should eq([ post ])
434
+ end
435
+
436
+ it "does not delete the relation" do
437
+ from_db.reload.posts.should eq([ post ])
438
+ end
439
+ end
440
+ end
441
+
442
+ context "when replacing the with a combination of old and new docs" do
443
+
444
+ let(:new_post) do
445
+ Post.create(title: "new post")
446
+ end
447
+
448
+ context "when using the same in memory instance" do
449
+
450
+ before do
451
+ person.posts = [ post, new_post ]
452
+ end
453
+
454
+ it "keeps the relation intact" do
455
+ person.posts.size.should eq(2)
456
+ end
457
+
458
+ it "keeps the first post" do
459
+ person.posts.should include(post)
460
+ end
461
+
462
+ it "keeps the second post" do
463
+ person.posts.should include(new_post)
464
+ end
465
+
466
+ it "does not delete the relation" do
467
+ person.reload.posts.should eq([ post, new_post ])
468
+ end
469
+ end
470
+
471
+ context "when using a new instance" do
472
+
473
+ let(:from_db) do
474
+ Person.find(person.id)
475
+ end
476
+
477
+ before do
478
+ from_db.posts = [ post, new_post ]
479
+ end
480
+
481
+ it "keeps the relation intact" do
482
+ from_db.posts.should eq([ post, new_post ])
483
+ end
484
+
485
+ it "does not delete the relation" do
486
+ from_db.reload.posts.should eq([ post, new_post ])
487
+ end
488
+ end
489
+ end
490
+
491
+ context "when replacing the with a combination of only new docs" do
492
+
493
+ let(:new_post) do
494
+ Post.create(title: "new post")
495
+ end
496
+
497
+ context "when using the same in memory instance" do
498
+
499
+ before do
500
+ person.posts = [ new_post ]
501
+ end
502
+
503
+ it "keeps the relation intact" do
504
+ person.posts.should eq([ new_post ])
505
+ end
506
+
507
+ it "does not delete the relation" do
508
+ person.reload.posts.should eq([ new_post ])
509
+ end
510
+ end
511
+
512
+ context "when using a new instance" do
513
+
514
+ let(:from_db) do
515
+ Person.find(person.id)
516
+ end
517
+
518
+ before do
519
+ from_db.posts = [ new_post ]
520
+ end
521
+
522
+ it "keeps the relation intact" do
523
+ from_db.posts.should eq([ new_post ])
524
+ end
525
+
526
+ it "does not delete the relation" do
527
+ from_db.reload.posts.should eq([ new_post ])
528
+ end
529
+ end
530
+ end
531
+ end
532
+ end
533
+
534
+ context "when the relation is polymorphic" do
535
+
536
+ context "when the parent is a new record" do
537
+
538
+ let(:movie) do
539
+ Movie.new
540
+ end
541
+
542
+ let(:rating) do
543
+ Rating.new
544
+ end
545
+
546
+ before do
547
+ movie.ratings = [ rating ]
548
+ end
549
+
550
+ it "sets the target of the relation" do
551
+ movie.ratings.target.should eq([ rating ])
552
+ end
553
+
554
+ it "sets the foreign key on the relation" do
555
+ rating.ratable_id.should eq(movie.id)
556
+ end
557
+
558
+ it "sets the base on the inverse relation" do
559
+ rating.ratable.should eq(movie)
560
+ end
561
+
562
+ it "does not save the target" do
563
+ rating.should_not be_persisted
564
+ end
565
+ end
566
+
567
+ context "when the parent is not a new record" do
568
+
569
+ let(:movie) do
570
+ Movie.create
571
+ end
572
+
573
+ let(:rating) do
574
+ Rating.new
575
+ end
576
+
577
+ before do
578
+ movie.ratings = [ rating ]
579
+ end
580
+
581
+ it "sets the target of the relation" do
582
+ movie.ratings.target.should eq([ rating ])
583
+ end
584
+
585
+ it "sets the foreign key of the relation" do
586
+ rating.ratable_id.should eq(movie.id)
587
+ end
588
+
589
+ it "sets the base on the inverse relation" do
590
+ rating.ratable.should eq(movie)
591
+ end
592
+
593
+ it "saves the target" do
594
+ rating.should be_persisted
595
+ end
596
+ end
597
+ end
598
+ end
599
+
600
+ describe "#= []" do
601
+
602
+ context "when the parent is persisted" do
603
+
604
+ let(:posts) do
605
+ [ Post.create(title: "1"), Post.create(title: "2") ]
606
+ end
607
+
608
+ let(:person) do
609
+ Person.create(posts: posts)
610
+ end
611
+
612
+ context "when the parent has multiple children" do
613
+
614
+ before do
615
+ person.posts = []
616
+ end
617
+
618
+ it "removes all the children" do
619
+ person.posts.should be_empty
620
+ end
621
+
622
+ it "persists the changes" do
623
+ person.posts(true).should be_empty
624
+ end
625
+ end
626
+ end
627
+ end
628
+
629
+ describe "#= nil" do
630
+
631
+ context "when the relation is not polymorphic" do
632
+
633
+ context "when the parent is a new record" do
634
+
635
+ let(:person) do
636
+ Person.new
637
+ end
638
+
639
+ let(:post) do
640
+ Post.new
641
+ end
642
+
643
+ before do
644
+ person.posts = [ post ]
645
+ person.posts = nil
646
+ end
647
+
648
+ it "sets the relation to an empty array" do
649
+ person.posts.should be_empty
650
+ end
651
+
652
+ it "removed the inverse relation" do
653
+ post.person.should be_nil
654
+ end
655
+
656
+ it "removes the foreign key value" do
657
+ post.person_id.should be_nil
658
+ end
659
+ end
660
+
661
+ context "when the parent is not a new record" do
662
+
663
+ let(:person) do
664
+ Person.create
665
+ end
666
+
667
+ context "when dependent is destructive" do
668
+
669
+ let(:post) do
670
+ Post.new
671
+ end
672
+
673
+ before do
674
+ person.posts = [ post ]
675
+ person.posts = nil
676
+ end
677
+
678
+ it "sets the relation to empty" do
679
+ person.posts.should be_empty
680
+ end
681
+
682
+ it "removed the inverse relation" do
683
+ post.person.should be_nil
684
+ end
685
+
686
+ it "removes the foreign key value" do
687
+ post.person_id.should be_nil
688
+ end
689
+
690
+ it "deletes the target from the database" do
691
+ post.should be_destroyed
692
+ end
693
+ end
694
+
695
+ context "when dependent is not destructive" do
696
+
697
+ let(:drug) do
698
+ Drug.new(name: "Oxycodone")
699
+ end
700
+
701
+ before do
702
+ person.drugs = [ drug ]
703
+ person.drugs = nil
704
+ end
705
+
706
+ it "sets the relation to empty" do
707
+ person.drugs.should be_empty
708
+ end
709
+
710
+ it "removed the inverse relation" do
711
+ drug.person.should be_nil
712
+ end
713
+
714
+ it "removes the foreign key value" do
715
+ drug.person_id.should be_nil
716
+ end
717
+
718
+ it "nullifies the relation" do
719
+ drug.should_not be_destroyed
720
+ end
721
+ end
722
+ end
723
+ end
724
+
725
+ context "when the relation is polymorphic" do
726
+
727
+ context "when the parent is a new record" do
728
+
729
+ let(:movie) do
730
+ Movie.new
731
+ end
732
+
733
+ let(:rating) do
734
+ Rating.new
735
+ end
736
+
737
+ before do
738
+ movie.ratings = [ rating ]
739
+ movie.ratings = nil
740
+ end
741
+
742
+ it "sets the relation to an empty array" do
743
+ movie.ratings.should be_empty
744
+ end
745
+
746
+ it "removed the inverse relation" do
747
+ rating.ratable.should be_nil
748
+ end
749
+
750
+ it "removes the foreign key value" do
751
+ rating.ratable_id.should be_nil
752
+ end
753
+ end
754
+
755
+ context "when the parent is not a new record" do
756
+
757
+ let(:movie) do
758
+ Movie.create
759
+ end
760
+
761
+ let(:rating) do
762
+ Rating.new
763
+ end
764
+
765
+ before do
766
+ movie.ratings = [ rating ]
767
+ movie.ratings = nil
768
+ end
769
+
770
+ it "sets the relation to empty" do
771
+ movie.ratings.should be_empty
772
+ end
773
+
774
+ it "removed the inverse relation" do
775
+ rating.ratable.should be_nil
776
+ end
777
+
778
+ it "removes the foreign key value" do
779
+ rating.ratable_id.should be_nil
780
+ end
781
+
782
+ context "when dependent is nullify" do
783
+
784
+ it "does not delete the target from the database" do
785
+ rating.should_not be_destroyed
786
+ end
787
+ end
788
+ end
789
+ end
790
+ end
791
+
792
+ describe "#\{name}_ids=" do
793
+
794
+ let(:person) do
795
+ Person.new
796
+ end
797
+
798
+ let(:post_one) do
799
+ Post.create
800
+ end
801
+
802
+ let(:post_two) do
803
+ Post.create
804
+ end
805
+
806
+ before do
807
+ person.post_ids = [ post_one.id, post_two.id ]
808
+ end
809
+
810
+ it "calls setter with documents find by given ids" do
811
+ person.posts.should eq([ post_one, post_two ])
812
+ end
813
+ end
814
+
815
+ describe "#\{name}_ids" do
816
+
817
+ let(:posts) do
818
+ [ Post.create, Post.create ]
819
+ end
820
+
821
+ let(:person) do
822
+ Person.create(posts: posts)
823
+ end
824
+
825
+ it "returns ids of documents that are in the relation" do
826
+ person.post_ids.should eq(posts.map(&:id))
827
+ end
828
+ end
829
+
830
+ [ :build, :new ].each do |method|
831
+
832
+ describe "##{method}" do
833
+
834
+ context "when providing scoped mass assignment" do
835
+
836
+ let(:person) do
837
+ Person.new
838
+ end
839
+
840
+ let(:drug) do
841
+ person.drugs.send(
842
+ method,
843
+ { name: "Oxycontin", generic: false }, as: :admin
844
+ )
845
+ end
846
+
847
+ it "sets the attributes for the provided role" do
848
+ drug.name.should eq("Oxycontin")
849
+ end
850
+
851
+ it "does not set the attributes for other roles" do
852
+ drug.generic.should be_nil
853
+ end
854
+ end
855
+
856
+ context "when the relation is not polymorphic" do
857
+
858
+ context "when the parent is a new record" do
859
+
860
+ let(:person) do
861
+ Person.new(title: "sir")
862
+ end
863
+
864
+ let!(:post) do
865
+ person.posts.send(method, title: "$$$")
866
+ end
867
+
868
+ it "sets the foreign key on the relation" do
869
+ post.person_id.should eq(person.id)
870
+ end
871
+
872
+ it "sets the base on the inverse relation" do
873
+ post.person.should eq(person)
874
+ end
875
+
876
+ it "sets the attributes" do
877
+ post.title.should eq("$$$")
878
+ end
879
+
880
+ it "sets the post processed defaults" do
881
+ post.person_title.should eq(person.title)
882
+ end
883
+
884
+ it "does not save the target" do
885
+ post.should be_new_record
886
+ end
887
+
888
+ it "adds the document to the target" do
889
+ person.posts.size.should eq(1)
890
+ end
891
+
892
+ it "does not perform validation" do
893
+ post.errors.should be_empty
894
+ end
895
+ end
896
+
897
+ context "when the parent is not a new record" do
898
+
899
+ let(:person) do
900
+ Person.create
901
+ end
902
+
903
+ let!(:post) do
904
+ person.posts.send(method, text: "Testing")
905
+ end
906
+
907
+ it "sets the foreign key on the relation" do
908
+ post.person_id.should eq(person.id)
909
+ end
910
+
911
+ it "sets the base on the inverse relation" do
912
+ post.person.should eq(person)
913
+ end
914
+
915
+ it "sets the attributes" do
916
+ post.text.should eq("Testing")
917
+ end
918
+
919
+ it "does not save the target" do
920
+ post.should be_new_record
921
+ end
922
+
923
+ it "adds the document to the target" do
924
+ person.posts.size.should eq(1)
925
+ end
926
+ end
927
+ end
928
+
929
+ context "when the relation is polymorphic" do
930
+
931
+ context "when the parent is a subclass" do
932
+
933
+ let(:video_game) do
934
+ VideoGame.create
935
+ end
936
+
937
+ let(:rating) do
938
+ video_game.ratings.build
939
+ end
940
+
941
+ it "sets the parent on the child" do
942
+ expect(rating.ratable).to eq(video_game)
943
+ end
944
+
945
+ it "sets the correct polymorphic type" do
946
+ expect(rating.ratable_type).to eq("VideoGame")
947
+ end
948
+ end
949
+
950
+ context "when the parent is a new record" do
951
+
952
+ let(:movie) do
953
+ Movie.new
954
+ end
955
+
956
+ let!(:rating) do
957
+ movie.ratings.send(method, value: 3)
958
+ end
959
+
960
+ it "sets the foreign key on the relation" do
961
+ rating.ratable_id.should eq(movie.id)
962
+ end
963
+
964
+ it "sets the base on the inverse relation" do
965
+ rating.ratable.should eq(movie)
966
+ end
967
+
968
+ it "sets the attributes" do
969
+ rating.value.should eq(3)
970
+ end
971
+
972
+ it "does not save the target" do
973
+ rating.should be_new_record
974
+ end
975
+
976
+ it "adds the document to the target" do
977
+ movie.ratings.size.should eq(1)
978
+ end
979
+
980
+ it "does not perform validation" do
981
+ rating.errors.should be_empty
982
+ end
983
+ end
984
+
985
+ context "when the parent is not a new record" do
986
+
987
+ let(:movie) do
988
+ Movie.create
989
+ end
990
+
991
+ let!(:rating) do
992
+ movie.ratings.send(method, value: 4)
993
+ end
994
+
995
+ it "sets the foreign key on the relation" do
996
+ rating.ratable_id.should eq(movie.id)
997
+ end
998
+
999
+ it "sets the base on the inverse relation" do
1000
+ rating.ratable.should eq(movie)
1001
+ end
1002
+
1003
+ it "sets the attributes" do
1004
+ rating.value.should eq(4)
1005
+ end
1006
+
1007
+ it "does not save the target" do
1008
+ rating.should be_new_record
1009
+ end
1010
+
1011
+ it "adds the document to the target" do
1012
+ movie.ratings.size.should eq(1)
1013
+ end
1014
+ end
1015
+ end
1016
+ end
1017
+ end
1018
+
1019
+ describe ".builder" do
1020
+
1021
+ let(:builder_klass) do
1022
+ Mongoid::Relations::Builders::Referenced::Many
1023
+ end
1024
+
1025
+ let(:document) do
1026
+ stub
1027
+ end
1028
+
1029
+ let(:metadata) do
1030
+ stub(extension?: false)
1031
+ end
1032
+
1033
+ it "returns the embedded in builder" do
1034
+ described_class.builder(nil, metadata, document).should
1035
+ be_a_kind_of(builder_klass)
1036
+ end
1037
+ end
1038
+
1039
+ describe "#clear" do
1040
+
1041
+ context "when the relation is not polymorphic" do
1042
+
1043
+ context "when the parent has been persisted" do
1044
+
1045
+ let!(:person) do
1046
+ Person.create
1047
+ end
1048
+
1049
+ context "when the children are persisted" do
1050
+
1051
+ let!(:post) do
1052
+ person.posts.create(title: "Testing")
1053
+ end
1054
+
1055
+ let!(:relation) do
1056
+ person.posts.clear
1057
+ end
1058
+
1059
+ it "clears out the relation" do
1060
+ person.posts.should be_empty
1061
+ end
1062
+
1063
+ it "marks the documents as deleted" do
1064
+ post.should be_destroyed
1065
+ end
1066
+
1067
+ it "deletes the documents from the db" do
1068
+ person.reload.posts.should be_empty
1069
+ end
1070
+
1071
+ it "returns the relation" do
1072
+ relation.should be_empty
1073
+ end
1074
+ end
1075
+
1076
+ context "when the children are not persisted" do
1077
+
1078
+ let!(:post) do
1079
+ person.posts.build(title: "Testing")
1080
+ end
1081
+
1082
+ let!(:relation) do
1083
+ person.posts.clear
1084
+ end
1085
+
1086
+ it "clears out the relation" do
1087
+ person.posts.should be_empty
1088
+ end
1089
+ end
1090
+ end
1091
+
1092
+ context "when the parent is not persisted" do
1093
+
1094
+ let(:person) do
1095
+ Person.new
1096
+ end
1097
+
1098
+ let!(:post) do
1099
+ person.posts.build(title: "Testing")
1100
+ end
1101
+
1102
+ let!(:relation) do
1103
+ person.posts.clear
1104
+ end
1105
+
1106
+ it "clears out the relation" do
1107
+ person.posts.should be_empty
1108
+ end
1109
+ end
1110
+ end
1111
+
1112
+ context "when the relation is polymorphic" do
1113
+
1114
+ context "when the parent has been persisted" do
1115
+
1116
+ let!(:movie) do
1117
+ Movie.create
1118
+ end
1119
+
1120
+ context "when the children are persisted" do
1121
+
1122
+ let!(:rating) do
1123
+ movie.ratings.create(value: 1)
1124
+ end
1125
+
1126
+ let!(:relation) do
1127
+ movie.ratings.clear
1128
+ end
1129
+
1130
+ it "clears out the relation" do
1131
+ movie.ratings.should be_empty
1132
+ end
1133
+
1134
+ it "handles the proper dependent strategy" do
1135
+ rating.should_not be_destroyed
1136
+ end
1137
+
1138
+ it "deletes the documents from the db" do
1139
+ movie.reload.ratings.should be_empty
1140
+ end
1141
+
1142
+ it "returns the relation" do
1143
+ relation.should be_empty
1144
+ end
1145
+ end
1146
+
1147
+ context "when the children are not persisted" do
1148
+
1149
+ let!(:rating) do
1150
+ movie.ratings.build(value: 3)
1151
+ end
1152
+
1153
+ let!(:relation) do
1154
+ movie.ratings.clear
1155
+ end
1156
+
1157
+ it "clears out the relation" do
1158
+ movie.ratings.should be_empty
1159
+ end
1160
+ end
1161
+ end
1162
+
1163
+ context "when the parent is not persisted" do
1164
+
1165
+ let(:movie) do
1166
+ Movie.new
1167
+ end
1168
+
1169
+ let!(:rating) do
1170
+ movie.ratings.build(value: 2)
1171
+ end
1172
+
1173
+ let!(:relation) do
1174
+ movie.ratings.clear
1175
+ end
1176
+
1177
+ it "clears out the relation" do
1178
+ movie.ratings.should be_empty
1179
+ end
1180
+ end
1181
+ end
1182
+ end
1183
+
1184
+ describe "#concat" do
1185
+
1186
+ context "when the relations are not polymorphic" do
1187
+
1188
+ context "when the parent is a new record" do
1189
+
1190
+ let(:person) do
1191
+ Person.new
1192
+ end
1193
+
1194
+ let(:post) do
1195
+ Post.new
1196
+ end
1197
+
1198
+ before do
1199
+ person.posts.concat([ post ])
1200
+ end
1201
+
1202
+ it "sets the foreign key on the relation" do
1203
+ post.person_id.should eq(person.id)
1204
+ end
1205
+
1206
+ it "sets the base on the inverse relation" do
1207
+ post.person.should eq(person)
1208
+ end
1209
+
1210
+ it "sets the same instance on the inverse relation" do
1211
+ post.person.should eql(person)
1212
+ end
1213
+
1214
+ it "does not save the target" do
1215
+ post.should be_new_record
1216
+ end
1217
+
1218
+ it "adds the document to the target" do
1219
+ person.posts.size.should eq(1)
1220
+ end
1221
+ end
1222
+
1223
+ context "when appending in a parent create block" do
1224
+
1225
+ let!(:post) do
1226
+ Post.create(title: "testing")
1227
+ end
1228
+
1229
+ let!(:person) do
1230
+ Person.create do |doc|
1231
+ doc.posts.concat([ post ])
1232
+ end
1233
+ end
1234
+
1235
+ it "adds the documents to the relation" do
1236
+ person.posts.should eq([ post ])
1237
+ end
1238
+
1239
+ it "sets the foreign key on the inverse relation" do
1240
+ post.person_id.should eq(person.id)
1241
+ end
1242
+
1243
+ it "saves the target" do
1244
+ post.should be_persisted
1245
+ end
1246
+
1247
+ it "adds the correct number of documents" do
1248
+ person.posts.size.should eq(1)
1249
+ end
1250
+
1251
+ it "persists the link" do
1252
+ person.reload.posts.should eq([ post ])
1253
+ end
1254
+ end
1255
+
1256
+ context "when the parent is not a new record" do
1257
+
1258
+ let(:person) do
1259
+ Person.create
1260
+ end
1261
+
1262
+ let(:post) do
1263
+ Post.new
1264
+ end
1265
+
1266
+ let(:post_three) do
1267
+ Post.new
1268
+ end
1269
+
1270
+ before do
1271
+ person.posts.concat([ post, post_three ])
1272
+ end
1273
+
1274
+ it "sets the foreign key on the relation" do
1275
+ post.person_id.should eq(person.id)
1276
+ end
1277
+
1278
+ it "sets the base on the inverse relation" do
1279
+ post.person.should eq(person)
1280
+ end
1281
+
1282
+ it "sets the same instance on the inverse relation" do
1283
+ post.person.should eql(person)
1284
+ end
1285
+
1286
+ it "saves the target" do
1287
+ post.should be_persisted
1288
+ end
1289
+
1290
+ it "adds the document to the target" do
1291
+ person.posts.count.should eq(2)
1292
+ end
1293
+
1294
+ context "when documents already exist on the relation" do
1295
+
1296
+ let(:post_two) do
1297
+ Post.new(title: "Test")
1298
+ end
1299
+
1300
+ before do
1301
+ person.posts.concat([ post_two ])
1302
+ end
1303
+
1304
+ it "sets the foreign key on the relation" do
1305
+ post_two.person_id.should eq(person.id)
1306
+ end
1307
+
1308
+ it "sets the base on the inverse relation" do
1309
+ post_two.person.should eq(person)
1310
+ end
1311
+
1312
+ it "sets the same instance on the inverse relation" do
1313
+ post_two.person.should eql(person)
1314
+ end
1315
+
1316
+ it "saves the target" do
1317
+ post_two.should be_persisted
1318
+ end
1319
+
1320
+ it "adds the document to the target" do
1321
+ person.posts.count.should eq(3)
1322
+ end
1323
+
1324
+ it "contains the initial document in the target" do
1325
+ person.posts.should include(post)
1326
+ end
1327
+
1328
+ it "contains the added document in the target" do
1329
+ person.posts.should include(post_two)
1330
+ end
1331
+ end
1332
+ end
1333
+ end
1334
+ end
1335
+
1336
+ context "when the relations are polymorphic" do
1337
+
1338
+ context "when the parent is a new record" do
1339
+
1340
+ let(:movie) do
1341
+ Movie.new
1342
+ end
1343
+
1344
+ let(:rating) do
1345
+ Rating.new
1346
+ end
1347
+
1348
+ before do
1349
+ movie.ratings.concat([ rating ])
1350
+ end
1351
+
1352
+ it "sets the foreign key on the relation" do
1353
+ rating.ratable_id.should eq(movie.id)
1354
+ end
1355
+
1356
+ it "sets the base on the inverse relation" do
1357
+ rating.ratable.should eq(movie)
1358
+ end
1359
+
1360
+ it "does not save the target" do
1361
+ rating.should be_new_record
1362
+ end
1363
+
1364
+ it "adds the document to the target" do
1365
+ movie.ratings.size.should eq(1)
1366
+ end
1367
+ end
1368
+
1369
+ context "when the parent is not a new record" do
1370
+
1371
+ let(:movie) do
1372
+ Movie.create
1373
+ end
1374
+
1375
+ let(:rating) do
1376
+ Rating.new
1377
+ end
1378
+
1379
+ before do
1380
+ movie.ratings.concat([ rating ])
1381
+ end
1382
+
1383
+ it "sets the foreign key on the relation" do
1384
+ rating.ratable_id.should eq(movie.id)
1385
+ end
1386
+
1387
+ it "sets the base on the inverse relation" do
1388
+ rating.ratable.should eq(movie)
1389
+ end
1390
+
1391
+ it "saves the target" do
1392
+ rating.should be_persisted
1393
+ end
1394
+
1395
+ it "adds the document to the target" do
1396
+ movie.ratings.count.should eq(1)
1397
+ end
1398
+ end
1399
+ end
1400
+
1401
+ describe "#count" do
1402
+
1403
+ let(:movie) do
1404
+ Movie.create
1405
+ end
1406
+
1407
+ context "when documents have been persisted" do
1408
+
1409
+ let!(:rating) do
1410
+ movie.ratings.create(value: 1)
1411
+ end
1412
+
1413
+ it "returns the number of persisted documents" do
1414
+ movie.ratings.count.should eq(1)
1415
+ end
1416
+ end
1417
+
1418
+ context "when documents have not been persisted" do
1419
+
1420
+ let!(:rating) do
1421
+ movie.ratings.build(value: 1)
1422
+ end
1423
+
1424
+ it "returns 0" do
1425
+ movie.ratings.count.should eq(0)
1426
+ end
1427
+ end
1428
+
1429
+ context "when new documents exist in the database" do
1430
+
1431
+ context "when the documents are part of the relation" do
1432
+
1433
+ before do
1434
+ Rating.create(ratable: movie)
1435
+ end
1436
+
1437
+ it "returns the count from the db" do
1438
+ movie.ratings.count.should eq(1)
1439
+ end
1440
+ end
1441
+
1442
+ context "when the documents are not part of the relation" do
1443
+
1444
+ before do
1445
+ Rating.create
1446
+ end
1447
+
1448
+ it "returns the count from the db" do
1449
+ movie.ratings.count.should eq(0)
1450
+ end
1451
+ end
1452
+ end
1453
+ end
1454
+
1455
+ describe "#create" do
1456
+
1457
+ context "when providing scoped mass assignment" do
1458
+
1459
+ let(:person) do
1460
+ Person.create
1461
+ end
1462
+
1463
+ let(:drug) do
1464
+ person.drugs.create(
1465
+ { name: "Oxycontin", generic: false }, as: :admin
1466
+ )
1467
+ end
1468
+
1469
+ it "sets the attributes for the provided role" do
1470
+ drug.name.should eq("Oxycontin")
1471
+ end
1472
+
1473
+ it "does not set the attributes for other roles" do
1474
+ drug.generic.should be_nil
1475
+ end
1476
+ end
1477
+
1478
+ context "when the relation is not polymorphic" do
1479
+
1480
+ context "when the parent is a new record" do
1481
+
1482
+ let(:person) do
1483
+ Person.new
1484
+ end
1485
+
1486
+ let(:post) do
1487
+ person.posts.create(text: "Testing")
1488
+ end
1489
+
1490
+ it "raises an unsaved document error" do
1491
+ expect { post }.to raise_error(Mongoid::Errors::UnsavedDocument)
1492
+ end
1493
+ end
1494
+
1495
+ context "when.with(safe: true).creating the document" do
1496
+
1497
+ context "when the operation is successful" do
1498
+
1499
+ let(:person) do
1500
+ Person.create
1501
+ end
1502
+
1503
+ let!(:post) do
1504
+ person.posts.with(safe: true).create(text: "Testing")
1505
+ end
1506
+
1507
+ it "creates the document" do
1508
+ person.posts.should eq([ post ])
1509
+ end
1510
+ end
1511
+
1512
+ context "when the operation fails" do
1513
+
1514
+ let(:person) do
1515
+ Person.create
1516
+ end
1517
+
1518
+ let!(:existing) do
1519
+ Post.create
1520
+ end
1521
+
1522
+ it "raises an error" do
1523
+ expect {
1524
+ person.posts.with(safe: true).create do |doc|
1525
+ doc._id = existing.id
1526
+ end
1527
+ }.to raise_error(Moped::Errors::OperationFailure)
1528
+ end
1529
+ end
1530
+ end
1531
+
1532
+ context "when the parent is not a new record" do
1533
+
1534
+ let(:person) do
1535
+ Person.create
1536
+ end
1537
+
1538
+ let!(:post) do
1539
+ person.posts.create(text: "Testing") do |post|
1540
+ post.content = "The Content"
1541
+ end
1542
+ end
1543
+
1544
+ it "sets the foreign key on the relation" do
1545
+ post.person_id.should eq(person.id)
1546
+ end
1547
+
1548
+ it "sets the base on the inverse relation" do
1549
+ post.person.should eq(person)
1550
+ end
1551
+
1552
+ it "sets the attributes" do
1553
+ post.text.should eq("Testing")
1554
+ end
1555
+
1556
+ it "saves the target" do
1557
+ post.should_not be_a_new_record
1558
+ end
1559
+
1560
+ it "calls the passed block" do
1561
+ post.content.should eq("The Content")
1562
+ end
1563
+
1564
+ it "adds the document to the target" do
1565
+ person.posts.count.should eq(1)
1566
+ end
1567
+ end
1568
+ end
1569
+
1570
+ context "when the relation is polymorphic" do
1571
+
1572
+ context "when the parent is a new record" do
1573
+
1574
+ let(:movie) do
1575
+ Movie.new
1576
+ end
1577
+
1578
+ let(:rating) do
1579
+ movie.ratings.create(value: 1)
1580
+ end
1581
+
1582
+ it "raises an unsaved document error" do
1583
+ expect { rating }.to raise_error(Mongoid::Errors::UnsavedDocument)
1584
+ end
1585
+ end
1586
+
1587
+ context "when the parent is not a new record" do
1588
+
1589
+ let(:movie) do
1590
+ Movie.create
1591
+ end
1592
+
1593
+ let!(:rating) do
1594
+ movie.ratings.create(value: 3)
1595
+ end
1596
+
1597
+ it "sets the foreign key on the relation" do
1598
+ rating.ratable_id.should eq(movie.id)
1599
+ end
1600
+
1601
+ it "sets the base on the inverse relation" do
1602
+ rating.ratable.should eq(movie)
1603
+ end
1604
+
1605
+ it "sets the attributes" do
1606
+ rating.value.should eq(3)
1607
+ end
1608
+
1609
+ it "saves the target" do
1610
+ rating.should_not be_new_record
1611
+ end
1612
+
1613
+ it "adds the document to the target" do
1614
+ movie.ratings.count.should eq(1)
1615
+ end
1616
+ end
1617
+ end
1618
+
1619
+ context "when using a diferent primary_key" do
1620
+
1621
+ let(:person) do
1622
+ Person.create!(username: 'arthurnn')
1623
+ end
1624
+
1625
+ let(:drug) do
1626
+ person.drugs.create!
1627
+ end
1628
+
1629
+ it 'saves pk value on fk field' do
1630
+ drug.person_id.should eq('arthurnn')
1631
+ end
1632
+ end
1633
+ end
1634
+
1635
+ describe "#create!" do
1636
+
1637
+ context "when providing mass scoping options" do
1638
+
1639
+ let(:person) do
1640
+ Person.create
1641
+ end
1642
+
1643
+ let(:drug) do
1644
+ person.drugs.create!(
1645
+ { name: "Oxycontin", generic: false }, as: :admin
1646
+ )
1647
+ end
1648
+
1649
+ it "sets the attributes for the provided role" do
1650
+ drug.name.should eq("Oxycontin")
1651
+ end
1652
+
1653
+ it "does not set the attributes for other roles" do
1654
+ drug.generic.should be_nil
1655
+ end
1656
+ end
1657
+
1658
+ context "when the relation is not polymorphic" do
1659
+
1660
+ context "when the parent is a new record" do
1661
+
1662
+ let(:person) do
1663
+ Person.new
1664
+ end
1665
+
1666
+ let(:post) do
1667
+ person.posts.create!(title: "Testing")
1668
+ end
1669
+
1670
+ it "raises an unsaved document error" do
1671
+ expect { post }.to raise_error(Mongoid::Errors::UnsavedDocument)
1672
+ end
1673
+ end
1674
+
1675
+ context "when the parent is not a new record" do
1676
+
1677
+ let(:person) do
1678
+ Person.create
1679
+ end
1680
+
1681
+ let!(:post) do
1682
+ person.posts.create!(title: "Testing")
1683
+ end
1684
+
1685
+ it "sets the foreign key on the relation" do
1686
+ post.person_id.should eq(person.id)
1687
+ end
1688
+
1689
+ it "sets the base on the inverse relation" do
1690
+ post.person.should eq(person)
1691
+ end
1692
+
1693
+ it "sets the attributes" do
1694
+ post.title.should eq("Testing")
1695
+ end
1696
+
1697
+ it "saves the target" do
1698
+ post.should_not be_a_new_record
1699
+ end
1700
+
1701
+ it "adds the document to the target" do
1702
+ person.posts.count.should eq(1)
1703
+ end
1704
+
1705
+ context "when validation fails" do
1706
+
1707
+ it "raises an error" do
1708
+ expect {
1709
+ person.posts.create!(title: "$$$")
1710
+ }.to raise_error(Mongoid::Errors::Validations)
1711
+ end
1712
+ end
1713
+ end
1714
+ end
1715
+
1716
+ context "when the relation is polymorphic" do
1717
+
1718
+ context "when the parent is a new record" do
1719
+
1720
+ let(:movie) do
1721
+ Movie.new
1722
+ end
1723
+
1724
+ let(:rating) do
1725
+ movie.ratings.create!(value: 1)
1726
+ end
1727
+
1728
+ it "raises an unsaved document error" do
1729
+ expect { rating }.to raise_error(Mongoid::Errors::UnsavedDocument)
1730
+ end
1731
+ end
1732
+
1733
+ context "when the parent is not a new record" do
1734
+
1735
+ let(:movie) do
1736
+ Movie.create
1737
+ end
1738
+
1739
+ let!(:rating) do
1740
+ movie.ratings.create!(value: 4)
1741
+ end
1742
+
1743
+ it "sets the foreign key on the relation" do
1744
+ rating.ratable_id.should eq(movie.id)
1745
+ end
1746
+
1747
+ it "sets the base on the inverse relation" do
1748
+ rating.ratable.should eq(movie)
1749
+ end
1750
+
1751
+ it "sets the attributes" do
1752
+ rating.value.should eq(4)
1753
+ end
1754
+
1755
+ it "saves the target" do
1756
+ rating.should_not be_new_record
1757
+ end
1758
+
1759
+ it "adds the document to the target" do
1760
+ movie.ratings.count.should eq(1)
1761
+ end
1762
+
1763
+ context "when validation fails" do
1764
+
1765
+ it "raises an error" do
1766
+ expect {
1767
+ movie.ratings.create!(value: 1000)
1768
+ }.to raise_error(Mongoid::Errors::Validations)
1769
+ end
1770
+ end
1771
+ end
1772
+ end
1773
+ end
1774
+
1775
+ describe ".criteria" do
1776
+
1777
+ let(:id) do
1778
+ Moped::BSON::ObjectId.new
1779
+ end
1780
+
1781
+ context "when the relation is polymorphic" do
1782
+
1783
+ let(:metadata) do
1784
+ Movie.relations["ratings"]
1785
+ end
1786
+
1787
+ let(:criteria) do
1788
+ described_class.criteria(metadata, id, Movie)
1789
+ end
1790
+
1791
+ it "includes the type in the criteria" do
1792
+ criteria.selector.should eq(
1793
+ {
1794
+ "ratable_id" => id,
1795
+ "ratable_type" => "Movie",
1796
+ "ratable_field" => { "$in" => [ :ratings, nil ] }
1797
+ }
1798
+ )
1799
+ end
1800
+ end
1801
+
1802
+ context "when the relation is not polymorphic" do
1803
+
1804
+ let(:metadata) do
1805
+ Person.relations["posts"]
1806
+ end
1807
+
1808
+ let(:criteria) do
1809
+ described_class.criteria(metadata, id, Person)
1810
+ end
1811
+
1812
+ it "does not include the type in the criteria" do
1813
+ criteria.selector.should eq({ "person_id" => id })
1814
+ end
1815
+ end
1816
+ end
1817
+
1818
+ describe "#delete" do
1819
+
1820
+ let!(:person) do
1821
+ Person.create(username: 'arthurnn')
1822
+ end
1823
+
1824
+ context "when the document is found" do
1825
+
1826
+ context "when no dependent option is set" do
1827
+
1828
+ context "when we are assigning attributes" do
1829
+
1830
+ let!(:drug) do
1831
+ person.drugs.create
1832
+ end
1833
+
1834
+ before do
1835
+ Mongoid::Threaded.begin_execution(:assign)
1836
+ end
1837
+
1838
+ after do
1839
+ Mongoid::Threaded.exit_execution(:assign)
1840
+ end
1841
+
1842
+ let(:deleted) do
1843
+ person.drugs.delete(drug)
1844
+ end
1845
+
1846
+ it "does not cascade" do
1847
+ deleted.changes.keys.should eq([ "person_id" ])
1848
+ end
1849
+ end
1850
+
1851
+ context "when the document is loaded" do
1852
+
1853
+ let!(:drug) do
1854
+ person.drugs.create
1855
+ end
1856
+
1857
+ let!(:deleted) do
1858
+ person.drugs.delete(drug)
1859
+ end
1860
+
1861
+ it "returns the document" do
1862
+ deleted.should eq(drug)
1863
+ end
1864
+
1865
+ it "deletes the foreign key" do
1866
+ drug.person_id.should be_nil
1867
+ end
1868
+
1869
+ it "removes the document from the relation" do
1870
+ person.drugs.should_not include(drug)
1871
+ end
1872
+ end
1873
+
1874
+ context "when the document is not loaded" do
1875
+
1876
+ let!(:drug) do
1877
+ Drug.create(person_id: person.username)
1878
+ end
1879
+
1880
+ let!(:deleted) do
1881
+ person.drugs.delete(drug)
1882
+ end
1883
+
1884
+ it "returns the document" do
1885
+ deleted.should eq(drug)
1886
+ end
1887
+
1888
+ it "deletes the foreign key" do
1889
+ drug.person_id.should be_nil
1890
+ end
1891
+
1892
+ it "removes the document from the relation" do
1893
+ person.drugs.should_not include(drug)
1894
+ end
1895
+ end
1896
+ end
1897
+
1898
+ context "when dependent is delete" do
1899
+
1900
+ context "when the document is loaded" do
1901
+
1902
+ let!(:post) do
1903
+ person.posts.create(title: "test")
1904
+ end
1905
+
1906
+ let!(:deleted) do
1907
+ person.posts.delete(post)
1908
+ end
1909
+
1910
+ it "returns the document" do
1911
+ deleted.should eq(post)
1912
+ end
1913
+
1914
+ it "deletes the document" do
1915
+ post.should be_destroyed
1916
+ end
1917
+
1918
+ it "removes the document from the relation" do
1919
+ person.posts.should_not include(post)
1920
+ end
1921
+ end
1922
+
1923
+ context "when the document is not loaded" do
1924
+
1925
+ let!(:post) do
1926
+ Post.create(title: "foo", person_id: person.id)
1927
+ end
1928
+
1929
+ let!(:deleted) do
1930
+ person.posts.delete(post)
1931
+ end
1932
+
1933
+ it "returns the document" do
1934
+ deleted.should eq(post)
1935
+ end
1936
+
1937
+ it "deletes the document" do
1938
+ post.should be_destroyed
1939
+ end
1940
+
1941
+ it "removes the document from the relation" do
1942
+ person.posts.should_not include(post)
1943
+ end
1944
+ end
1945
+ end
1946
+ end
1947
+
1948
+ context "when the document is not found" do
1949
+
1950
+ let!(:post) do
1951
+ Post.create(title: "foo")
1952
+ end
1953
+
1954
+ let!(:deleted) do
1955
+ person.posts.delete(post)
1956
+ end
1957
+
1958
+ it "returns nil" do
1959
+ deleted.should be_nil
1960
+ end
1961
+
1962
+ it "does not delete the document" do
1963
+ post.should be_persisted
1964
+ end
1965
+ end
1966
+ end
1967
+
1968
+ [ :delete_all, :destroy_all ].each do |method|
1969
+
1970
+ describe "##{method}" do
1971
+
1972
+ context "when the relation is not polymorphic" do
1973
+
1974
+ context "when conditions are provided" do
1975
+
1976
+ let(:person) do
1977
+ Person.create(username: 'durran')
1978
+ end
1979
+
1980
+ before do
1981
+ person.posts.create(title: "Testing")
1982
+ person.posts.create(title: "Test")
1983
+ end
1984
+
1985
+ it "removes the correct posts" do
1986
+ person.posts.send(method, conditions: { title: "Testing" })
1987
+ person.posts.count.should eq(1)
1988
+ person.reload.posts_count.should eq(1) if method == :destroy_all
1989
+ end
1990
+
1991
+ it "deletes the documents from the database" do
1992
+ person.posts.send(method, conditions: {title: "Testing" })
1993
+ Post.where(title: "Testing").count.should eq(0)
1994
+ end
1995
+
1996
+ it "returns the number of documents deleted" do
1997
+ person.posts.send(method, conditions: { title: "Testing" }).should eq(1)
1998
+ end
1999
+ end
2000
+
2001
+ context "when conditions are not provided" do
2002
+
2003
+ let(:person) do
2004
+ Person.create
2005
+ end
2006
+
2007
+ before do
2008
+ person.posts.create(title: "Testing")
2009
+ person.posts.create(title: "Test")
2010
+ end
2011
+
2012
+ it "removes the correct posts" do
2013
+ person.posts.send(method)
2014
+ person.posts.count.should eq(0)
2015
+ end
2016
+
2017
+ it "deletes the documents from the database" do
2018
+ person.posts.send(method)
2019
+ Post.where(title: "Testing").count.should eq(0)
2020
+ end
2021
+
2022
+ it "returns the number of documents deleted" do
2023
+ person.posts.send(method).should eq(2)
2024
+ end
2025
+ end
2026
+ end
2027
+
2028
+ context "when the relation is polymorphic" do
2029
+
2030
+ context "when conditions are provided" do
2031
+
2032
+ let(:movie) do
2033
+ Movie.create(title: "Bladerunner")
2034
+ end
2035
+
2036
+ before do
2037
+ movie.ratings.create(value: 1)
2038
+ movie.ratings.create(value: 2)
2039
+ end
2040
+
2041
+ it "removes the correct ratings" do
2042
+ movie.ratings.send(method, conditions: { value: 1 })
2043
+ movie.ratings.count.should eq(1)
2044
+ end
2045
+
2046
+ it "deletes the documents from the database" do
2047
+ movie.ratings.send(method, conditions: { value: 1 })
2048
+ Rating.where(value: 1).count.should eq(0)
2049
+ end
2050
+
2051
+ it "returns the number of documents deleted" do
2052
+ movie.ratings.send(method, conditions: { value: 1 }).should eq(1)
2053
+ end
2054
+ end
2055
+
2056
+ context "when conditions are not provided" do
2057
+
2058
+ let(:movie) do
2059
+ Movie.create(title: "Bladerunner")
2060
+ end
2061
+
2062
+ before do
2063
+ movie.ratings.create(value: 1)
2064
+ movie.ratings.create(value: 2)
2065
+ end
2066
+
2067
+ it "removes the correct ratings" do
2068
+ movie.ratings.send(method)
2069
+ movie.ratings.count.should eq(0)
2070
+ end
2071
+
2072
+ it "deletes the documents from the database" do
2073
+ movie.ratings.send(method)
2074
+ Rating.where(value: 1).count.should eq(0)
2075
+ end
2076
+
2077
+ it "returns the number of documents deleted" do
2078
+ movie.ratings.send(method).should eq(2)
2079
+ end
2080
+ end
2081
+ end
2082
+ end
2083
+ end
2084
+
2085
+ describe ".eager_load" do
2086
+
2087
+ before do
2088
+ Mongoid.identity_map_enabled = true
2089
+ end
2090
+
2091
+ after do
2092
+ Mongoid.identity_map_enabled = false
2093
+ end
2094
+
2095
+ context "when the relation is not polymorphic" do
2096
+
2097
+ context "when the eager load has returned documents" do
2098
+
2099
+ let!(:person) do
2100
+ Person.create
2101
+ end
2102
+
2103
+ let!(:post) do
2104
+ person.posts.create(title: "testing")
2105
+ end
2106
+
2107
+ let(:metadata) do
2108
+ Person.relations["posts"]
2109
+ end
2110
+
2111
+ let!(:eager) do
2112
+ described_class.eager_load(metadata, Person.all.map(&:_id))
2113
+ end
2114
+
2115
+ let(:map) do
2116
+ Mongoid::IdentityMap.get(Post, {"person_id" => person.id})
2117
+ end
2118
+
2119
+ it "puts the documents in the identity map" do
2120
+ map.should eq({ post.id => post })
2121
+ end
2122
+ end
2123
+
2124
+ context "when the eager load has not returned documents" do
2125
+
2126
+ let!(:person) do
2127
+ Person.create
2128
+ end
2129
+
2130
+ let(:metadata) do
2131
+ Person.relations["posts"]
2132
+ end
2133
+
2134
+ let!(:eager) do
2135
+ described_class.eager_load(metadata, Person.all.map(&:_id))
2136
+ end
2137
+
2138
+ let(:map) do
2139
+ Mongoid::IdentityMap.get(Post, {"person_id" => person.id})
2140
+ end
2141
+
2142
+ it "puts an empty array in the identity map" do
2143
+ map.should be_empty
2144
+ end
2145
+ end
2146
+
2147
+ context "when the eager load has not returned documents for some" do
2148
+
2149
+ let!(:person_one) do
2150
+ Person.create
2151
+ end
2152
+
2153
+ let!(:person_two) do
2154
+ Person.create
2155
+ end
2156
+
2157
+ let!(:post) do
2158
+ person_one.posts.create(title: "testing")
2159
+ end
2160
+
2161
+ let(:metadata) do
2162
+ Person.relations["posts"]
2163
+ end
2164
+
2165
+ let!(:eager) do
2166
+ described_class.eager_load(metadata, Person.all.map(&:_id))
2167
+ end
2168
+
2169
+ let(:map_one) do
2170
+ Mongoid::IdentityMap.get(Post, {"person_id" => person_one.id})
2171
+ end
2172
+
2173
+ let(:map_two) do
2174
+ Mongoid::IdentityMap.get(Post, {"person_id" => person_two.id})
2175
+ end
2176
+
2177
+ it "puts the found documents in the identity map" do
2178
+ map_one.should eq({ post.id => post })
2179
+ end
2180
+
2181
+ it "puts an empty array for parents with no docs" do
2182
+ map_two.should be_empty
2183
+ end
2184
+ end
2185
+ end
2186
+
2187
+ context "when the relation is polymorphic" do
2188
+
2189
+ let!(:movie) do
2190
+ Movie.create(name: "Bladerunner")
2191
+ end
2192
+
2193
+ let!(:book) do
2194
+ Book.create(name: "Game of Thrones")
2195
+ end
2196
+
2197
+ let!(:movie_rating) do
2198
+ movie.ratings.create(value: 10)
2199
+ end
2200
+
2201
+ let!(:book_rating) do
2202
+ book.create_rating(value: 10)
2203
+ end
2204
+
2205
+ let(:metadata) do
2206
+ Movie.relations["ratings"]
2207
+ end
2208
+
2209
+ let!(:eager) do
2210
+ described_class.eager_load(metadata, Movie.all.map(&:_id))
2211
+ end
2212
+
2213
+ let(:map) do
2214
+ Mongoid::IdentityMap.get(Rating, {"ratable_id" => movie.id})
2215
+ end
2216
+
2217
+ it "puts the documents in the identity map" do
2218
+ map.should eq({ movie_rating.id => movie_rating })
2219
+ end
2220
+ end
2221
+ end
2222
+
2223
+ describe ".embedded?" do
2224
+
2225
+ it "returns false" do
2226
+ described_class.should_not be_embedded
2227
+ end
2228
+ end
2229
+
2230
+ describe "#exists?" do
2231
+
2232
+ let!(:person) do
2233
+ Person.create
2234
+ end
2235
+
2236
+ context "when documents exist in the database" do
2237
+
2238
+ before do
2239
+ person.posts.create
2240
+ end
2241
+
2242
+ it "returns true" do
2243
+ person.posts.exists?.should be_true
2244
+ end
2245
+ end
2246
+
2247
+ context "when no documents exist in the database" do
2248
+
2249
+ before do
2250
+ person.posts.build
2251
+ end
2252
+
2253
+ it "returns false" do
2254
+ person.posts.exists?.should be_false
2255
+ end
2256
+ end
2257
+ end
2258
+
2259
+ describe "#find" do
2260
+
2261
+ context "when the identity map is enabled" do
2262
+
2263
+ before do
2264
+ Mongoid.identity_map_enabled = true
2265
+ end
2266
+
2267
+ after do
2268
+ Mongoid.identity_map_enabled = false
2269
+ end
2270
+
2271
+ context "when the document is in the map" do
2272
+
2273
+ let(:person) do
2274
+ Person.create
2275
+ end
2276
+
2277
+ before do
2278
+ person.posts.create(title: "Test")
2279
+ end
2280
+
2281
+ context "when the document does not belong to the relation" do
2282
+
2283
+ let!(:post) do
2284
+ Post.create(title: "testing")
2285
+ end
2286
+
2287
+ it "raises an error" do
2288
+ expect {
2289
+ person.posts.find(post.id)
2290
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
2291
+ end
2292
+ end
2293
+ end
2294
+ end
2295
+
2296
+ context "when the relation is not polymorphic" do
2297
+
2298
+ let(:person) do
2299
+ Person.create
2300
+ end
2301
+
2302
+ let!(:post_one) do
2303
+ person.posts.create(title: "Test")
2304
+ end
2305
+
2306
+ let!(:post_two) do
2307
+ person.posts.create(title: "OMG I has relations")
2308
+ end
2309
+
2310
+ context "when providing an id" do
2311
+
2312
+ context "when the id matches" do
2313
+
2314
+ let(:post) do
2315
+ person.posts.find(post_one.id)
2316
+ end
2317
+
2318
+ it "returns the matching document" do
2319
+ post.should eq(post_one)
2320
+ end
2321
+ end
2322
+
2323
+ context "when the id matches but is not scoped to the relation" do
2324
+
2325
+ let(:post) do
2326
+ Post.create(title: "Unscoped")
2327
+ end
2328
+
2329
+ it "raises an error" do
2330
+ expect {
2331
+ person.posts.find(post.id)
2332
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
2333
+ end
2334
+ end
2335
+
2336
+ context "when the id does not match" do
2337
+
2338
+ context "when config set to raise error" do
2339
+
2340
+ before do
2341
+ Mongoid.raise_not_found_error = true
2342
+ end
2343
+
2344
+ it "raises an error" do
2345
+ expect {
2346
+ person.posts.find(Moped::BSON::ObjectId.new)
2347
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
2348
+ end
2349
+ end
2350
+
2351
+ context "when config set not to raise error" do
2352
+
2353
+ let(:post) do
2354
+ person.posts.find(Moped::BSON::ObjectId.new)
2355
+ end
2356
+
2357
+ before do
2358
+ Mongoid.raise_not_found_error = false
2359
+ end
2360
+
2361
+ after do
2362
+ Mongoid.raise_not_found_error = true
2363
+ end
2364
+
2365
+ it "returns nil" do
2366
+ post.should be_nil
2367
+ end
2368
+ end
2369
+ end
2370
+ end
2371
+
2372
+ context "when providing an array of ids" do
2373
+
2374
+ context "when the ids match" do
2375
+
2376
+ let(:posts) do
2377
+ person.posts.find([ post_one.id, post_two.id ])
2378
+ end
2379
+
2380
+ it "returns the matching documents" do
2381
+ posts.should eq([ post_one, post_two ])
2382
+ end
2383
+ end
2384
+
2385
+ context "when the ids do not match" do
2386
+
2387
+ context "when config set to raise error" do
2388
+
2389
+ before do
2390
+ Mongoid.raise_not_found_error = true
2391
+ end
2392
+
2393
+ it "raises an error" do
2394
+ expect {
2395
+ person.posts.find([ Moped::BSON::ObjectId.new ])
2396
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
2397
+ end
2398
+ end
2399
+
2400
+ context "when config set not to raise error" do
2401
+
2402
+ let(:posts) do
2403
+ person.posts.find([ Moped::BSON::ObjectId.new ])
2404
+ end
2405
+
2406
+ before do
2407
+ Mongoid.raise_not_found_error = false
2408
+ end
2409
+
2410
+ after do
2411
+ Mongoid.raise_not_found_error = true
2412
+ end
2413
+
2414
+ it "returns an empty array" do
2415
+ posts.should be_empty
2416
+ end
2417
+ end
2418
+ end
2419
+ end
2420
+ end
2421
+
2422
+ context "when the relation is polymorphic" do
2423
+
2424
+ let(:movie) do
2425
+ Movie.create
2426
+ end
2427
+
2428
+ let!(:rating_one) do
2429
+ movie.ratings.create(value: 1)
2430
+ end
2431
+
2432
+ let!(:rating_two) do
2433
+ movie.ratings.create(value: 5)
2434
+ end
2435
+
2436
+ context "when providing an id" do
2437
+
2438
+ context "when the id matches" do
2439
+
2440
+ let(:rating) do
2441
+ movie.ratings.find(rating_one.id)
2442
+ end
2443
+
2444
+ it "returns the matching document" do
2445
+ rating.should eq(rating_one)
2446
+ end
2447
+ end
2448
+
2449
+ context "when the id does not match" do
2450
+
2451
+ context "when config set to raise error" do
2452
+
2453
+ before do
2454
+ Mongoid.raise_not_found_error = true
2455
+ end
2456
+
2457
+ it "raises an error" do
2458
+ expect {
2459
+ movie.ratings.find(Moped::BSON::ObjectId.new)
2460
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
2461
+ end
2462
+ end
2463
+
2464
+ context "when config set not to raise error" do
2465
+
2466
+ let(:rating) do
2467
+ movie.ratings.find(Moped::BSON::ObjectId.new)
2468
+ end
2469
+
2470
+ before do
2471
+ Mongoid.raise_not_found_error = false
2472
+ end
2473
+
2474
+ after do
2475
+ Mongoid.raise_not_found_error = true
2476
+ end
2477
+
2478
+ it "returns nil" do
2479
+ rating.should be_nil
2480
+ end
2481
+ end
2482
+ end
2483
+ end
2484
+
2485
+ context "when providing an array of ids" do
2486
+
2487
+ context "when the ids match" do
2488
+
2489
+ let(:ratings) do
2490
+ movie.ratings.find([ rating_one.id, rating_two.id ])
2491
+ end
2492
+
2493
+ it "returns the matching documents" do
2494
+ ratings.should eq([ rating_one, rating_two ])
2495
+ end
2496
+ end
2497
+
2498
+ context "when the ids do not match" do
2499
+
2500
+ context "when config set to raise error" do
2501
+
2502
+ before do
2503
+ Mongoid.raise_not_found_error = true
2504
+ end
2505
+
2506
+ it "raises an error" do
2507
+ expect {
2508
+ movie.ratings.find([ Moped::BSON::ObjectId.new ])
2509
+ }.to raise_error(Mongoid::Errors::DocumentNotFound)
2510
+ end
2511
+ end
2512
+
2513
+ context "when config set not to raise error" do
2514
+
2515
+ let(:ratings) do
2516
+ movie.ratings.find([ Moped::BSON::ObjectId.new ])
2517
+ end
2518
+
2519
+ before do
2520
+ Mongoid.raise_not_found_error = false
2521
+ end
2522
+
2523
+ after do
2524
+ Mongoid.raise_not_found_error = true
2525
+ end
2526
+
2527
+ it "returns an empty array" do
2528
+ ratings.should be_empty
2529
+ end
2530
+ end
2531
+ end
2532
+ end
2533
+ end
2534
+ end
2535
+
2536
+ describe "#find_or_create_by" do
2537
+
2538
+ context "when the relation is not polymorphic" do
2539
+
2540
+ let(:person) do
2541
+ Person.create
2542
+ end
2543
+
2544
+ let!(:post) do
2545
+ person.posts.create(title: "Testing")
2546
+ end
2547
+
2548
+ context "when the document exists" do
2549
+
2550
+ let(:found) do
2551
+ person.posts.find_or_create_by(title: "Testing")
2552
+ end
2553
+
2554
+ it "returns the document" do
2555
+ found.should eq(post)
2556
+ end
2557
+
2558
+ it "keeps the document in the relation" do
2559
+ found.person.should eq(person)
2560
+ end
2561
+ end
2562
+
2563
+ context "when the document does not exist" do
2564
+
2565
+ context "when there is no criteria attached" do
2566
+
2567
+ let(:found) do
2568
+ person.posts.find_or_create_by(title: "Test") do |post|
2569
+ post.content = "The Content"
2570
+ end
2571
+ end
2572
+
2573
+ it "sets the new document attributes" do
2574
+ found.title.should eq("Test")
2575
+ end
2576
+
2577
+ it "returns a newly persisted document" do
2578
+ found.should be_persisted
2579
+ end
2580
+
2581
+ it "calls the passed block" do
2582
+ found.content.should eq("The Content")
2583
+ end
2584
+
2585
+ it "keeps the document in the relation" do
2586
+ found.person.should eq(person)
2587
+ end
2588
+ end
2589
+
2590
+ context "when a criteria is attached" do
2591
+
2592
+ let(:found) do
2593
+ person.posts.recent.find_or_create_by(title: "Test")
2594
+ end
2595
+
2596
+ it "sets the new document attributes" do
2597
+ found.title.should eq("Test")
2598
+ end
2599
+
2600
+ it "returns a newly persisted document" do
2601
+ found.should be_persisted
2602
+ end
2603
+
2604
+ it "keeps the document in the relation" do
2605
+ found.person.should eq(person)
2606
+ end
2607
+ end
2608
+ end
2609
+ end
2610
+
2611
+ context "when the relation is polymorphic" do
2612
+
2613
+ let(:movie) do
2614
+ Movie.create
2615
+ end
2616
+
2617
+ let!(:rating) do
2618
+ movie.ratings.create(value: 1)
2619
+ end
2620
+
2621
+ context "when the document exists" do
2622
+
2623
+ let(:found) do
2624
+ movie.ratings.find_or_create_by(value: 1)
2625
+ end
2626
+
2627
+ it "returns the document" do
2628
+ found.should eq(rating)
2629
+ end
2630
+
2631
+ it "keeps the document in the relation" do
2632
+ found.ratable.should eq(movie)
2633
+ end
2634
+ end
2635
+
2636
+ context "when the document does not exist" do
2637
+
2638
+ let(:found) do
2639
+ movie.ratings.find_or_create_by(value: 3)
2640
+ end
2641
+
2642
+ it "sets the new document attributes" do
2643
+ found.value.should eq(3)
2644
+ end
2645
+
2646
+ it "returns a newly persisted document" do
2647
+ found.should be_persisted
2648
+ end
2649
+
2650
+ it "keeps the document in the relation" do
2651
+ found.ratable.should eq(movie)
2652
+ end
2653
+ end
2654
+ end
2655
+ end
2656
+
2657
+ describe "#find_or_initialize_by" do
2658
+
2659
+ context "when the relation is not polymorphic" do
2660
+
2661
+ let(:person) do
2662
+ Person.create
2663
+ end
2664
+
2665
+ let!(:post) do
2666
+ person.posts.create(title: "Testing")
2667
+ end
2668
+
2669
+ context "when the document exists" do
2670
+
2671
+ let(:found) do
2672
+ person.posts.find_or_initialize_by(title: "Testing")
2673
+ end
2674
+
2675
+ it "returns the document" do
2676
+ found.should eq(post)
2677
+ end
2678
+ end
2679
+
2680
+ context "when the document does not exist" do
2681
+
2682
+ let(:found) do
2683
+ person.posts.find_or_initialize_by(title: "Test") do |post|
2684
+ post.content = "The Content"
2685
+ end
2686
+ end
2687
+
2688
+ it "sets the new document attributes" do
2689
+ found.title.should eq("Test")
2690
+ end
2691
+
2692
+ it "returns a non persisted document" do
2693
+ found.should_not be_persisted
2694
+ end
2695
+
2696
+ it "calls the passed block" do
2697
+ found.content.should eq("The Content")
2698
+ end
2699
+ end
2700
+ end
2701
+
2702
+ context "when the relation is polymorphic" do
2703
+
2704
+ let(:movie) do
2705
+ Movie.create
2706
+ end
2707
+
2708
+ let!(:rating) do
2709
+ movie.ratings.create(value: 1)
2710
+ end
2711
+
2712
+ context "when the document exists" do
2713
+
2714
+ let(:found) do
2715
+ movie.ratings.find_or_initialize_by(value: 1)
2716
+ end
2717
+
2718
+ it "returns the document" do
2719
+ found.should eq(rating)
2720
+ end
2721
+ end
2722
+
2723
+ context "when the document does not exist" do
2724
+
2725
+ let(:found) do
2726
+ movie.ratings.find_or_initialize_by(value: 3)
2727
+ end
2728
+
2729
+ it "sets the new document attributes" do
2730
+ found.value.should eq(3)
2731
+ end
2732
+
2733
+ it "returns a non persisted document" do
2734
+ found.should_not be_persisted
2735
+ end
2736
+ end
2737
+ end
2738
+ end
2739
+
2740
+ describe ".foreign_key_suffix" do
2741
+
2742
+ it "returns _id" do
2743
+ described_class.foreign_key_suffix.should eq("_id")
2744
+ end
2745
+ end
2746
+
2747
+ describe "#initialize" do
2748
+
2749
+ context "when an illegal mixed relation exists" do
2750
+
2751
+ let(:post) do
2752
+ Post.new
2753
+ end
2754
+
2755
+ it "raises an error" do
2756
+ expect {
2757
+ post.videos
2758
+ }.to raise_error(Mongoid::Errors::MixedRelations)
2759
+ end
2760
+ end
2761
+
2762
+ context "when a cyclic relation exists" do
2763
+
2764
+ let(:post) do
2765
+ Post.new
2766
+ end
2767
+
2768
+ it "does not raise an error" do
2769
+ post.roles.should be_empty
2770
+ end
2771
+ end
2772
+ end
2773
+
2774
+ describe ".macro" do
2775
+
2776
+ it "returns has_many" do
2777
+ described_class.macro.should eq(:has_many)
2778
+ end
2779
+ end
2780
+
2781
+ describe "#max" do
2782
+
2783
+ let(:person) do
2784
+ Person.create
2785
+ end
2786
+
2787
+ let(:post_one) do
2788
+ Post.create(rating: 5)
2789
+ end
2790
+
2791
+ let(:post_two) do
2792
+ Post.create(rating: 10)
2793
+ end
2794
+
2795
+ before do
2796
+ person.posts.push(post_one, post_two)
2797
+ end
2798
+
2799
+ let(:max) do
2800
+ person.posts.max do |a,b|
2801
+ a.rating <=> b.rating
2802
+ end
2803
+ end
2804
+
2805
+ it "returns the document with the max value of the supplied field" do
2806
+ max.should eq(post_two)
2807
+ end
2808
+ end
2809
+
2810
+ describe "#max_by" do
2811
+
2812
+ let(:person) do
2813
+ Person.create
2814
+ end
2815
+
2816
+ let(:post_one) do
2817
+ Post.create(rating: 5)
2818
+ end
2819
+
2820
+ let(:post_two) do
2821
+ Post.create(rating: 10)
2822
+ end
2823
+
2824
+ before do
2825
+ person.posts.push(post_one, post_two)
2826
+ end
2827
+
2828
+ let(:max) do
2829
+ person.posts.max_by(&:rating)
2830
+ end
2831
+
2832
+ it "returns the document with the max value of the supplied field" do
2833
+ max.should eq(post_two)
2834
+ end
2835
+ end
2836
+
2837
+ describe "#method_missing" do
2838
+
2839
+ let!(:person) do
2840
+ Person.create
2841
+ end
2842
+
2843
+ let!(:post_one) do
2844
+ person.posts.create(title: "First", content: "Posting")
2845
+ end
2846
+
2847
+ let!(:post_two) do
2848
+ person.posts.create(title: "Second", content: "Testing")
2849
+ end
2850
+
2851
+ context "when providing a single criteria" do
2852
+
2853
+ let(:posts) do
2854
+ person.posts.where(title: "First")
2855
+ end
2856
+
2857
+ it "applies the criteria to the documents" do
2858
+ posts.should eq([ post_one ])
2859
+ end
2860
+ end
2861
+
2862
+ context "when providing a criteria class method" do
2863
+
2864
+ let(:posts) do
2865
+ person.posts.posting
2866
+ end
2867
+
2868
+ it "applies the criteria to the documents" do
2869
+ posts.should eq([ post_one ])
2870
+ end
2871
+ end
2872
+
2873
+ context "when chaining criteria" do
2874
+
2875
+ let(:posts) do
2876
+ person.posts.posting.where(:title.in => [ "First" ])
2877
+ end
2878
+
2879
+ it "applies the criteria to the documents" do
2880
+ posts.should eq([ post_one ])
2881
+ end
2882
+ end
2883
+
2884
+ context "when delegating methods" do
2885
+
2886
+ describe "#distinct" do
2887
+
2888
+ it "returns the distinct values for the fields" do
2889
+ person.posts.distinct(:title).should =~ [ "First", "Second"]
2890
+ end
2891
+ end
2892
+ end
2893
+ end
2894
+
2895
+ describe "#min" do
2896
+
2897
+ let(:person) do
2898
+ Person.create
2899
+ end
2900
+
2901
+ let(:post_one) do
2902
+ Post.create(rating: 5)
2903
+ end
2904
+
2905
+ let(:post_two) do
2906
+ Post.create(rating: 10)
2907
+ end
2908
+
2909
+ before do
2910
+ person.posts.push(post_one, post_two)
2911
+ end
2912
+
2913
+ let(:min) do
2914
+ person.posts.min do |a, b|
2915
+ a.rating <=> b.rating
2916
+ end
2917
+ end
2918
+
2919
+ it "returns the min value of the supplied field" do
2920
+ min.should eq(post_one)
2921
+ end
2922
+ end
2923
+
2924
+ describe "#min_by" do
2925
+
2926
+ let(:person) do
2927
+ Person.create
2928
+ end
2929
+
2930
+ let(:post_one) do
2931
+ Post.create(rating: 5)
2932
+ end
2933
+
2934
+ let(:post_two) do
2935
+ Post.create(rating: 10)
2936
+ end
2937
+
2938
+ before do
2939
+ person.posts.push(post_one, post_two)
2940
+ end
2941
+
2942
+ let(:min) do
2943
+ person.posts.min_by(&:rating)
2944
+ end
2945
+
2946
+ it "returns the min value of the supplied field" do
2947
+ min.should eq(post_one)
2948
+ end
2949
+ end
2950
+
2951
+ describe "#nullify_all" do
2952
+
2953
+ context "when the inverse has not been loaded" do
2954
+
2955
+ let(:person) do
2956
+ Person.create
2957
+ end
2958
+
2959
+ let!(:post_one) do
2960
+ person.posts.create(title: "One")
2961
+ end
2962
+
2963
+ let!(:post_two) do
2964
+ person.posts.create(title: "Two")
2965
+ end
2966
+
2967
+ let(:from_db) do
2968
+ Person.first
2969
+ end
2970
+
2971
+ before do
2972
+ from_db.posts.nullify_all
2973
+ end
2974
+
2975
+ it "loads the targets before nullifying" do
2976
+ from_db.posts.should be_empty
2977
+ end
2978
+
2979
+ it "persists the base nullifications" do
2980
+ Person.first.posts.should be_empty
2981
+ end
2982
+
2983
+ it "persists the inverse nullifications" do
2984
+ Post.all.each do |post|
2985
+ post.person.should be_nil
2986
+ end
2987
+ end
2988
+ end
2989
+
2990
+ context "when the relation is not polymorphic" do
2991
+
2992
+ let(:person) do
2993
+ Person.create
2994
+ end
2995
+
2996
+ let!(:post_one) do
2997
+ person.posts.create(title: "One")
2998
+ end
2999
+
3000
+ let!(:post_two) do
3001
+ person.posts.create(title: "Two")
3002
+ end
3003
+
3004
+ before do
3005
+ person.posts.nullify_all
3006
+ end
3007
+
3008
+ it "removes all the foreign keys from the target" do
3009
+ [ post_one, post_two ].each do |post|
3010
+ post.person_id.should be_nil
3011
+ end
3012
+ end
3013
+
3014
+ it "removes all the references from the target" do
3015
+ [ post_one, post_two ].each do |post|
3016
+ post.person.should be_nil
3017
+ end
3018
+ end
3019
+
3020
+ it "saves the documents" do
3021
+ post_one.reload.person.should be_nil
3022
+ end
3023
+
3024
+ context "when adding a nullified document back to the relation" do
3025
+
3026
+ before do
3027
+ person.posts.push(post_one)
3028
+ end
3029
+
3030
+ it "persists the relation" do
3031
+ person.posts(true).should eq([ post_one ])
3032
+ end
3033
+ end
3034
+ end
3035
+
3036
+ context "when the relation is polymorphic" do
3037
+
3038
+ let(:movie) do
3039
+ Movie.create(title: "Oldboy")
3040
+ end
3041
+
3042
+ let!(:rating_one) do
3043
+ movie.ratings.create(value: 10)
3044
+ end
3045
+
3046
+ let!(:rating_two) do
3047
+ movie.ratings.create(value: 9)
3048
+ end
3049
+
3050
+ before do
3051
+ movie.ratings.nullify_all
3052
+ end
3053
+
3054
+ it "removes all the foreign keys from the target" do
3055
+ [ rating_one, rating_two ].each do |rating|
3056
+ rating.ratable_id.should be_nil
3057
+ end
3058
+ end
3059
+
3060
+ it "removes all the references from the target" do
3061
+ [ rating_one, rating_two ].each do |rating|
3062
+ rating.ratable.should be_nil
3063
+ end
3064
+ end
3065
+ end
3066
+ end
3067
+
3068
+ describe "#respond_to?" do
3069
+
3070
+ let(:person) do
3071
+ Person.new
3072
+ end
3073
+
3074
+ let(:posts) do
3075
+ person.posts
3076
+ end
3077
+
3078
+ Array.public_instance_methods.each do |method|
3079
+
3080
+ context "when checking #{method}" do
3081
+
3082
+ it "returns true" do
3083
+ posts.respond_to?(method).should be_true
3084
+ end
3085
+ end
3086
+ end
3087
+
3088
+ Mongoid::Relations::Referenced::Many.public_instance_methods.each do |method|
3089
+
3090
+ context "when checking #{method}" do
3091
+
3092
+ it "returns true" do
3093
+ posts.respond_to?(method).should be_true
3094
+ end
3095
+ end
3096
+ end
3097
+
3098
+ Post.scopes.keys.each do |method|
3099
+
3100
+ context "when checking #{method}" do
3101
+
3102
+ it "returns true" do
3103
+ posts.respond_to?(method).should be_true
3104
+ end
3105
+ end
3106
+ end
3107
+ end
3108
+
3109
+ describe ".stores_foreign_key?" do
3110
+
3111
+ it "returns false" do
3112
+ described_class.stores_foreign_key?.should be_false
3113
+ end
3114
+ end
3115
+
3116
+ describe "#scoped" do
3117
+
3118
+ let(:person) do
3119
+ Person.new
3120
+ end
3121
+
3122
+ let(:scoped) do
3123
+ person.posts.scoped
3124
+ end
3125
+
3126
+ it "returns the relation criteria" do
3127
+ scoped.should be_a(Mongoid::Criteria)
3128
+ end
3129
+
3130
+ it "returns with an empty selector" do
3131
+ scoped.selector.should eq({ "person_id" => person.id })
3132
+ end
3133
+ end
3134
+
3135
+ [ :size, :length ].each do |method|
3136
+
3137
+ describe "##{method}" do
3138
+
3139
+ let(:movie) do
3140
+ Movie.create
3141
+ end
3142
+
3143
+ context "when documents have been persisted" do
3144
+
3145
+ let!(:rating) do
3146
+ movie.ratings.create(value: 1)
3147
+ end
3148
+
3149
+ it "returns 1" do
3150
+ movie.ratings.send(method).should eq(1)
3151
+ end
3152
+ end
3153
+
3154
+ context "when documents have not been persisted" do
3155
+
3156
+ before do
3157
+ movie.ratings.build(value: 1)
3158
+ movie.ratings.create(value: 2)
3159
+ end
3160
+
3161
+ it "returns the total number of documents" do
3162
+ movie.ratings.send(method).should eq(2)
3163
+ end
3164
+ end
3165
+ end
3166
+ end
3167
+
3168
+ describe "#unscoped" do
3169
+
3170
+ context "when the relation has no default scope" do
3171
+
3172
+ let!(:person) do
3173
+ Person.create
3174
+ end
3175
+
3176
+ let!(:post_one) do
3177
+ person.posts.create(title: "first")
3178
+ end
3179
+
3180
+ let!(:post_two) do
3181
+ Post.create(title: "second")
3182
+ end
3183
+
3184
+ let(:unscoped) do
3185
+ person.posts.unscoped
3186
+ end
3187
+
3188
+ it "returns only the associated documents" do
3189
+ unscoped.should eq([ post_one ])
3190
+ end
3191
+ end
3192
+
3193
+ context "when the relation has a default scope" do
3194
+
3195
+ let!(:church) do
3196
+ Church.create
3197
+ end
3198
+
3199
+ let!(:acolyte_one) do
3200
+ church.acolytes.create(name: "first")
3201
+ end
3202
+
3203
+ let!(:acolyte_two) do
3204
+ Acolyte.create(name: "second")
3205
+ end
3206
+
3207
+ let(:unscoped) do
3208
+ church.acolytes.unscoped
3209
+ end
3210
+
3211
+ it "only returns associated documents" do
3212
+ unscoped.should eq([ acolyte_one ])
3213
+ end
3214
+
3215
+ it "removes the default scoping options" do
3216
+ unscoped.options.should eq({})
3217
+ end
3218
+ end
3219
+ end
3220
+
3221
+ describe ".valid_options" do
3222
+
3223
+ it "returns the valid options" do
3224
+ described_class.valid_options.should eq(
3225
+ [
3226
+ :after_add,
3227
+ :after_remove,
3228
+ :as,
3229
+ :autosave,
3230
+ :before_add,
3231
+ :before_remove,
3232
+ :dependent,
3233
+ :foreign_key,
3234
+ :order,
3235
+ :primary_key
3236
+ ]
3237
+ )
3238
+ end
3239
+ end
3240
+
3241
+ describe ".validation_default" do
3242
+
3243
+ it "returns true" do
3244
+ described_class.validation_default.should be_true
3245
+ end
3246
+ end
3247
+
3248
+ context "when the association has an order defined" do
3249
+
3250
+ let(:person) do
3251
+ Person.create
3252
+ end
3253
+
3254
+ let(:post_one) do
3255
+ OrderedPost.create(rating: 10, title: '1')
3256
+ end
3257
+
3258
+ let(:post_two) do
3259
+ OrderedPost.create(rating: 20, title: '2')
3260
+ end
3261
+
3262
+ let(:post_three) do
3263
+ OrderedPost.create(rating: 20, title: '3')
3264
+ end
3265
+
3266
+ before do
3267
+ person.ordered_posts.nullify_all
3268
+ person.ordered_posts.push(post_one, post_two, post_three)
3269
+ end
3270
+
3271
+ it "order documents" do
3272
+ person.ordered_posts(true).should eq(
3273
+ [post_two, post_three, post_one]
3274
+ )
3275
+ end
3276
+
3277
+ it "chaining order criterias" do
3278
+ person.ordered_posts.order_by(:title.desc).to_a.should eq(
3279
+ [post_three, post_two, post_one]
3280
+ )
3281
+ end
3282
+ end
3283
+
3284
+ context "when reloading the relation" do
3285
+
3286
+ let!(:person) do
3287
+ Person.create
3288
+ end
3289
+
3290
+ let!(:post_one) do
3291
+ Post.create(title: "one")
3292
+ end
3293
+
3294
+ let!(:post_two) do
3295
+ Post.create(title: "two")
3296
+ end
3297
+
3298
+ before do
3299
+ person.posts << post_one
3300
+ end
3301
+
3302
+ context "when the relation references the same documents" do
3303
+
3304
+ before do
3305
+ Post.collection.find({ _id: post_one.id }).
3306
+ update({ "$set" => { title: "reloaded" }})
3307
+ end
3308
+
3309
+ let(:reloaded) do
3310
+ person.posts(true)
3311
+ end
3312
+
3313
+ it "reloads the document from the database" do
3314
+ reloaded.first.title.should eq("reloaded")
3315
+ end
3316
+ end
3317
+
3318
+ context "when the relation references different documents" do
3319
+
3320
+ before do
3321
+ person.posts << post_two
3322
+ end
3323
+
3324
+ let(:reloaded) do
3325
+ person.posts(true)
3326
+ end
3327
+
3328
+ it "reloads the first document from the database" do
3329
+ reloaded.should include(post_one)
3330
+ end
3331
+
3332
+ it "reloads the new document from the database" do
3333
+ reloaded.should include(post_two)
3334
+ end
3335
+ end
3336
+ end
3337
+
3338
+ context "when the parent is using integer ids" do
3339
+
3340
+ let(:jar) do
3341
+ Jar.create do |doc|
3342
+ doc._id = 1
3343
+ end
3344
+ end
3345
+
3346
+ it "allows creation of the document" do
3347
+ jar.id.should eq(1)
3348
+ end
3349
+ end
3350
+
3351
+ context "when adding a document" do
3352
+
3353
+ let(:person) do
3354
+ Person.new
3355
+ end
3356
+
3357
+ let(:post_one) do
3358
+ Post.new
3359
+ end
3360
+
3361
+ let(:first_add) do
3362
+ person.posts.push(post_one)
3363
+ end
3364
+
3365
+ context "when chaining a second add" do
3366
+
3367
+ let(:post_two) do
3368
+ Post.new
3369
+ end
3370
+
3371
+ let(:result) do
3372
+ first_add.push(post_two)
3373
+ end
3374
+
3375
+ it "adds both documents" do
3376
+ result.should eq([ post_one, post_two ])
3377
+ end
3378
+ end
3379
+ end
3380
+
3381
+ context "when pushing with a before_add callback" do
3382
+
3383
+ let(:artist) do
3384
+ Artist.new
3385
+ end
3386
+
3387
+ let(:album) do
3388
+ Album.new
3389
+ end
3390
+
3391
+ context "when execution raises no errors" do
3392
+
3393
+ before do
3394
+ artist.albums << album
3395
+ end
3396
+
3397
+ it "it executes method callbacks" do
3398
+ artist.before_add_referenced_called.should be_true
3399
+ end
3400
+
3401
+ it "it executes proc callbacks" do
3402
+ album.before_add_called.should be_true
3403
+ end
3404
+
3405
+ it "adds the document to the relation" do
3406
+ artist.albums.should eq([ album ])
3407
+ end
3408
+ end
3409
+
3410
+ context "when execution raises errors" do
3411
+
3412
+ before do
3413
+ artist.should_receive(:before_add_album).and_raise
3414
+ end
3415
+
3416
+ it "does not add the document to the relation" do
3417
+ expect {
3418
+ artist.albums << album
3419
+ }.to raise_error
3420
+ artist.albums.should be_empty
3421
+ end
3422
+ end
3423
+ end
3424
+
3425
+ context "when pushing with an after_add callback" do
3426
+
3427
+ let(:artist) do
3428
+ Artist.new
3429
+ end
3430
+
3431
+ let(:album) do
3432
+ Album.new
3433
+ end
3434
+
3435
+ it "executes the callback" do
3436
+ artist.albums << album
3437
+ artist.after_add_referenced_called.should be_true
3438
+ end
3439
+
3440
+ context "when execution raises errors" do
3441
+
3442
+ before do
3443
+ artist.should_receive(:after_add_album).and_raise
3444
+ end
3445
+
3446
+ it "adds the document to the relation" do
3447
+ expect {
3448
+ artist.albums << album
3449
+ }.to raise_error
3450
+ artist.albums.should eq([ album ])
3451
+ end
3452
+ end
3453
+ end
3454
+
3455
+ context "when #delete or #clear with before_remove callback" do
3456
+
3457
+ let(:artist) do
3458
+ Artist.new
3459
+ end
3460
+
3461
+ let(:album) do
3462
+ Album.new
3463
+ end
3464
+
3465
+ before do
3466
+ artist.albums << album
3467
+ end
3468
+
3469
+ context "when executing raises no errors" do
3470
+
3471
+ describe "#delete" do
3472
+
3473
+ before do
3474
+ artist.albums.delete album
3475
+ end
3476
+
3477
+ it "executes the callback" do
3478
+ artist.before_remove_referenced_called.should be_true
3479
+ end
3480
+
3481
+ it "removes the document from the relation" do
3482
+ artist.albums.should be_empty
3483
+ end
3484
+ end
3485
+
3486
+ describe "#clear" do
3487
+
3488
+ before do
3489
+ artist.albums.clear
3490
+ end
3491
+
3492
+ it "executes the callback" do
3493
+ artist.before_remove_referenced_called.should be_true
3494
+ end
3495
+
3496
+ it "clears the relation" do
3497
+ artist.albums.should be_empty
3498
+ end
3499
+ end
3500
+
3501
+ context "when execution raises errors" do
3502
+
3503
+ before do
3504
+ artist.should_receive(:before_remove_album).and_raise
3505
+ end
3506
+
3507
+ describe "#delete" do
3508
+
3509
+ before do
3510
+ expect {
3511
+ artist.albums.delete album
3512
+ }.to raise_error
3513
+ end
3514
+
3515
+ it "does not remove the document from the relation" do
3516
+ artist.albums.should eq([ album ])
3517
+ end
3518
+ end
3519
+
3520
+ describe "#clear" do
3521
+
3522
+ before do
3523
+ expect {
3524
+ artist.albums.clear
3525
+ }.to raise_error
3526
+ end
3527
+
3528
+ it "does not clear the relation" do
3529
+ artist.albums.should eq([ album ])
3530
+ end
3531
+ end
3532
+ end
3533
+ end
3534
+ end
3535
+
3536
+ context "when #delete or #clear with after_remove callback" do
3537
+
3538
+ let(:artist) do
3539
+ Artist.new
3540
+ end
3541
+
3542
+ let(:album) do
3543
+ Album.new
3544
+ end
3545
+
3546
+ before do
3547
+ artist.albums << album
3548
+ end
3549
+
3550
+ context "without errors" do
3551
+
3552
+ describe "#delete" do
3553
+
3554
+ before do
3555
+ artist.albums.delete album
3556
+ end
3557
+
3558
+ it "executes the callback" do
3559
+ artist.after_remove_referenced_called.should be_true
3560
+ end
3561
+ end
3562
+
3563
+ describe "#clear" do
3564
+
3565
+ before do
3566
+ artist.albums.clear
3567
+ end
3568
+
3569
+ it "executes the callback" do
3570
+ artist.albums.clear
3571
+ artist.after_remove_referenced_called.should be_true
3572
+ end
3573
+ end
3574
+ end
3575
+
3576
+ context "when errors are raised" do
3577
+
3578
+ before do
3579
+ artist.should_receive(:after_remove_album).and_raise
3580
+ end
3581
+
3582
+ describe "#delete" do
3583
+
3584
+ before do
3585
+ expect {
3586
+ artist.albums.delete album
3587
+ }.to raise_error
3588
+ end
3589
+
3590
+ it "removes the documents from the relation" do
3591
+ artist.albums.should be_empty
3592
+ end
3593
+ end
3594
+
3595
+ describe "#clear" do
3596
+
3597
+ before do
3598
+ expect {
3599
+ artist.albums.clear
3600
+ }.to raise_error
3601
+ end
3602
+
3603
+ it "removes the documents from the relation" do
3604
+ artist.albums.should be_empty
3605
+ end
3606
+ end
3607
+ end
3608
+ end
3609
+
3610
+ context "when executing a criteria call on an ordered relation" do
3611
+
3612
+ let(:person) do
3613
+ Person.create
3614
+ end
3615
+
3616
+ let!(:post_one) do
3617
+ person.ordered_posts.create(rating: 1)
3618
+ end
3619
+
3620
+ let!(:post_two) do
3621
+ person.ordered_posts.create(rating: 5)
3622
+ end
3623
+
3624
+ let(:criteria) do
3625
+ person.ordered_posts.only(:_id, :rating)
3626
+ end
3627
+
3628
+ it "does not drop the ordering" do
3629
+ criteria.should eq([ post_two, post_one ])
3630
+ end
3631
+ end
3632
+ end