mongoid_rails4 4.0.0

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