mongoid 3.1.4 → 3.1.5

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