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