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