mongoid 3.1.4 → 3.1.5

Sign up to get free protection for your applications and to get access to all the features.
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