mongoid 3.1.6 → 4.0.2

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 (571) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +479 -8
  3. data/README.md +10 -7
  4. data/lib/config/locales/en.yml +34 -20
  5. data/lib/mongoid.rb +10 -76
  6. data/lib/mongoid/atomic.rb +3 -14
  7. data/lib/mongoid/atomic/paths/embedded.rb +0 -30
  8. data/lib/mongoid/atomic/paths/embedded/many.rb +1 -1
  9. data/lib/mongoid/atomic/paths/embedded/one.rb +1 -1
  10. data/lib/mongoid/atomic/paths/root.rb +0 -13
  11. data/lib/mongoid/attributes.rb +65 -101
  12. data/lib/mongoid/attributes/dynamic.rb +154 -0
  13. data/lib/mongoid/attributes/nested.rb +82 -0
  14. data/lib/mongoid/attributes/processing.rb +13 -66
  15. data/lib/mongoid/{dirty.rb → changeable.rb} +32 -2
  16. data/lib/mongoid/composable.rb +105 -0
  17. data/lib/mongoid/config.rb +3 -9
  18. data/lib/mongoid/config/options.rb +1 -1
  19. data/lib/mongoid/contextual.rb +2 -0
  20. data/lib/mongoid/contextual/aggregable/memory.rb +2 -2
  21. data/lib/mongoid/contextual/aggregable/mongo.rb +7 -9
  22. data/lib/mongoid/contextual/atomic.rb +53 -53
  23. data/lib/mongoid/contextual/geo_near.rb +1 -1
  24. data/lib/mongoid/contextual/map_reduce.rb +4 -2
  25. data/lib/mongoid/contextual/memory.rb +23 -11
  26. data/lib/mongoid/contextual/mongo.rb +75 -57
  27. data/lib/mongoid/contextual/none.rb +90 -0
  28. data/lib/mongoid/contextual/text_search.rb +178 -0
  29. data/lib/mongoid/copyable.rb +2 -3
  30. data/lib/mongoid/criteria.rb +39 -34
  31. data/lib/mongoid/criteria/#findable.rb# +141 -0
  32. data/lib/mongoid/{criterion → criteria}/findable.rb +7 -47
  33. data/lib/mongoid/{criterion/inspection.rb → criteria/inspectable.rb} +2 -2
  34. data/lib/mongoid/{criterion → criteria}/marshalable.rb +3 -1
  35. data/lib/mongoid/{criterion → criteria}/modifiable.rb +28 -8
  36. data/lib/mongoid/criteria/permission.rb +70 -0
  37. data/lib/mongoid/{criterion/scoping.rb → criteria/scopable.rb} +2 -2
  38. data/lib/mongoid/document.rb +39 -24
  39. data/lib/mongoid/errors.rb +4 -1
  40. data/lib/mongoid/errors/document_not_destroyed.rb +25 -0
  41. data/lib/mongoid/errors/document_not_found.rb +2 -1
  42. data/lib/mongoid/errors/invalid_storage_options.rb +1 -1
  43. data/lib/mongoid/errors/invalid_storage_parent.rb +26 -0
  44. data/lib/mongoid/errors/invalid_value.rb +16 -0
  45. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  46. data/lib/mongoid/errors/readonly_document.rb +24 -0
  47. data/lib/mongoid/extensions.rb +15 -7
  48. data/lib/mongoid/extensions/array.rb +3 -3
  49. data/lib/mongoid/extensions/big_decimal.rb +1 -1
  50. data/lib/mongoid/extensions/boolean.rb +15 -17
  51. data/lib/mongoid/extensions/date.rb +1 -1
  52. data/lib/mongoid/extensions/date_time.rb +3 -3
  53. data/lib/mongoid/extensions/float.rb +2 -1
  54. data/lib/mongoid/extensions/hash.rb +3 -3
  55. data/lib/mongoid/extensions/integer.rb +1 -1
  56. data/lib/mongoid/extensions/object.rb +7 -7
  57. data/lib/mongoid/extensions/object_id.rb +5 -5
  58. data/lib/mongoid/extensions/range.rb +9 -3
  59. data/lib/mongoid/extensions/regexp.rb +1 -1
  60. data/lib/mongoid/extensions/set.rb +1 -1
  61. data/lib/mongoid/extensions/string.rb +6 -18
  62. data/lib/mongoid/extensions/symbol.rb +1 -1
  63. data/lib/mongoid/extensions/time.rb +3 -3
  64. data/lib/mongoid/extensions/time_with_zone.rb +1 -1
  65. data/lib/mongoid/factory.rb +8 -6
  66. data/lib/mongoid/fields.rb +41 -8
  67. data/lib/mongoid/fields/foreign_key.rb +3 -3
  68. data/lib/mongoid/fields/localized.rb +1 -1
  69. data/lib/mongoid/fields/standard.rb +5 -17
  70. data/lib/mongoid/fields/validators/macro.rb +15 -5
  71. data/lib/mongoid/{finders.rb → findable.rb} +35 -7
  72. data/lib/mongoid/{indexes.rb → indexable.rb} +50 -55
  73. data/lib/mongoid/indexable/specification.rb +104 -0
  74. data/lib/mongoid/{indexes → indexable}/validators/options.rb +2 -1
  75. data/lib/mongoid/{inspection.rb → inspectable.rb} +15 -11
  76. data/lib/mongoid/{callbacks.rb → interceptable.rb} +30 -62
  77. data/lib/mongoid/log_subscriber.rb +55 -0
  78. data/lib/mongoid/matchable.rb +152 -0
  79. data/lib/mongoid/{matchers → matchable}/all.rb +1 -1
  80. data/lib/mongoid/{matchers → matchable}/and.rb +2 -2
  81. data/lib/mongoid/{matchers → matchable}/default.rb +1 -1
  82. data/lib/mongoid/{matchers → matchable}/exists.rb +1 -1
  83. data/lib/mongoid/{matchers → matchable}/gt.rb +1 -1
  84. data/lib/mongoid/{matchers → matchable}/gte.rb +1 -1
  85. data/lib/mongoid/{matchers → matchable}/in.rb +2 -2
  86. data/lib/mongoid/{matchers → matchable}/lt.rb +1 -1
  87. data/lib/mongoid/{matchers → matchable}/lte.rb +1 -1
  88. data/lib/mongoid/{matchers → matchable}/ne.rb +2 -2
  89. data/lib/mongoid/{matchers → matchable}/nin.rb +3 -2
  90. data/lib/mongoid/{matchers → matchable}/or.rb +2 -2
  91. data/lib/mongoid/{matchers → matchable}/size.rb +1 -1
  92. data/lib/mongoid/persistable.rb +216 -0
  93. data/lib/mongoid/persistable/creatable.rb +189 -0
  94. data/lib/mongoid/persistable/deletable.rb +149 -0
  95. data/lib/mongoid/persistable/destroyable.rb +60 -0
  96. data/lib/mongoid/persistable/incrementable.rb +36 -0
  97. data/lib/mongoid/persistable/logical.rb +38 -0
  98. data/lib/mongoid/persistable/poppable.rb +39 -0
  99. data/lib/mongoid/persistable/pullable.rb +55 -0
  100. data/lib/mongoid/persistable/pushable.rb +62 -0
  101. data/lib/mongoid/persistable/renamable.rb +35 -0
  102. data/lib/mongoid/persistable/savable.rb +52 -0
  103. data/lib/mongoid/persistable/settable.rb +33 -0
  104. data/lib/mongoid/persistable/unsettable.rb +36 -0
  105. data/lib/mongoid/persistable/updatable.rb +153 -0
  106. data/lib/mongoid/persistable/upsertable.rb +55 -0
  107. data/lib/mongoid/positional.rb +71 -0
  108. data/lib/mongoid/query_cache.rb +255 -0
  109. data/lib/mongoid/railtie.rb +34 -60
  110. data/lib/mongoid/railties/database.rake +9 -25
  111. data/lib/mongoid/relations.rb +11 -25
  112. data/lib/mongoid/relations/accessors.rb +15 -51
  113. data/lib/mongoid/relations/auto_save.rb +15 -36
  114. data/lib/mongoid/relations/binding.rb +2 -25
  115. data/lib/mongoid/relations/bindings/embedded/in.rb +1 -1
  116. data/lib/mongoid/relations/bindings/embedded/many.rb +1 -3
  117. data/lib/mongoid/relations/bindings/referenced/in.rb +3 -8
  118. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +4 -2
  119. data/lib/mongoid/relations/builder.rb +1 -1
  120. data/lib/mongoid/relations/builders.rb +2 -2
  121. data/lib/mongoid/relations/builders/embedded/one.rb +1 -1
  122. data/lib/mongoid/relations/builders/nested_attributes/many.rb +10 -13
  123. data/lib/mongoid/relations/builders/nested_attributes/one.rb +5 -6
  124. data/lib/mongoid/relations/builders/referenced/in.rb +1 -1
  125. data/lib/mongoid/relations/builders/referenced/many.rb +1 -2
  126. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +1 -2
  127. data/lib/mongoid/relations/builders/referenced/one.rb +1 -1
  128. data/lib/mongoid/relations/cascading.rb +3 -5
  129. data/lib/mongoid/relations/constraint.rb +1 -1
  130. data/lib/mongoid/relations/conversions.rb +1 -1
  131. data/lib/mongoid/relations/counter_cache.rb +39 -15
  132. data/lib/mongoid/relations/eager.rb +46 -0
  133. data/lib/mongoid/relations/eager/base.rb +149 -0
  134. data/lib/mongoid/relations/eager/belongs_to.rb +31 -0
  135. data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +47 -0
  136. data/lib/mongoid/relations/eager/has_many.rb +38 -0
  137. data/lib/mongoid/relations/eager/has_one.rb +30 -0
  138. data/lib/mongoid/relations/embedded/batchable.rb +4 -5
  139. data/lib/mongoid/relations/embedded/in.rb +4 -4
  140. data/lib/mongoid/relations/embedded/many.rb +14 -32
  141. data/lib/mongoid/relations/embedded/one.rb +1 -1
  142. data/lib/mongoid/relations/macros.rb +3 -4
  143. data/lib/mongoid/relations/many.rb +51 -31
  144. data/lib/mongoid/relations/marshalable.rb +3 -3
  145. data/lib/mongoid/relations/metadata.rb +14 -79
  146. data/lib/mongoid/relations/nested_builder.rb +2 -2
  147. data/lib/mongoid/relations/one.rb +1 -1
  148. data/lib/mongoid/relations/options.rb +1 -0
  149. data/lib/mongoid/relations/polymorphic.rb +0 -1
  150. data/lib/mongoid/relations/proxy.rb +21 -41
  151. data/lib/mongoid/relations/referenced/in.rb +4 -20
  152. data/lib/mongoid/relations/referenced/many.rb +22 -35
  153. data/lib/mongoid/relations/referenced/many_to_many.rb +19 -42
  154. data/lib/mongoid/relations/referenced/one.rb +6 -25
  155. data/lib/mongoid/relations/synchronization.rb +4 -4
  156. data/lib/mongoid/relations/targets/enumerable.rb +10 -10
  157. data/lib/mongoid/relations/touchable.rb +34 -1
  158. data/lib/mongoid/{reloading.rb → reloadable.rb} +7 -5
  159. data/lib/mongoid/{scoping.rb → scopable.rb} +36 -36
  160. data/lib/mongoid/selectable.rb +59 -0
  161. data/lib/mongoid/{serialization.rb → serializable.rb} +11 -2
  162. data/lib/mongoid/sessions.rb +37 -345
  163. data/lib/mongoid/sessions/factory.rb +2 -0
  164. data/lib/mongoid/sessions/options.rb +185 -0
  165. data/lib/mongoid/sessions/storage_options.rb +140 -0
  166. data/lib/mongoid/sessions/thread_options.rb +19 -0
  167. data/lib/mongoid/sessions/validators/storage.rb +16 -3
  168. data/lib/mongoid/{sharding.rb → shardable.rb} +5 -1
  169. data/lib/mongoid/{state.rb → stateful.rb} +13 -1
  170. data/lib/mongoid/support/query_counter.rb +23 -0
  171. data/lib/mongoid/tasks/database.rake +31 -0
  172. data/lib/mongoid/tasks/database.rb +107 -0
  173. data/lib/mongoid/threaded.rb +26 -172
  174. data/lib/mongoid/threaded/lifecycle.rb +0 -28
  175. data/lib/mongoid/timestamps/updated/short.rb +2 -2
  176. data/lib/mongoid/{hierarchy.rb → traversable.rb} +15 -7
  177. data/lib/mongoid/{validations.rb → validatable.rb} +23 -10
  178. data/lib/mongoid/{validations → validatable}/associated.rb +4 -2
  179. data/lib/mongoid/{validations → validatable}/format.rb +1 -1
  180. data/lib/mongoid/{validations → validatable}/length.rb +1 -1
  181. data/lib/mongoid/{validations → validatable}/localizable.rb +1 -1
  182. data/lib/mongoid/{validations → validatable}/macros.rb +4 -3
  183. data/lib/mongoid/{validations → validatable}/presence.rb +1 -1
  184. data/lib/mongoid/{validations → validatable}/queryable.rb +1 -2
  185. data/lib/mongoid/{validations → validatable}/uniqueness.rb +25 -21
  186. data/lib/mongoid/version.rb +1 -1
  187. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +46 -25
  188. data/lib/rails/generators/mongoid/model/model_generator.rb +0 -1
  189. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +0 -3
  190. data/lib/rails/generators/mongoid_generator.rb +3 -40
  191. data/lib/rails/mongoid.rb +0 -122
  192. data/lib/support/ruby_version.rb +1 -1
  193. data/spec/app/models/account.rb +2 -6
  194. data/spec/app/models/acolyte.rb +2 -1
  195. data/spec/app/models/actor.rb +0 -1
  196. data/spec/app/models/address.rb +8 -3
  197. data/spec/app/models/animal.rb +1 -1
  198. data/spec/app/models/appointment.rb +3 -3
  199. data/spec/app/models/article.rb +1 -4
  200. data/spec/app/models/audio.rb +5 -0
  201. data/spec/app/models/author.rb +0 -2
  202. data/spec/app/models/band.rb +3 -2
  203. data/spec/app/models/bar.rb +1 -0
  204. data/spec/app/models/book.rb +1 -0
  205. data/spec/app/models/building.rb +0 -2
  206. data/spec/app/models/building_address.rb +0 -2
  207. data/spec/app/models/bus.rb +1 -1
  208. data/spec/app/models/canvas.rb +1 -1
  209. data/spec/app/models/contextable_item.rb +5 -0
  210. data/spec/app/models/contractor.rb +0 -2
  211. data/spec/app/models/country_code.rb +1 -1
  212. data/spec/app/models/definition.rb +2 -2
  213. data/spec/app/models/dog.rb +1 -1
  214. data/spec/app/models/draft.rb +9 -0
  215. data/spec/app/models/dragon.rb +4 -0
  216. data/spec/app/models/drug.rb +1 -3
  217. data/spec/app/models/dungeon.rb +4 -0
  218. data/spec/app/models/edit.rb +5 -0
  219. data/spec/app/models/even.rb +7 -0
  220. data/spec/app/models/event.rb +1 -1
  221. data/spec/app/models/filesystem.rb +1 -0
  222. data/spec/app/models/fish.rb +0 -1
  223. data/spec/app/models/fruits.rb +6 -0
  224. data/spec/app/models/game.rb +0 -2
  225. data/spec/app/models/house.rb +1 -3
  226. data/spec/app/models/id_key.rb +6 -0
  227. data/spec/app/models/item.rb +1 -5
  228. data/spec/app/models/jar.rb +1 -1
  229. data/spec/app/models/label.rb +4 -4
  230. data/spec/app/models/line_item.rb +1 -1
  231. data/spec/app/models/login.rb +1 -1
  232. data/spec/app/models/message.rb +8 -0
  233. data/spec/app/models/movie.rb +1 -0
  234. data/spec/app/models/name.rb +3 -3
  235. data/spec/app/models/note.rb +3 -1
  236. data/spec/app/models/odd.rb +7 -0
  237. data/spec/app/models/oscar.rb +1 -1
  238. data/spec/app/models/parent_doc.rb +1 -1
  239. data/spec/app/models/person.rb +16 -10
  240. data/spec/app/models/phone.rb +1 -3
  241. data/spec/app/models/player.rb +3 -3
  242. data/spec/app/models/post.rb +5 -3
  243. data/spec/app/models/preference.rb +1 -1
  244. data/spec/app/models/quiz.rb +0 -3
  245. data/spec/app/models/record.rb +10 -5
  246. data/spec/app/models/registry.rb +1 -1
  247. data/spec/app/models/server.rb +1 -1
  248. data/spec/app/models/service.rb +3 -3
  249. data/spec/app/models/sound.rb +5 -0
  250. data/spec/app/models/symptom.rb +1 -1
  251. data/spec/app/models/template.rb +1 -1
  252. data/spec/app/models/title.rb +0 -1
  253. data/spec/app/models/track.rb +5 -5
  254. data/spec/app/models/tree.rb +3 -3
  255. data/spec/app/models/video.rb +1 -5
  256. data/spec/app/models/wiki_page.rb +2 -5
  257. data/spec/app/models/word.rb +3 -0
  258. data/spec/app/models/word_origin.rb +1 -1
  259. data/spec/config/mongoid.yml +7 -8
  260. data/spec/helpers.rb +18 -0
  261. data/spec/mongoid/#atomic_spec.rb# +365 -0
  262. data/spec/mongoid/atomic/modifiers_spec.rb +22 -22
  263. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +8 -49
  264. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +7 -49
  265. data/spec/mongoid/atomic/paths/root_spec.rb +3 -61
  266. data/spec/mongoid/atomic/paths_spec.rb +19 -19
  267. data/spec/mongoid/atomic_spec.rb +19 -19
  268. data/spec/mongoid/{nested_attributes_spec.rb → attributes/nested_spec.rb} +474 -592
  269. data/spec/mongoid/attributes/readonly_spec.rb +58 -18
  270. data/spec/mongoid/attributes_spec.rb +349 -434
  271. data/spec/mongoid/{dirty_spec.rb → changeable_spec.rb} +203 -153
  272. data/spec/mongoid/{components_spec.rb → composable_spec.rb} +3 -3
  273. data/spec/mongoid/config/environment_spec.rb +3 -3
  274. data/spec/mongoid/config/options_spec.rb +6 -6
  275. data/spec/mongoid/config_spec.rb +24 -48
  276. data/spec/mongoid/contextual/aggregable/memory_spec.rb +12 -12
  277. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +78 -38
  278. data/spec/mongoid/contextual/atomic_spec.rb +60 -56
  279. data/spec/mongoid/contextual/find_and_modify_spec.rb +14 -14
  280. data/spec/mongoid/contextual/geo_near_spec.rb +22 -22
  281. data/spec/mongoid/contextual/map_reduce_spec.rb +27 -27
  282. data/spec/mongoid/contextual/memory_spec.rb +156 -94
  283. data/spec/mongoid/contextual/mongo_spec.rb +238 -150
  284. data/spec/mongoid/contextual/none_spec.rb +127 -0
  285. data/spec/mongoid/contextual/text_search_spec.rb +209 -0
  286. data/spec/mongoid/copyable_spec.rb +56 -68
  287. data/spec/mongoid/criteria/findable_spec.rb +991 -0
  288. data/spec/mongoid/{criterion/inspection_spec.rb → criteria/inspectable_spec.rb} +5 -5
  289. data/spec/mongoid/{criterion → criteria}/marshalable_spec.rb +2 -2
  290. data/spec/mongoid/criteria/modifiable_spec.rb +1252 -0
  291. data/spec/mongoid/{criterion/scoping_spec.rb → criteria/scopable_spec.rb} +37 -37
  292. data/spec/mongoid/criteria_spec.rb +715 -2421
  293. data/spec/mongoid/document_spec.rb +171 -121
  294. data/spec/mongoid/equality_spec.rb +22 -22
  295. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +3 -3
  296. data/spec/mongoid/errors/callback_spec.rb +3 -3
  297. data/spec/mongoid/errors/delete_restriction_spec.rb +3 -3
  298. data/spec/mongoid/errors/document_not_destroyed_spec.rb +33 -0
  299. data/spec/mongoid/errors/document_not_found_spec.rb +11 -11
  300. data/spec/mongoid/errors/eager_load_spec.rb +3 -3
  301. data/spec/mongoid/errors/invalid_collection_spec.rb +3 -3
  302. data/spec/mongoid/errors/invalid_config_option_spec.rb +3 -3
  303. data/spec/mongoid/errors/invalid_field_option_spec.rb +3 -3
  304. data/spec/mongoid/errors/invalid_field_spec.rb +3 -3
  305. data/spec/mongoid/errors/invalid_find_spec.rb +3 -3
  306. data/spec/mongoid/errors/invalid_includes_spec.rb +3 -3
  307. data/spec/mongoid/errors/invalid_index_spec.rb +3 -3
  308. data/spec/mongoid/errors/invalid_options_spec.rb +3 -3
  309. data/spec/mongoid/errors/invalid_path_spec.rb +3 -3
  310. data/spec/mongoid/errors/invalid_scope_spec.rb +5 -5
  311. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +3 -3
  312. data/spec/mongoid/errors/invalid_storage_options_spec.rb +3 -3
  313. data/spec/mongoid/errors/invalid_time_spec.rb +3 -3
  314. data/spec/mongoid/errors/inverse_not_found_spec.rb +3 -3
  315. data/spec/mongoid/errors/mixed_relations_spec.rb +3 -3
  316. data/spec/mongoid/errors/mixed_session_configuration_spec.rb +3 -3
  317. data/spec/mongoid/errors/mongoid_error_spec.rb +8 -8
  318. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +3 -3
  319. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  320. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +3 -3
  321. data/spec/mongoid/errors/no_metadata_spec.rb +3 -3
  322. data/spec/mongoid/errors/no_parent_spec.rb +3 -3
  323. data/spec/mongoid/errors/no_session_config_spec.rb +3 -3
  324. data/spec/mongoid/errors/no_session_database_spec.rb +3 -3
  325. data/spec/mongoid/errors/no_session_hosts_spec.rb +3 -3
  326. data/spec/mongoid/errors/no_sessions_config_spec.rb +3 -3
  327. data/spec/mongoid/errors/readonly_attribute_spec.rb +3 -3
  328. data/spec/mongoid/errors/readonly_document_spec.rb +29 -0
  329. data/spec/mongoid/errors/scope_overwrite_spec.rb +3 -3
  330. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +3 -3
  331. data/spec/mongoid/errors/unknown_attribute_spec.rb +5 -5
  332. data/spec/mongoid/errors/unsaved_document_spec.rb +3 -3
  333. data/spec/mongoid/errors/unsupported_javascript_spec.rb +3 -3
  334. data/spec/mongoid/errors/validations_spec.rb +7 -7
  335. data/spec/mongoid/extensions/array_spec.rb +61 -61
  336. data/spec/mongoid/extensions/big_decimal_spec.rb +11 -11
  337. data/spec/mongoid/extensions/binary_spec.rb +12 -12
  338. data/spec/mongoid/extensions/boolean_spec.rb +18 -18
  339. data/spec/mongoid/extensions/date_spec.rb +13 -13
  340. data/spec/mongoid/extensions/date_time_spec.rb +8 -8
  341. data/spec/mongoid/extensions/false_class_spec.rb +5 -5
  342. data/spec/mongoid/extensions/float_spec.rb +29 -15
  343. data/spec/mongoid/extensions/hash_spec.rb +29 -29
  344. data/spec/mongoid/extensions/integer_spec.rb +15 -15
  345. data/spec/mongoid/extensions/module_spec.rb +2 -2
  346. data/spec/mongoid/extensions/nil_class_spec.rb +1 -1
  347. data/spec/mongoid/extensions/object_id_spec.rb +134 -134
  348. data/spec/mongoid/extensions/object_spec.rb +26 -26
  349. data/spec/mongoid/extensions/range_spec.rb +61 -12
  350. data/spec/mongoid/extensions/regexp_spec.rb +4 -4
  351. data/spec/mongoid/extensions/set_spec.rb +4 -4
  352. data/spec/mongoid/extensions/string_spec.rb +35 -46
  353. data/spec/mongoid/extensions/symbol_spec.rb +9 -9
  354. data/spec/mongoid/extensions/time_spec.rb +49 -49
  355. data/spec/mongoid/extensions/time_with_zone_spec.rb +34 -34
  356. data/spec/mongoid/extensions/true_class_spec.rb +5 -5
  357. data/spec/mongoid/extensions_spec.rb +29 -0
  358. data/spec/mongoid/factory_spec.rb +15 -15
  359. data/spec/mongoid/fields/foreign_key_spec.rb +73 -66
  360. data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +15 -15
  361. data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +22 -22
  362. data/spec/mongoid/fields/localized_spec.rb +38 -23
  363. data/spec/mongoid/fields/standard_spec.rb +12 -12
  364. data/spec/mongoid/fields_spec.rb +263 -217
  365. data/spec/mongoid/findable_spec.rb +509 -0
  366. data/spec/mongoid/indexable/specification_spec.rb +102 -0
  367. data/spec/mongoid/{indexes_spec.rb → indexable_spec.rb} +171 -51
  368. data/spec/mongoid/{inspection_spec.rb → inspectable_spec.rb} +6 -14
  369. data/spec/mongoid/{callbacks_spec.rb → interceptable_spec.rb} +117 -116
  370. data/spec/mongoid/log_subscriber_spec.rb +75 -0
  371. data/spec/mongoid/loggable_spec.rb +1 -1
  372. data/spec/mongoid/{matchers → matchable}/all_spec.rb +4 -4
  373. data/spec/mongoid/{matchers → matchable}/and_spec.rb +11 -11
  374. data/spec/mongoid/{matchers → matchable}/default_spec.rb +15 -15
  375. data/spec/mongoid/{matchers → matchable}/exists_spec.rb +5 -5
  376. data/spec/mongoid/{matchers → matchable}/gt_spec.rb +9 -8
  377. data/spec/mongoid/{matchers → matchable}/gte_spec.rb +7 -7
  378. data/spec/mongoid/matchable/in_spec.rb +49 -0
  379. data/spec/mongoid/{matchers → matchable}/lt_spec.rb +7 -7
  380. data/spec/mongoid/{matchers → matchable}/lte_spec.rb +7 -7
  381. data/spec/mongoid/matchable/ne_spec.rb +46 -0
  382. data/spec/mongoid/matchable/nin_spec.rb +48 -0
  383. data/spec/mongoid/{matchers → matchable}/or_spec.rb +6 -6
  384. data/spec/mongoid/{matchers → matchable}/size_spec.rb +3 -3
  385. data/spec/mongoid/{matchers_spec.rb → matchable_spec.rb} +41 -41
  386. data/spec/mongoid/persistable/creatable_spec.rb +553 -0
  387. data/spec/mongoid/persistable/deletable_spec.rb +218 -0
  388. data/spec/mongoid/persistable/destroyable_spec.rb +192 -0
  389. data/spec/mongoid/persistable/incrementable_spec.rb +173 -0
  390. data/spec/mongoid/persistable/logical_spec.rb +143 -0
  391. data/spec/mongoid/persistable/poppable_spec.rb +115 -0
  392. data/spec/mongoid/persistable/pullable_spec.rb +228 -0
  393. data/spec/mongoid/persistable/pushable_spec.rb +258 -0
  394. data/spec/mongoid/persistable/renamable_spec.rb +135 -0
  395. data/spec/mongoid/persistable/savable_spec.rb +498 -0
  396. data/spec/mongoid/persistable/settable_spec.rb +162 -0
  397. data/spec/mongoid/persistable/unsettable_spec.rb +155 -0
  398. data/spec/mongoid/persistable/updatable_spec.rb +558 -0
  399. data/spec/mongoid/persistable/upsertable_spec.rb +106 -0
  400. data/spec/mongoid/persistable_spec.rb +206 -0
  401. data/spec/mongoid/{atomic/positionable_spec.rb → positional_spec.rb} +14 -19
  402. data/spec/mongoid/query_cache_spec.rb +263 -0
  403. data/spec/mongoid/railties/document_spec.rb +2 -2
  404. data/spec/mongoid/relations/accessors_spec.rb +53 -145
  405. data/spec/mongoid/relations/auto_save_spec.rb +37 -17
  406. data/spec/mongoid/relations/bindings/embedded/in_spec.rb +12 -12
  407. data/spec/mongoid/relations/bindings/embedded/many_spec.rb +3 -3
  408. data/spec/mongoid/relations/bindings/embedded/one_spec.rb +5 -5
  409. data/spec/mongoid/relations/bindings/referenced/in_spec.rb +26 -26
  410. data/spec/mongoid/relations/bindings/referenced/many_spec.rb +10 -10
  411. data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +19 -19
  412. data/spec/mongoid/relations/bindings/referenced/one_spec.rb +12 -12
  413. data/spec/mongoid/relations/builders/embedded/in_spec.rb +4 -4
  414. data/spec/mongoid/relations/builders/embedded/many_spec.rb +18 -18
  415. data/spec/mongoid/relations/builders/embedded/one_spec.rb +11 -11
  416. data/spec/mongoid/relations/builders/nested_attributes/many_spec.rb +12 -13
  417. data/spec/mongoid/relations/builders/nested_attributes/one_spec.rb +14 -14
  418. data/spec/mongoid/relations/builders/referenced/in_spec.rb +24 -35
  419. data/spec/mongoid/relations/builders/referenced/many_spec.rb +15 -15
  420. data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +18 -18
  421. data/spec/mongoid/relations/builders/referenced/one_spec.rb +12 -25
  422. data/spec/mongoid/relations/builders_spec.rb +21 -21
  423. data/spec/mongoid/relations/cascading/delete_spec.rb +9 -9
  424. data/spec/mongoid/relations/cascading/destroy_spec.rb +6 -6
  425. data/spec/mongoid/relations/cascading/nullify_spec.rb +4 -4
  426. data/spec/mongoid/relations/cascading/restrict_spec.rb +7 -7
  427. data/spec/mongoid/relations/cascading_spec.rb +16 -16
  428. data/spec/mongoid/relations/constraint_spec.rb +8 -7
  429. data/spec/mongoid/relations/conversions_spec.rb +16 -14
  430. data/spec/mongoid/relations/counter_cache_spec.rb +85 -0
  431. data/spec/mongoid/relations/cyclic_spec.rb +18 -18
  432. data/spec/mongoid/relations/eager/belongs_to_spec.rb +154 -0
  433. data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +117 -0
  434. data/spec/mongoid/relations/eager/has_many_spec.rb +207 -0
  435. data/spec/mongoid/relations/eager/has_one_spec.rb +163 -0
  436. data/spec/mongoid/relations/eager_spec.rb +228 -0
  437. data/spec/mongoid/relations/embedded/dirty_spec.rb +8 -8
  438. data/spec/mongoid/relations/embedded/in_spec.rb +56 -57
  439. data/spec/mongoid/relations/embedded/many_spec.rb +467 -372
  440. data/spec/mongoid/relations/embedded/one_spec.rb +108 -141
  441. data/spec/mongoid/relations/macros_spec.rb +108 -102
  442. data/spec/mongoid/relations/metadata_spec.rb +180 -255
  443. data/spec/mongoid/relations/options_spec.rb +1 -1
  444. data/spec/mongoid/relations/polymorphic_spec.rb +13 -17
  445. data/spec/mongoid/relations/proxy_spec.rb +2 -2
  446. data/spec/mongoid/relations/referenced/in_spec.rb +128 -303
  447. data/spec/mongoid/relations/referenced/many_spec.rb +587 -527
  448. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +401 -424
  449. data/spec/mongoid/relations/referenced/one_spec.rb +149 -264
  450. data/spec/mongoid/relations/reflections_spec.rb +6 -6
  451. data/spec/mongoid/relations/synchronization_spec.rb +46 -50
  452. data/spec/mongoid/relations/targets/enumerable_spec.rb +118 -118
  453. data/spec/mongoid/relations/touchable_spec.rb +333 -0
  454. data/spec/mongoid/relations_spec.rb +16 -15
  455. data/spec/mongoid/{reloading_spec.rb → reloadable_spec.rb} +38 -55
  456. data/spec/mongoid/{scoping_spec.rb → scopable_spec.rb} +89 -164
  457. data/spec/mongoid/selectable_spec.rb +134 -0
  458. data/spec/mongoid/{serialization_spec.rb → serializable_spec.rb} +129 -82
  459. data/spec/mongoid/sessions/factory_spec.rb +49 -28
  460. data/spec/mongoid/sessions/mongo_uri_spec.rb +7 -7
  461. data/spec/mongoid/sessions/options_spec.rb +108 -0
  462. data/spec/mongoid/sessions_spec.rb +319 -178
  463. data/spec/mongoid/{sharding_spec.rb → shardable_spec.rb} +8 -8
  464. data/spec/mongoid/{state_spec.rb → stateful_spec.rb} +36 -11
  465. data/spec/mongoid/tasks/database_rake_spec.rb +285 -0
  466. data/spec/mongoid/tasks/database_spec.rb +160 -0
  467. data/spec/mongoid/threaded_spec.rb +17 -70
  468. data/spec/mongoid/timestamps/created/short_spec.rb +6 -6
  469. data/spec/mongoid/timestamps/created_spec.rb +5 -5
  470. data/spec/mongoid/timestamps/timeless_spec.rb +6 -6
  471. data/spec/mongoid/timestamps/updated/short_spec.rb +11 -11
  472. data/spec/mongoid/timestamps/updated_spec.rb +9 -13
  473. data/spec/mongoid/timestamps_spec.rb +9 -13
  474. data/spec/mongoid/{hierarchy_spec.rb → traversable_spec.rb} +19 -19
  475. data/spec/mongoid/{validations → validatable}/associated_spec.rb +45 -22
  476. data/spec/mongoid/{validations → validatable}/format_spec.rb +6 -6
  477. data/spec/mongoid/{validations → validatable}/length_spec.rb +14 -14
  478. data/spec/mongoid/{validations → validatable}/numericality_spec.rb +1 -1
  479. data/spec/mongoid/{validations → validatable}/presence_spec.rb +37 -44
  480. data/spec/mongoid/{validations → validatable}/uniqueness_spec.rb +184 -192
  481. data/spec/mongoid/{validations_spec.rb → validatable_spec.rb} +28 -28
  482. data/spec/mongoid_spec.rb +8 -8
  483. data/spec/rails/mongoid_spec.rb +19 -335
  484. data/spec/spec_helper.rb +31 -13
  485. metadata +303 -283
  486. data/lib/mongoid/atomic/positionable.rb +0 -73
  487. data/lib/mongoid/components.rb +0 -92
  488. data/lib/mongoid/config/inflections.rb +0 -6
  489. data/lib/mongoid/contextual/eager.rb +0 -158
  490. data/lib/mongoid/errors/versioning_not_on_root.rb +0 -23
  491. data/lib/mongoid/identity_map.rb +0 -163
  492. data/lib/mongoid/json.rb +0 -16
  493. data/lib/mongoid/matchers.rb +0 -32
  494. data/lib/mongoid/matchers/strategies.rb +0 -97
  495. data/lib/mongoid/multi_parameter_attributes.rb +0 -105
  496. data/lib/mongoid/nested_attributes.rb +0 -78
  497. data/lib/mongoid/observer.rb +0 -192
  498. data/lib/mongoid/paranoia.rb +0 -136
  499. data/lib/mongoid/persistence.rb +0 -357
  500. data/lib/mongoid/persistence/atomic.rb +0 -231
  501. data/lib/mongoid/persistence/atomic/add_to_set.rb +0 -47
  502. data/lib/mongoid/persistence/atomic/bit.rb +0 -35
  503. data/lib/mongoid/persistence/atomic/inc.rb +0 -45
  504. data/lib/mongoid/persistence/atomic/operation.rb +0 -154
  505. data/lib/mongoid/persistence/atomic/pop.rb +0 -32
  506. data/lib/mongoid/persistence/atomic/pull.rb +0 -32
  507. data/lib/mongoid/persistence/atomic/pull_all.rb +0 -32
  508. data/lib/mongoid/persistence/atomic/push.rb +0 -25
  509. data/lib/mongoid/persistence/atomic/push_all.rb +0 -25
  510. data/lib/mongoid/persistence/atomic/rename.rb +0 -30
  511. data/lib/mongoid/persistence/atomic/sets.rb +0 -28
  512. data/lib/mongoid/persistence/atomic/unset.rb +0 -27
  513. data/lib/mongoid/persistence/deletion.rb +0 -31
  514. data/lib/mongoid/persistence/insertion.rb +0 -38
  515. data/lib/mongoid/persistence/modification.rb +0 -35
  516. data/lib/mongoid/persistence/operations.rb +0 -214
  517. data/lib/mongoid/persistence/operations/embedded/insert.rb +0 -46
  518. data/lib/mongoid/persistence/operations/embedded/remove.rb +0 -43
  519. data/lib/mongoid/persistence/operations/insert.rb +0 -34
  520. data/lib/mongoid/persistence/operations/remove.rb +0 -33
  521. data/lib/mongoid/persistence/operations/update.rb +0 -59
  522. data/lib/mongoid/persistence/operations/upsert.rb +0 -28
  523. data/lib/mongoid/persistence/upsertion.rb +0 -31
  524. data/lib/mongoid/unit_of_work.rb +0 -61
  525. data/lib/mongoid/versioning.rb +0 -217
  526. data/lib/rack/mongoid.rb +0 -2
  527. data/lib/rack/mongoid/middleware/identity_map.rb +0 -39
  528. data/lib/rails/generators/mongoid/observer/observer_generator.rb +0 -17
  529. data/lib/rails/generators/mongoid/observer/templates/observer.rb.tt +0 -4
  530. data/spec/app/models/actor_observer.rb +0 -15
  531. data/spec/app/models/callback_recorder.rb +0 -25
  532. data/spec/app/models/paranoid_phone.rb +0 -25
  533. data/spec/app/models/paranoid_post.rb +0 -36
  534. data/spec/app/models/phone_observer.rb +0 -6
  535. data/spec/mongoid/attributes/processing_spec.rb +0 -149
  536. data/spec/mongoid/criterion/destructive_spec.rb +0 -101
  537. data/spec/mongoid/criterion/modifiable_spec.rb +0 -409
  538. data/spec/mongoid/criterion/modification_spec.rb +0 -402
  539. data/spec/mongoid/errors/versioning_not_on_root_spec.rb +0 -29
  540. data/spec/mongoid/finders_spec.rb +0 -321
  541. data/spec/mongoid/identity_map_spec.rb +0 -564
  542. data/spec/mongoid/json_spec.rb +0 -33
  543. data/spec/mongoid/matchers/in_spec.rb +0 -25
  544. data/spec/mongoid/matchers/ne_spec.rb +0 -25
  545. data/spec/mongoid/matchers/nin_spec.rb +0 -25
  546. data/spec/mongoid/multi_parameter_attributes_spec.rb +0 -128
  547. data/spec/mongoid/observer_spec.rb +0 -290
  548. data/spec/mongoid/paranoia_spec.rb +0 -759
  549. data/spec/mongoid/persistence/atomic/add_to_set_spec.rb +0 -262
  550. data/spec/mongoid/persistence/atomic/bit_spec.rb +0 -88
  551. data/spec/mongoid/persistence/atomic/inc_spec.rb +0 -133
  552. data/spec/mongoid/persistence/atomic/pop_spec.rb +0 -111
  553. data/spec/mongoid/persistence/atomic/pull_all_spec.rb +0 -77
  554. data/spec/mongoid/persistence/atomic/pull_spec.rb +0 -80
  555. data/spec/mongoid/persistence/atomic/push_all_spec.rb +0 -77
  556. data/spec/mongoid/persistence/atomic/push_spec.rb +0 -77
  557. data/spec/mongoid/persistence/atomic/rename_spec.rb +0 -42
  558. data/spec/mongoid/persistence/atomic/sets_spec.rb +0 -154
  559. data/spec/mongoid/persistence/atomic/unset_spec.rb +0 -65
  560. data/spec/mongoid/persistence/atomic_spec.rb +0 -216
  561. data/spec/mongoid/persistence/operations/embedded/insert_spec.rb +0 -191
  562. data/spec/mongoid/persistence/operations/embedded/remove_spec.rb +0 -8
  563. data/spec/mongoid/persistence/operations/insert_spec.rb +0 -149
  564. data/spec/mongoid/persistence/operations/remove_spec.rb +0 -113
  565. data/spec/mongoid/persistence/operations/update_spec.rb +0 -141
  566. data/spec/mongoid/persistence/operations/upsert_spec.rb +0 -59
  567. data/spec/mongoid/persistence/operations_spec.rb +0 -313
  568. data/spec/mongoid/persistence_spec.rb +0 -2279
  569. data/spec/mongoid/unit_of_work_spec.rb +0 -196
  570. data/spec/mongoid/versioning_spec.rb +0 -540
  571. data/spec/rack/mongoid/middleware/identity_map_spec.rb +0 -72
@@ -1,313 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Mongoid::Persistence::Operations do
4
-
5
- let(:document) do
6
- Person.new
7
- end
8
-
9
- let(:klass) do
10
- Class.new do
11
- include Mongoid::Persistence::Operations
12
- end
13
- end
14
-
15
- describe "#collection" do
16
-
17
- let(:options) do
18
- { validate: true }
19
- end
20
-
21
- context "when the document is a root" do
22
-
23
- let(:operation) do
24
- klass.new(document, options)
25
- end
26
-
27
- let(:collection) do
28
- operation.collection
29
- end
30
-
31
- it "returns the root collection" do
32
- collection.name.should eq(document.collection.name)
33
- end
34
- end
35
-
36
- context "when the document is embedded" do
37
-
38
- let(:name) do
39
- document.build_name(first_name: "Syd")
40
- end
41
-
42
- let(:operation) do
43
- klass.new(name, options)
44
- end
45
-
46
- let(:collection) do
47
- operation.collection
48
- end
49
-
50
- it "returns the root collection" do
51
- collection.name.should eq(document.collection.name)
52
- end
53
- end
54
- end
55
-
56
- describe "#deletes" do
57
-
58
- context "when the child is an embeds one" do
59
-
60
- let(:child) do
61
- document.build_name(first_name: "Syd")
62
- end
63
-
64
- let(:operation) do
65
- klass.new(child)
66
- end
67
-
68
- let(:deletes) do
69
- operation.deletes
70
- end
71
-
72
- it "returns the delete atomic modifiers" do
73
- deletes.should eq(
74
- { "$unset" => { "name" => true } }
75
- )
76
- end
77
- end
78
-
79
- context "when the child is an embeds many" do
80
-
81
- let(:child) do
82
- document.addresses.build(street: "Unter den Linden")
83
- end
84
-
85
- let(:operation) do
86
- klass.new(child)
87
- end
88
-
89
- let(:deletes) do
90
- operation.deletes
91
- end
92
-
93
- it "returns the delete atomic modifiers" do
94
- deletes.should eq(
95
- { "$pull" => { "addresses" => { "_id" => "unter-den-linden" } } }
96
- )
97
- end
98
- end
99
- end
100
-
101
- describe "#inserts" do
102
-
103
- let(:child) do
104
- document.build_name(first_name: "Syd")
105
- end
106
-
107
- let(:operation) do
108
- klass.new(child)
109
- end
110
-
111
- let(:inserts) do
112
- operation.inserts
113
- end
114
-
115
- it "returns the insert atomic modifiers" do
116
- inserts.should eq(
117
- { "$set" => { "name" => { "first_name" => "Syd", "_id" => "Syd-" } } }
118
- )
119
- end
120
- end
121
-
122
- describe "#notifying_parent?" do
123
-
124
- let(:operation) do
125
- klass.new(document, options)
126
- end
127
-
128
- context "when the suppress option is true" do
129
-
130
- let(:options) do
131
- { suppress: true }
132
- end
133
-
134
- it "returns false" do
135
- operation.should_not be_notifying_parent
136
- end
137
- end
138
-
139
- context "when the suppress option is false" do
140
-
141
- let(:options) do
142
- { suppress: false }
143
- end
144
-
145
- it "returns true" do
146
- operation.should be_notifying_parent
147
- end
148
- end
149
-
150
- context "when the suppress option is nil" do
151
-
152
- let(:options) do
153
- {}
154
- end
155
-
156
- it "returns true" do
157
- operation.should be_notifying_parent
158
- end
159
- end
160
- end
161
-
162
- describe "#options" do
163
-
164
- let(:options) do
165
- {}
166
- end
167
-
168
- let(:operation) do
169
- klass.new(document, options)
170
- end
171
-
172
- it "returns the options" do
173
- operation.options.should eq(options)
174
- end
175
- end
176
-
177
- describe "#parent" do
178
-
179
- let(:child) do
180
- document.addresses.build(street: "Unter den Linden")
181
- end
182
-
183
- let(:operation) do
184
- klass.new(child)
185
- end
186
-
187
- it "returns the document's parent" do
188
- operation.parent.should eq(document)
189
- end
190
- end
191
-
192
- describe "#selector" do
193
-
194
- let(:operation) do
195
- klass.new(document)
196
- end
197
-
198
- it "returns the document's atomic selector" do
199
- operation.selector.should eq(document.atomic_selector)
200
- end
201
- end
202
-
203
- describe "#updates" do
204
-
205
- context "when there are no conflicting mods" do
206
-
207
- let(:operation) do
208
- klass.new(document)
209
- end
210
-
211
- let(:updates) do
212
- operation.updates
213
- end
214
-
215
- it "returns the updates" do
216
- updates.should eq(document.atomic_updates)
217
- end
218
- end
219
-
220
- context "when conflicting mods exist" do
221
-
222
- let!(:document) do
223
- Person.new.tap do |person|
224
- person.new_record = false
225
- person.move_changes
226
- end
227
- end
228
-
229
- let!(:child) do
230
- document.addresses.build(street: "Unter den Linden").tap do |doc|
231
- doc.new_record = false
232
- end
233
- end
234
-
235
- let!(:conflict) do
236
- document.addresses.build(street: "Freiderichstr")
237
- end
238
-
239
- let(:operation) do
240
- klass.new(document)
241
- end
242
-
243
- let!(:updates) do
244
- operation.updates
245
- end
246
-
247
- let!(:conflicts) do
248
- operation.conflicts
249
- end
250
-
251
- it "returns the updates without conflicts" do
252
- updates.should eq(
253
- {
254
- "$set" => {
255
- "addresses.0.street" => "Unter den Linden",
256
- "addresses.0._id" => "unter-den-linden"
257
- }
258
- }
259
- )
260
- end
261
-
262
- it "sets the conflicts" do
263
- conflicts.should eq(
264
- {
265
- "$pushAll" => {
266
- "addresses" => [ { "street" => "Freiderichstr", "_id" => "freiderichstr" } ]
267
- }
268
- }
269
- )
270
- end
271
- end
272
- end
273
-
274
- describe "#validating?" do
275
-
276
- let(:operation) do
277
- klass.new(document, options)
278
- end
279
-
280
- context "when validate option is true" do
281
-
282
- let(:options) do
283
- { validate: true }
284
- end
285
-
286
- it "returns true" do
287
- operation.should be_validating
288
- end
289
- end
290
-
291
- context "when validate option is false" do
292
-
293
- let(:options) do
294
- { validate: false }
295
- end
296
-
297
- it "returns false" do
298
- operation.should_not be_validating
299
- end
300
- end
301
-
302
- context "when validate option is nil" do
303
-
304
- let(:options) do
305
- {}
306
- end
307
-
308
- it "returns true" do
309
- operation.should be_validating
310
- end
311
- end
312
- end
313
- end
@@ -1,2279 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Mongoid::Persistence do
4
-
5
- describe ".create" do
6
-
7
- context "when provided an array of attributes" do
8
-
9
- context "when no block is passed" do
10
-
11
- let(:people) do
12
- Person.create([{ title: "sir" }, { title: "madam" }])
13
- end
14
-
15
- it "creates the first document" do
16
- people.first.title.should eq("sir")
17
- end
18
-
19
- it "persists the first document" do
20
- people.first.should be_persisted
21
- end
22
-
23
- it "creates the second document" do
24
- people.last.title.should eq("madam")
25
- end
26
-
27
- it "persists the second document" do
28
- people.last.should be_persisted
29
- end
30
- end
31
-
32
- context "when no block is passed" do
33
-
34
- let(:people) do
35
- Person.create([{ title: "sir" }, { title: "madam" }]) do |person|
36
- person.age = 36
37
- end
38
- end
39
-
40
- it "creates the first document" do
41
- people.first.title.should eq("sir")
42
- end
43
-
44
- it "persists the first document" do
45
- people.first.should be_persisted
46
- end
47
-
48
- it "passes the block to the first document" do
49
- people.first.age.should eq(36)
50
- end
51
-
52
- it "creates the second document" do
53
- people.last.title.should eq("madam")
54
- end
55
-
56
- it "persists the second document" do
57
- people.last.should be_persisted
58
- end
59
-
60
- it "passes the block to the second document" do
61
- people.last.age.should eq(36)
62
- end
63
- end
64
- end
65
-
66
- context "when providing attributes" do
67
-
68
- let(:person) do
69
- Person.create(title: "Sensei")
70
- end
71
-
72
- it "it saves the document" do
73
- person.should be_persisted
74
- end
75
-
76
- it "returns the document" do
77
- person.should be_a_kind_of(Person)
78
- end
79
-
80
- context "when creating an embedded document" do
81
-
82
- let(:address) do
83
- Address.create(addressable: person)
84
- end
85
-
86
- it "persists the document" do
87
- address.should be_persisted
88
- end
89
- end
90
-
91
- context "when creating an embedded document with store_as option" do
92
-
93
- let(:user) do
94
- User.create
95
- end
96
-
97
- before(:all) do
98
- User.embeds_many(
99
- :addresses,
100
- class_name: "Address",
101
- store_as: "user_adresses",
102
- validate: false
103
- )
104
- Address.embedded_in :user
105
- end
106
-
107
- before do
108
- user.addresses.create!(city: "nantes")
109
- end
110
-
111
- let(:document) do
112
- user.collection.find(_id: user.id).first
113
- end
114
-
115
- it "should not persist in address key on User document" do
116
- document.keys.should_not include("addresses")
117
- end
118
-
119
- it "should persist on user_addesses key on User document" do
120
- document.keys.should include("user_adresses")
121
- end
122
- end
123
- end
124
-
125
- context "when passing in a block" do
126
-
127
- let(:person) do
128
- Person.create do |peep|
129
- peep.ssn = "666-66-6666"
130
- end
131
- end
132
-
133
- it "sets the attributes" do
134
- person.ssn.should eq("666-66-6666")
135
- end
136
-
137
- it "persists the document" do
138
- person.should be_persisted
139
- end
140
- end
141
-
142
- context "when mass assignment role is indicated" do
143
-
144
- context "when attributes assigned from default role" do
145
-
146
- let(:item) do
147
- Item.create(
148
- title: "Some Title",
149
- is_rss: true,
150
- user_login: "SomeLogin"
151
- )
152
- end
153
-
154
- it "sets the field for the default role" do
155
- item.is_rss.should be_true
156
- end
157
-
158
- it "does not set the field for non default role title" do
159
- item.title.should be_nil
160
- end
161
-
162
- it "does not set the field for non default role user login" do
163
- item.user_login.should be_nil
164
- end
165
- end
166
-
167
- context "when attributes assigned from parser role" do
168
-
169
- let(:item) do
170
- Item.create(
171
- { title: "Some Title",
172
- is_rss: true,
173
- user_login: "SomeLogin" }, as: :parser
174
- )
175
- end
176
-
177
- it "sets the user login field for parser role" do
178
- item.user_login.should eq("SomeLogin")
179
- end
180
-
181
- it "sets the is rss field for parse role" do
182
- item.is_rss.should be_false
183
- end
184
-
185
- it "does not set the title field" do
186
- item.title.should be_nil
187
- end
188
- end
189
-
190
- context "when attributes assigned without protection" do
191
-
192
- let(:item) do
193
- Item.create(
194
- { title: "Some Title",
195
- is_rss: true,
196
- user_login: "SomeLogin"
197
- }, without_protection: true
198
- )
199
- end
200
-
201
- it "sets the title attribute" do
202
- item.title.should eq("Some Title")
203
- end
204
-
205
- it "sets the user login attribute" do
206
- item.user_login.should eq("SomeLogin")
207
- end
208
-
209
- it "sets the rss attribute" do
210
- item.is_rss.should be_true
211
- end
212
- end
213
- end
214
- end
215
-
216
- describe ".create!" do
217
-
218
- context "when provided an array of attributes" do
219
-
220
- context "when no block is passed" do
221
-
222
- let(:people) do
223
- Person.create!([{ title: "sir" }, { title: "madam" }])
224
- end
225
-
226
- it "creates the first document" do
227
- people.first.title.should eq("sir")
228
- end
229
-
230
- it "persists the first document" do
231
- people.first.should be_persisted
232
- end
233
-
234
- it "creates the second document" do
235
- people.last.title.should eq("madam")
236
- end
237
-
238
- it "persists the second document" do
239
- people.last.should be_persisted
240
- end
241
- end
242
-
243
- context "when no block is passed" do
244
-
245
- let(:people) do
246
- Person.create!([{ title: "sir" }, { title: "madam" }]) do |person|
247
- person.age = 36
248
- end
249
- end
250
-
251
- it "creates the first document" do
252
- people.first.title.should eq("sir")
253
- end
254
-
255
- it "persists the first document" do
256
- people.first.should be_persisted
257
- end
258
-
259
- it "passes the block to the first document" do
260
- people.first.age.should eq(36)
261
- end
262
-
263
- it "creates the second document" do
264
- people.last.title.should eq("madam")
265
- end
266
-
267
- it "persists the second document" do
268
- people.last.should be_persisted
269
- end
270
-
271
- it "passes the block to the second document" do
272
- people.last.age.should eq(36)
273
- end
274
- end
275
- end
276
-
277
- context "inserting with a field that is not unique" do
278
-
279
- context "when a unique index exists" do
280
-
281
- before do
282
- Person.create_indexes
283
- end
284
-
285
- it "raises an error" do
286
- expect {
287
- 4.times { Person.with(safe: true).create!(ssn: "555-55-1029") }
288
- }.to raise_error
289
- end
290
- end
291
- end
292
-
293
- context "when passing in a block" do
294
-
295
- let(:person) do
296
- Person.create! do |peep|
297
- peep.ssn = "666-66-6666"
298
- end
299
- end
300
-
301
- it "sets the attributes" do
302
- person.ssn.should eq("666-66-6666")
303
- end
304
-
305
- it "persists the document" do
306
- person.should be_persisted
307
- end
308
- end
309
-
310
- context "when setting the composite key" do
311
-
312
- let(:account) do
313
- Account.create!(name: "Hello")
314
- end
315
-
316
- it "saves the document" do
317
- account.should be_persisted
318
- end
319
- end
320
-
321
- context "when a callback returns false" do
322
-
323
- it "raises a callback error" do
324
- expect { Oscar.create! }.to raise_error(Mongoid::Errors::Callback)
325
- end
326
- end
327
-
328
- context "when mass assignment role is indicated" do
329
-
330
- context "when attributes assigned from default role" do
331
-
332
- let(:item) do
333
- Item.create!(
334
- title: "Some Title",
335
- is_rss: true,
336
- user_login: "SomeLogin"
337
- )
338
- end
339
-
340
- it "sets the field for the default role" do
341
- item.is_rss.should be_true
342
- end
343
-
344
- it "does not set the field for non default role title" do
345
- item.title.should be_nil
346
- end
347
-
348
- it "does not set the field for non default role user login" do
349
- item.user_login.should be_nil
350
- end
351
- end
352
-
353
- context "when attributes assigned from parser role" do
354
-
355
- let(:item) do
356
- Item.create!(
357
- { title: "Some Title",
358
- is_rss: true,
359
- user_login: "SomeLogin" }, as: :parser
360
- )
361
- end
362
-
363
- it "sets the user login field for parser role" do
364
- item.user_login.should eq("SomeLogin")
365
- end
366
-
367
- it "sets the is rss field for parse role" do
368
- item.is_rss.should be_false
369
- end
370
-
371
- it "does not set the title field" do
372
- item.title.should be_nil
373
- end
374
- end
375
-
376
- context "when attributes assigned without protection" do
377
-
378
- let(:item) do
379
- Item.create!(
380
- { title: "Some Title",
381
- is_rss: true,
382
- user_login: "SomeLogin"
383
- }, without_protection: true
384
- )
385
- end
386
-
387
- it "sets the title attribute" do
388
- item.title.should eq("Some Title")
389
- end
390
-
391
- it "sets the user login attribute" do
392
- item.user_login.should eq("SomeLogin")
393
- end
394
-
395
- it "sets the rss attribute" do
396
- item.is_rss.should be_true
397
- end
398
- end
399
- end
400
- end
401
-
402
- [ :delete, :destroy ].each do |method|
403
-
404
- describe "##{method}" do
405
-
406
- let(:person) do
407
- Person.create
408
- end
409
-
410
- context "when removing a root document" do
411
-
412
- let!(:deleted) do
413
- person.send(method)
414
- end
415
-
416
- it "deletes the document from the collection" do
417
- expect {
418
- Person.find(person.id)
419
- }.to raise_error
420
- end
421
-
422
- it "returns true" do
423
- deleted.should be_true
424
- end
425
-
426
- it "resets the flagged for destroy flag" do
427
- person.should_not be_flagged_for_destroy
428
- end
429
- end
430
-
431
- context "when removing an embedded document" do
432
-
433
- let(:address) do
434
- person.addresses.build(street: "Bond Street")
435
- end
436
-
437
- context "when the document is not yet saved" do
438
-
439
- before do
440
- address.send(method)
441
- end
442
-
443
- it "removes the document from the parent" do
444
- person.addresses.should be_empty
445
- end
446
-
447
- it "removes the attributes from the parent" do
448
- person.raw_attributes["addresses"].should be_nil
449
- end
450
-
451
- it "resets the flagged for destroy flag" do
452
- address.should_not be_flagged_for_destroy
453
- end
454
- end
455
-
456
- context "when the document has been saved" do
457
-
458
- before do
459
- address.save
460
- address.send(method)
461
- end
462
-
463
- let(:from_db) do
464
- Person.find(person.id)
465
- end
466
-
467
- it "removes the object from the parent and database" do
468
- from_db.addresses.should be_empty
469
- end
470
- end
471
- end
472
-
473
- context "when removing deeply embedded documents" do
474
-
475
- context "when the document has been saved" do
476
-
477
- let(:address) do
478
- person.addresses.create(street: "Bond Street")
479
- end
480
-
481
- let(:location) do
482
- address.locations.create(name: "Home")
483
- end
484
-
485
- let(:from_db) do
486
- Person.find(person.id)
487
- end
488
-
489
- before do
490
- location.send(method)
491
- end
492
-
493
- it "removes the object from the parent and database" do
494
- from_db.addresses.first.locations.should be_empty
495
- end
496
-
497
- it "resets the flagged for destroy flag" do
498
- location.should_not be_flagged_for_destroy
499
- end
500
- end
501
- end
502
- end
503
- end
504
-
505
- describe "#save" do
506
-
507
- let(:person) do
508
- Person.create
509
- end
510
-
511
- context "when skipping validation" do
512
-
513
- context "when no relations are involved" do
514
-
515
- let(:account) do
516
- Account.new
517
- end
518
-
519
- let!(:saved) do
520
- account.save(validate: false)
521
- end
522
-
523
- it "returns true" do
524
- saved.should be_true
525
- end
526
-
527
- it "saves the document" do
528
- account.should be_persisted
529
- end
530
-
531
- it "does not add any validation errors" do
532
- account.errors.should be_empty
533
- end
534
- end
535
-
536
- context "when saving document that is a belongs to child" do
537
-
538
- let(:account) do
539
- Account.create
540
- end
541
-
542
- let(:alert) do
543
- Alert.new(account: account)
544
- end
545
-
546
- context "when validating presence of the parent" do
547
-
548
- before do
549
- Alert.validates(:message, :account, presence: true)
550
- end
551
-
552
- after do
553
- Alert.reset_callbacks(:validate)
554
- end
555
-
556
- context "when the parent validates associated on the child" do
557
-
558
- before do
559
- alert.save(validate: false)
560
- end
561
-
562
- it "clears any errors off the document" do
563
- alert.errors.should be_empty
564
- end
565
-
566
- context "when the document is not new" do
567
-
568
- before do
569
- alert.save(validate: false)
570
- end
571
-
572
- it "clears any errors off the document" do
573
- alert.errors.should be_empty
574
- end
575
- end
576
- end
577
- end
578
- end
579
- end
580
-
581
- context "when the document has been instantiated with limited fields" do
582
-
583
- before do
584
- person.age = 20
585
- person.save
586
- end
587
-
588
- context "when a default is excluded" do
589
-
590
- let(:limited) do
591
- Person.only(:_id).find(person.id)
592
- end
593
-
594
- it "does not flag the excluded fields as dirty" do
595
- limited.changes.should be_empty
596
- end
597
-
598
- it "does not overwrite with the default" do
599
- limited.save
600
- limited.reload.age.should eq(20)
601
- end
602
- end
603
-
604
- context "when iterating over the documents" do
605
-
606
- let(:limited) do
607
- Person.only(:_id)
608
- end
609
-
610
- it "does not flag any changes" do
611
- limited.each do |person|
612
- person.changes.should be_empty
613
- end
614
- end
615
- end
616
- end
617
-
618
- context "when validation passes" do
619
-
620
- it "returns true" do
621
- person.save.should be_true
622
- end
623
- end
624
-
625
- context "when validation fails" do
626
-
627
- let(:address) do
628
- person.addresses.create(city: "London")
629
- end
630
-
631
- before do
632
- address.save
633
- end
634
-
635
- it "has the appropriate errors" do
636
- address.errors[:street].should eq(["can't be blank"])
637
- end
638
- end
639
-
640
- context "when modifying the entire hierarchy" do
641
-
642
- context "when performing modification and insert ops" do
643
-
644
- let(:person) do
645
- Person.create(title: "Blah")
646
- end
647
-
648
- let!(:address) do
649
- person.addresses.build(street: "Bond St")
650
- end
651
-
652
- let!(:name) do
653
- person.create_name(first_name: "Tony")
654
- end
655
-
656
- let(:from_db) do
657
- Person.find(person.id)
658
- end
659
-
660
- before do
661
- person.title = "King"
662
- name.first_name = "Ryan"
663
- end
664
-
665
- it "persists with proper set and push modifiers" do
666
- person.atomic_updates.should eq({
667
- "$set" => {
668
- "title" => "King",
669
- "name.first_name" => "Ryan"
670
- },
671
- "$pushAll"=> {
672
- "addresses" => [ { "_id" => address.id, "street" => "Bond St" } ]
673
- }
674
- })
675
- end
676
-
677
- context "when saving the document" do
678
-
679
- it "saves the root document" do
680
- person.title.should eq("King")
681
- end
682
-
683
- it "saves embedded many relations" do
684
- person.addresses.first.street.should eq("Bond St")
685
- end
686
-
687
- it "saves embedded one relations" do
688
- person.name.first_name.should eq("Ryan")
689
- end
690
- end
691
- end
692
-
693
- context "when combining modifications and pushes" do
694
-
695
- let!(:location) do
696
- Location.new(name: 'Work')
697
- end
698
-
699
- let!(:address) do
700
- Address.new(
701
- number: 101,
702
- street: 'South St',
703
- locations: [ location ]
704
- )
705
- end
706
-
707
- let!(:person) do
708
- Person.create(
709
- title: "Blah",
710
- addresses: [ address ]
711
- )
712
- end
713
-
714
- let(:from_db) do
715
- Person.find(person.id)
716
- end
717
-
718
- before do
719
- address.number = 102
720
- person.addresses << Address.new(street: "North Ave")
721
- person.save
722
- end
723
-
724
- it "saves modifications to existing embedded docs" do
725
- from_db.addresses[0].number.should eq(102)
726
- end
727
-
728
- it "saves modifications to new embedded docs" do
729
- from_db.addresses[1].street.should eq('North Ave')
730
- end
731
-
732
- it "saves modifications to deeply embedded docs" do
733
- from_db.addresses[0].locations.first.name.should eq('Work')
734
- end
735
- end
736
-
737
- context "when removing elements without using delete or destroy" do
738
-
739
- let!(:person) do
740
- Person.create!(title: "Blah")
741
- end
742
-
743
- let(:from_db) do
744
- Person.find(person.id)
745
- end
746
-
747
- before do
748
- person.create_name(first_name: "Tony")
749
- person.name = nil
750
- person.save
751
- end
752
-
753
- it "saves the hierarchy" do
754
- person.name.should be_nil
755
- end
756
- end
757
- end
758
- end
759
-
760
- describe "save!" do
761
-
762
- context "inserting with a field that is not unique" do
763
-
764
- context "when a unique index exists" do
765
-
766
- let(:person) do
767
- Person.new(ssn: "555-55-9999")
768
- end
769
-
770
- before do
771
- Person.create_indexes
772
- Person.create!(ssn: "555-55-9999")
773
- end
774
-
775
- it "raises an error" do
776
- expect { person.with(safe: true).save! }.to raise_error
777
- end
778
- end
779
- end
780
-
781
- context "with a validation error" do
782
-
783
- let(:person) do
784
- Person.new
785
- end
786
-
787
- let!(:service) do
788
- Service.new(person: person, sid: "a")
789
- end
790
-
791
- it "raises an error with multiple save attempts" do
792
- expect { subject.save! }.to raise_error
793
- expect { subject.save! }.to raise_error
794
- end
795
- end
796
-
797
- context "when a callback returns false" do
798
-
799
- let(:oscar) do
800
- Oscar.new
801
- end
802
-
803
- it "raises a callback error" do
804
- expect { oscar.save! }.to raise_error(Mongoid::Errors::Callback)
805
- end
806
- end
807
-
808
- context "when a callback destroys the document" do
809
-
810
- let(:oscar) do
811
- Oscar.new(:destroy_after_save => true)
812
- end
813
-
814
- before do
815
- oscar.save!
816
- end
817
-
818
- it "flags the document as destroyed" do
819
- oscar.should be_destroyed
820
- end
821
- end
822
- end
823
-
824
- describe "#touch" do
825
-
826
- context "when the document is embedded" do
827
-
828
- let(:band) do
829
- Band.create(name: "Placebo")
830
- end
831
-
832
- let(:label) do
833
- band.create_label(name: "Mute", updated_at: 10.days.ago)
834
- end
835
-
836
- before do
837
- label.touch
838
- end
839
-
840
- it "updates the updated_at timestamp" do
841
- label.updated_at.should be_within(1).of(Time.now)
842
- end
843
-
844
- it "persists the changes" do
845
- label.reload.updated_at.should be_within(1).of(Time.now)
846
- end
847
- end
848
-
849
- context "when no relations have touch options" do
850
-
851
- context "when no updated at is defined" do
852
-
853
- let(:person) do
854
- Person.create
855
- end
856
-
857
- context "when no attribute is provided" do
858
-
859
- let!(:touched) do
860
- person.touch
861
- end
862
-
863
- it "returns true" do
864
- touched.should be_true
865
- end
866
-
867
- it "does not set the updated at field" do
868
- person[:updated_at].should be_nil
869
- end
870
- end
871
-
872
- context "when an attribute is provided" do
873
-
874
- let!(:touched) do
875
- person.touch(:lunch_time)
876
- end
877
-
878
- it "sets the attribute to the current time" do
879
- person.lunch_time.should be_within(5).of(Time.now)
880
- end
881
-
882
- it "persists the change" do
883
- person.reload.lunch_time.should be_within(5).of(Time.now)
884
- end
885
-
886
- it "returns true" do
887
- touched.should be_true
888
- end
889
- end
890
-
891
- context "when an attribute alias is provided" do
892
-
893
- let!(:touched) do
894
- person.touch(:aliased_timestamp)
895
- end
896
-
897
- it "sets the attribute to the current time" do
898
- person.aliased_timestamp.should be_within(5).of(Time.now)
899
- end
900
-
901
- it "persists the change" do
902
- person.reload.aliased_timestamp.should be_within(5).of(Time.now)
903
- end
904
-
905
- it "returns true" do
906
- touched.should be_true
907
- end
908
- end
909
- end
910
-
911
- context "when an updated at is defined" do
912
-
913
- let!(:agent) do
914
- Agent.create(updated_at: 2.days.ago)
915
- end
916
-
917
- context "when no attribute is provided" do
918
-
919
- let!(:touched) do
920
- agent.touch
921
- end
922
-
923
- it "sets the updated at to the current time" do
924
- agent.updated_at.should be_within(5).of(Time.now)
925
- end
926
-
927
- it "persists the change" do
928
- agent.reload.updated_at.should be_within(5).of(Time.now)
929
- end
930
-
931
- it "returns true" do
932
- touched.should be_true
933
- end
934
-
935
- it "keeps changes for next callback" do
936
- agent.changes.should_not be_empty
937
- end
938
- end
939
-
940
- context "when an attribute is provided" do
941
-
942
- let!(:touched) do
943
- agent.touch(:dob)
944
- end
945
-
946
- it "sets the updated at to the current time" do
947
- agent.updated_at.should be_within(5).of(Time.now)
948
- end
949
-
950
- it "sets the attribute to the current time" do
951
- agent.dob.should be_within(5).of(Time.now)
952
- end
953
-
954
- it "sets both attributes to the exact same time" do
955
- agent.updated_at.should eq(agent.dob)
956
- end
957
-
958
- it "persists the updated at change" do
959
- agent.reload.updated_at.should be_within(5).of(Time.now)
960
- end
961
-
962
- it "persists the attribute change" do
963
- agent.reload.dob.should be_within(5).of(Time.now)
964
- end
965
-
966
- it "returns true" do
967
- touched.should be_true
968
- end
969
-
970
- it "keeps changes for next callback" do
971
- agent.changes.should_not be_empty
972
- end
973
- end
974
- end
975
-
976
- context "when record is new" do
977
-
978
- let(:agent) do
979
- Agent.new(updated_at: 2.days.ago)
980
- end
981
-
982
- context "when no attribute is provided" do
983
-
984
- let!(:touched) do
985
- agent.touch
986
- end
987
-
988
- it "returns false" do
989
- touched.should be_false
990
- end
991
- end
992
-
993
- context "when an attribute is provided" do
994
-
995
- let!(:touched) do
996
- agent.touch(:dob)
997
- end
998
-
999
- it "returns false" do
1000
- touched.should be_false
1001
- end
1002
- end
1003
- end
1004
-
1005
- context "when creating the child" do
1006
-
1007
- let(:time) do
1008
- Time.utc(2012, 4, 3, 12)
1009
- end
1010
-
1011
- let(:jar) do
1012
- Jar.new(_id: 1, updated_at: time).tap do |jar|
1013
- jar.save!
1014
- end
1015
- end
1016
-
1017
- let!(:cookie) do
1018
- jar.cookies.create!(updated_at: time)
1019
- end
1020
-
1021
- it "does not touch the parent" do
1022
- jar.updated_at.should eq(time)
1023
- end
1024
- end
1025
- end
1026
-
1027
- context "when relations have touch options" do
1028
-
1029
- context "when the relation is nil" do
1030
-
1031
- let!(:agent) do
1032
- Agent.create
1033
- end
1034
-
1035
- context "when the relation autobuilds" do
1036
-
1037
- let!(:touched) do
1038
- agent.touch
1039
- end
1040
-
1041
- it "does nothing to the relation" do
1042
- agent.instance_variable_get(:@agency).should be_nil
1043
- end
1044
- end
1045
- end
1046
-
1047
- context "when the relation is not nil" do
1048
-
1049
- let!(:agent) do
1050
- Agent.create
1051
- end
1052
-
1053
- let!(:agency) do
1054
- agent.create_agency.tap do |a|
1055
- a.unset(:updated_at)
1056
- end
1057
- end
1058
-
1059
- let!(:touched) do
1060
- agent.touch
1061
- end
1062
-
1063
- it "sets the parent updated at to the current time" do
1064
- agency.updated_at.should be_within(5).of(Time.now)
1065
- end
1066
-
1067
- it "persists the change" do
1068
- agency.reload.updated_at.should be_within(5).of(Time.now)
1069
- end
1070
- end
1071
-
1072
- context "when creating the child" do
1073
-
1074
- let!(:agency) do
1075
- Agency.create
1076
- end
1077
-
1078
- let!(:updated) do
1079
- agency.updated_at
1080
- end
1081
-
1082
- let!(:agent) do
1083
- agency.agents.create
1084
- end
1085
-
1086
- it "updates the parent's updated at" do
1087
- agency.updated_at.should_not eq(updated)
1088
- end
1089
- end
1090
-
1091
- context "when destroying the child" do
1092
-
1093
- let!(:agency) do
1094
- Agency.create
1095
- end
1096
-
1097
- let!(:agent) do
1098
- agency.agents.create
1099
- end
1100
-
1101
- let!(:updated) do
1102
- agency.updated_at
1103
- end
1104
-
1105
- before do
1106
- agent.destroy
1107
- end
1108
-
1109
- it "updates the parent's updated at" do
1110
- agency.updated_at.should_not eq(updated)
1111
- end
1112
- end
1113
- end
1114
- end
1115
-
1116
- describe "#update_attribute" do
1117
-
1118
- context "when the field is aliased" do
1119
-
1120
- let(:person) do
1121
- Person.create
1122
- end
1123
-
1124
- context "when setting via the field name" do
1125
-
1126
- before do
1127
- person.update_attribute(:t, "testing")
1128
- end
1129
-
1130
- it "updates the field" do
1131
- person.t.should eq("testing")
1132
- end
1133
-
1134
- it "persists the changes" do
1135
- person.reload.t.should eq("testing")
1136
- end
1137
- end
1138
-
1139
- context "when setting via the field alias" do
1140
-
1141
- before do
1142
- person.update_attribute(:test, "testing")
1143
- end
1144
-
1145
- it "updates the field" do
1146
- person.t.should eq("testing")
1147
- end
1148
-
1149
- it "persists the changes" do
1150
- person.reload.t.should eq("testing")
1151
- end
1152
- end
1153
- end
1154
-
1155
- context "when setting an array field" do
1156
-
1157
- let(:person) do
1158
- Person.create(aliases: [])
1159
- end
1160
-
1161
- before do
1162
- person.update_attribute(:aliases, person.aliases << "Bond")
1163
- end
1164
-
1165
- it "sets the new value in the document" do
1166
- person.aliases.should eq([ "Bond" ])
1167
- end
1168
-
1169
- it "persists the changes" do
1170
- person.reload.aliases.should eq([ "Bond" ])
1171
- end
1172
- end
1173
-
1174
- context "when setting a boolean field" do
1175
-
1176
- context "when the field is true" do
1177
-
1178
- let(:person) do
1179
- Person.new(terms: true)
1180
- end
1181
-
1182
- context "when setting to false" do
1183
-
1184
- before do
1185
- person.update_attribute(:terms, false)
1186
- end
1187
-
1188
- it "persists the document" do
1189
- person.should be_persisted
1190
- end
1191
-
1192
- it "changes the attribute value" do
1193
- person.terms.should be_false
1194
- end
1195
-
1196
- it "persists the changes" do
1197
- person.reload.terms.should be_false
1198
- end
1199
- end
1200
- end
1201
- end
1202
-
1203
- context "when provided a symbol attribute name" do
1204
-
1205
- let(:post) do
1206
- Post.new
1207
- end
1208
-
1209
- context "when the document is valid" do
1210
-
1211
- before do
1212
- post.update_attribute(:title, "Testing")
1213
- end
1214
-
1215
- it "sets the attribute" do
1216
- post.title.should eq("Testing")
1217
- end
1218
-
1219
- it "saves the document" do
1220
- post.should be_persisted
1221
- end
1222
- end
1223
-
1224
- context "when updating to the same value" do
1225
-
1226
- before do
1227
- post.update_attribute(:title, "Testing")
1228
- end
1229
-
1230
- it "returns true" do
1231
- post.update_attribute(:title, "Testing").should be_true
1232
- end
1233
- end
1234
-
1235
- context "when the document is invalid" do
1236
-
1237
- before do
1238
- post.update_attribute(:title, "$invalid")
1239
- end
1240
-
1241
- it "sets the attribute" do
1242
- post.title.should eq("$invalid")
1243
- end
1244
-
1245
- it "saves the document" do
1246
- post.should be_persisted
1247
- end
1248
- end
1249
-
1250
- context "when the document has been destroyed" do
1251
-
1252
- before do
1253
- post.delete
1254
- end
1255
-
1256
- it "raises an error" do
1257
- expect {
1258
- post.update_attribute(:title, "something")
1259
- }.to raise_error
1260
- end
1261
- end
1262
- end
1263
-
1264
- context "when provided a string attribute name" do
1265
-
1266
- let(:post) do
1267
- Post.new
1268
- end
1269
-
1270
- context "when the document is valid" do
1271
-
1272
- before do
1273
- post.update_attribute("title", "Testing")
1274
- end
1275
-
1276
- it "sets the attribute" do
1277
- post.title.should eq("Testing")
1278
- end
1279
-
1280
- it "saves the document" do
1281
- post.should be_persisted
1282
- end
1283
- end
1284
-
1285
- context "when the document is invalid" do
1286
-
1287
- before do
1288
- post.update_attribute("title", "$invalid")
1289
- end
1290
-
1291
- it "sets the attribute" do
1292
- post.title.should eq("$invalid")
1293
- end
1294
-
1295
- it "saves the document" do
1296
- post.should be_persisted
1297
- end
1298
- end
1299
- end
1300
-
1301
- context "when persisting a localized field" do
1302
-
1303
- let!(:product) do
1304
- Product.create(description: "The bomb")
1305
- end
1306
-
1307
- before do
1308
- ::I18n.locale = :de
1309
- product.update_attribute(:description, "Die Bombe")
1310
- end
1311
-
1312
- after do
1313
- ::I18n.locale = :en
1314
- end
1315
-
1316
- let(:attributes) do
1317
- product.attributes["description"]
1318
- end
1319
-
1320
- it "persists the en locale" do
1321
- attributes["en"].should eq("The bomb")
1322
- end
1323
-
1324
- it "persists the de locale" do
1325
- attributes["de"].should eq("Die Bombe")
1326
- end
1327
- end
1328
-
1329
- context "when updating a deeply embedded document" do
1330
-
1331
- let!(:person) do
1332
- Person.create
1333
- end
1334
-
1335
- let!(:address) do
1336
- person.addresses.create(street: "Winterfeldtstr")
1337
- end
1338
-
1339
- let!(:location) do
1340
- address.locations.create(name: "work")
1341
- end
1342
-
1343
- let(:from_db) do
1344
- Person.last.addresses.last.locations.last
1345
- end
1346
-
1347
- before do
1348
- from_db.update_attribute(:name, "home")
1349
- end
1350
-
1351
- it "updates the attribute" do
1352
- from_db.name.should eq("home")
1353
- end
1354
-
1355
- it "persists the changes" do
1356
- from_db.reload.name.should eq("home")
1357
- end
1358
- end
1359
- end
1360
-
1361
- describe "#update_attributes" do
1362
-
1363
- context "when providing options" do
1364
-
1365
- let(:person) do
1366
- Person.create
1367
- end
1368
-
1369
- let(:params) do
1370
- [{ pets: false }, { as: :default }]
1371
- end
1372
-
1373
- it "accepts the additional parameter" do
1374
- expect {
1375
- person.update_attributes(*params)
1376
- }.to_not raise_error(ArgumentError)
1377
- end
1378
-
1379
- it "calls assign_attributes" do
1380
- person.should_receive(:assign_attributes).with(*params)
1381
- person.update_attributes(*params)
1382
- end
1383
-
1384
- end
1385
-
1386
- context "when saving with a hash field with invalid keys" do
1387
-
1388
- let(:person) do
1389
- Person.create
1390
- end
1391
-
1392
- it "raises an error" do
1393
- expect {
1394
- person.with(safe: true).update_attributes(map: { "bad.key" => "value" })
1395
- }.to raise_error(Moped::Errors::OperationFailure)
1396
- end
1397
- end
1398
-
1399
- context "when validation passes" do
1400
-
1401
- let(:person) do
1402
- Person.create
1403
- end
1404
-
1405
- let!(:saved) do
1406
- person.update_attributes(pets: false)
1407
- end
1408
-
1409
- let(:from_db) do
1410
- Person.find(person.id)
1411
- end
1412
-
1413
- it "returns true" do
1414
- saved.should be_true
1415
- end
1416
-
1417
- it "saves the attributes" do
1418
- from_db.pets.should be_false
1419
- end
1420
- end
1421
-
1422
- context "when the document has been destroyed" do
1423
-
1424
- let!(:person) do
1425
- Person.create
1426
- end
1427
-
1428
- before do
1429
- person.delete
1430
- end
1431
-
1432
- it "raises an error" do
1433
- expect {
1434
- person.update_attributes(title: "something")
1435
- }.to raise_error
1436
- end
1437
- end
1438
-
1439
- context "when updating through a one-to-one relation" do
1440
-
1441
- let(:person) do
1442
- Person.create!
1443
- end
1444
-
1445
- let(:game) do
1446
- Game.create(person: person)
1447
- end
1448
-
1449
- before do
1450
- person.update_attributes!(ssn: "444-44-4444")
1451
- game.person.update_attributes!(ssn: "555-66-7777")
1452
- end
1453
-
1454
- let(:from_db) do
1455
- Person.find(person.id)
1456
- end
1457
-
1458
- it "saves the attributes" do
1459
- person.ssn.should eq("555-66-7777")
1460
- end
1461
- end
1462
-
1463
- context "on a new record" do
1464
-
1465
- let(:person) do
1466
- Person.new
1467
- end
1468
-
1469
- before do
1470
- person.update_attributes(pets: false, title: nil)
1471
- end
1472
-
1473
- it "saves the new record" do
1474
- Person.find(person.id).should_not be_nil
1475
- end
1476
- end
1477
-
1478
- context "when passing in a relation" do
1479
-
1480
- context "when providing an embedded child" do
1481
-
1482
- let!(:person) do
1483
- Person.create
1484
- end
1485
-
1486
- let!(:name) do
1487
- person.create_name(first_name: "test", last_name: "user")
1488
- end
1489
-
1490
- let(:new_name) do
1491
- Name.new(first_name: "Rupert", last_name: "Parkes")
1492
- end
1493
-
1494
- before do
1495
- person.update_attributes(name: new_name)
1496
- end
1497
-
1498
- it "updates the embedded document" do
1499
- person.name.should eq(new_name)
1500
- end
1501
-
1502
- it "persists the changes" do
1503
- person.reload.name.should eq(new_name)
1504
- end
1505
- end
1506
-
1507
- context "when providing a parent to a referenced in" do
1508
-
1509
- let!(:person) do
1510
- Person.create
1511
- end
1512
-
1513
- let!(:post) do
1514
- Post.create(title: "Testing")
1515
- end
1516
-
1517
- context "when the relation has not yet been touched" do
1518
-
1519
- before do
1520
- post.update_attributes(person: person)
1521
- end
1522
-
1523
- it "sets the instance of the relation" do
1524
- person.posts.should eq([ post ])
1525
- end
1526
-
1527
- it "sets properly through method_missing" do
1528
- person.posts.to_a.should eq([ post ])
1529
- end
1530
-
1531
- it "persists the reference" do
1532
- person.posts(true).should eq([ post ])
1533
- end
1534
- end
1535
-
1536
- context "when the relation has been touched" do
1537
-
1538
- before do
1539
- person.posts
1540
- post.update_attributes(person: person)
1541
- end
1542
-
1543
- it "sets the instance of the relation" do
1544
- person.posts.should eq([ post ])
1545
- end
1546
-
1547
- it "sets properly through method_missing" do
1548
- person.posts.to_a.should eq([ post ])
1549
- end
1550
-
1551
- it "persists the reference" do
1552
- person.posts(true).should eq([ post ])
1553
- end
1554
- end
1555
- end
1556
- end
1557
-
1558
- context "when in a deeply nested hierarchy" do
1559
-
1560
- let!(:person) do
1561
- Person.new(title: "The Boss")
1562
- end
1563
-
1564
- let!(:phone_number) do
1565
- Phone.new(number: "123-456-7890")
1566
- end
1567
-
1568
- let!(:country_code) do
1569
- CountryCode.new(code: 1)
1570
- end
1571
-
1572
- before do
1573
- phone_number.country_code = country_code
1574
- person.phone_numbers << phone_number
1575
- person.save
1576
- end
1577
-
1578
- it "sets the first level document" do
1579
- person.phone_numbers.first.should eq(phone_number)
1580
- end
1581
-
1582
- it "sets the second level document" do
1583
- person.phone_numbers.first.country_code.should eq(country_code)
1584
- end
1585
-
1586
- context "when updating the first level document" do
1587
-
1588
- let(:phone) do
1589
- person.phone_numbers.first
1590
- end
1591
-
1592
- before do
1593
- phone.number = "098-765-4321"
1594
- phone.update_attributes(number: "098-765-4321")
1595
- end
1596
-
1597
- it "sets the new attributes" do
1598
- phone.number.should eq("098-765-4321")
1599
- end
1600
-
1601
- context "when reloading the root" do
1602
-
1603
- let(:reloaded) do
1604
- person.reload
1605
- end
1606
-
1607
- it "saves the new attributes" do
1608
- reloaded.phone_numbers.first.number.should eq("098-765-4321")
1609
- end
1610
- end
1611
- end
1612
- end
1613
- end
1614
-
1615
- describe "#update_attributes!" do
1616
-
1617
- context "when providing options" do
1618
-
1619
- let(:person) do
1620
- Person.create
1621
- end
1622
-
1623
- let(:params) do
1624
- [{ pets: false }, { as: :default }]
1625
- end
1626
-
1627
- it "accepts the additional parameter" do
1628
- expect {
1629
- person.update_attributes!(*params)
1630
- }.to_not raise_error(ArgumentError)
1631
- end
1632
-
1633
- it "calls assign_attributes" do
1634
- person.should_receive(:assign_attributes).with(*params)
1635
- person.update_attributes!(*params)
1636
- end
1637
-
1638
- end
1639
-
1640
- context "when a callback returns false" do
1641
-
1642
- let(:oscar) do
1643
- Oscar.new
1644
- end
1645
-
1646
- it "raises a callback error" do
1647
- expect {
1648
- oscar.update_attributes!(title: "The Grouch")
1649
- }.to raise_error(Mongoid::Errors::Callback)
1650
- end
1651
- end
1652
- end
1653
-
1654
- describe "#upsert" do
1655
-
1656
- context "when the document validates on upsert" do
1657
-
1658
- let(:account) do
1659
- Account.new(name: "testing")
1660
- end
1661
-
1662
- context "when the document is not valid in the upsert context" do
1663
-
1664
- before do
1665
- account.upsert
1666
- end
1667
-
1668
- it "adds the validation errors" do
1669
- account.errors[:nickname].should_not be_empty
1670
- end
1671
-
1672
- it "does not upsert the document" do
1673
- account.should be_a_new_record
1674
- end
1675
- end
1676
- end
1677
-
1678
- context "when the document is new" do
1679
-
1680
- let!(:existing) do
1681
- Band.create(name: "Photek")
1682
- end
1683
-
1684
- context "when a matching document exists in the db" do
1685
-
1686
- let(:updated) do
1687
- Band.new(name: "Tool") do |band|
1688
- band.id = existing.id
1689
- end
1690
- end
1691
-
1692
- before do
1693
- updated.with(safe: true).upsert
1694
- end
1695
-
1696
- it "updates the existing document" do
1697
- existing.reload.name.should eq("Tool")
1698
- end
1699
- end
1700
-
1701
- context "when no matching document exists in the db" do
1702
-
1703
- let(:insert) do
1704
- Band.new(name: "Tool")
1705
- end
1706
-
1707
- before do
1708
- insert.with(safe: true).upsert
1709
- end
1710
-
1711
- it "inserts a new document" do
1712
- insert.reload.should eq(insert)
1713
- end
1714
-
1715
- it "does not modify any fields" do
1716
- insert.reload.name.should eq("Tool")
1717
- end
1718
-
1719
- it "sets the document as persisted" do
1720
- insert.should be_persisted
1721
- end
1722
- end
1723
- end
1724
-
1725
- context "when the document is not new" do
1726
-
1727
- let!(:existing) do
1728
- Band.create(name: "Photek")
1729
- end
1730
-
1731
- context "when updating fields outside of the id" do
1732
-
1733
- before do
1734
- existing.name = "Depeche Mode"
1735
- end
1736
-
1737
- let!(:upsert) do
1738
- existing.upsert
1739
- end
1740
-
1741
- it "updates the existing document" do
1742
- existing.reload.name.should eq("Depeche Mode")
1743
- end
1744
-
1745
- it "returns true" do
1746
- upsert.should be_true
1747
- end
1748
- end
1749
- end
1750
- end
1751
-
1752
- [ :delete_all, :destroy_all ].each do |method|
1753
-
1754
- describe "##{method}" do
1755
-
1756
- let!(:person) do
1757
- Person.create(title: "sir")
1758
- end
1759
-
1760
- context "when no conditions are provided" do
1761
-
1762
- let!(:removed) do
1763
- Person.send(method)
1764
- end
1765
-
1766
- it "removes all the documents" do
1767
- Person.count.should eq(0)
1768
- end
1769
-
1770
- it "returns the number of documents removed" do
1771
- removed.should eq(1)
1772
- end
1773
- end
1774
-
1775
- context "when conditions are provided" do
1776
-
1777
- let!(:person_two) do
1778
- Person.create
1779
- end
1780
-
1781
- context "when in a conditions attribute" do
1782
-
1783
- let!(:removed) do
1784
- Person.send(method, conditions: { title: "sir" })
1785
- end
1786
-
1787
- it "removes the matching documents" do
1788
- Person.count.should eq(1)
1789
- end
1790
-
1791
- it "returns the number of documents removed" do
1792
- removed.should eq(1)
1793
- end
1794
- end
1795
-
1796
- context "when no conditions attribute provided" do
1797
-
1798
- let!(:removed) do
1799
- Person.send(method, title: "sir")
1800
- end
1801
-
1802
- it "removes the matching documents" do
1803
- Person.count.should eq(1)
1804
- end
1805
-
1806
- it "returns the number of documents removed" do
1807
- removed.should eq(1)
1808
- end
1809
- end
1810
- end
1811
- end
1812
- end
1813
-
1814
- context "when a DateTime attribute is updated and persisted" do
1815
-
1816
- let(:user) do
1817
- User.create!(last_login: 2.days.ago).tap do |u|
1818
- u.last_login = DateTime.now
1819
- end
1820
- end
1821
-
1822
- it "reads for persistance as a UTC Time" do
1823
- user.changes["last_login"].last.class.should eq(Time)
1824
- end
1825
-
1826
- it "persists with no exceptions thrown" do
1827
- user.save!
1828
- end
1829
- end
1830
-
1831
- context "when a Date attribute is persisted" do
1832
-
1833
- let(:user) do
1834
- User.create!(account_expires: 2.years.from_now).tap do |u|
1835
- u.account_expires = "2/2/2002".to_date
1836
- end
1837
- end
1838
-
1839
- it "reads for persistance as a UTC Time" do
1840
- user.changes["account_expires"].last.class.should eq(Time)
1841
- end
1842
-
1843
- it "persists with no exceptions thrown" do
1844
- user.save!
1845
- end
1846
- end
1847
-
1848
- context "when setting floating point numbers" do
1849
-
1850
- context "when value is an empty string" do
1851
-
1852
- let(:person) do
1853
- Person.new
1854
- end
1855
-
1856
- before do
1857
- Person.validates_numericality_of :blood_alcohol_content, allow_blank: true
1858
- end
1859
-
1860
- it "does not set the value" do
1861
- person.save.should be_true
1862
- end
1863
- end
1864
- end
1865
-
1866
- context "when setting association foreign keys" do
1867
-
1868
- let(:game) do
1869
- Game.new
1870
- end
1871
-
1872
- let(:person) do
1873
- Person.create
1874
- end
1875
-
1876
- context "when value is an empty string" do
1877
-
1878
- before do
1879
- game.person_id = ""
1880
- game.save
1881
- end
1882
-
1883
- it "sets the foreign key to empty" do
1884
- game.reload.person_id.should be_blank
1885
- end
1886
- end
1887
-
1888
- context "when value is a populated string" do
1889
-
1890
- before do
1891
- game.person_id = person.id.to_s
1892
- game.save
1893
- end
1894
-
1895
- it "sets the foreign key as ObjectID" do
1896
- game.reload.person_id.should eq(person.id)
1897
- end
1898
- end
1899
-
1900
- context "when value is a ObjectID" do
1901
-
1902
- before do
1903
- game.person_id = person.id
1904
- game.save
1905
- end
1906
-
1907
- it "keeps the the foreign key as ObjectID" do
1908
- game.reload.person_id.should eq(person.id)
1909
- end
1910
- end
1911
- end
1912
-
1913
- context "when the document is a subclass of a root class" do
1914
-
1915
- let!(:browser) do
1916
- Browser.create(version: 3, name: "Test")
1917
- end
1918
-
1919
- let(:collection) do
1920
- Canvas.collection
1921
- end
1922
-
1923
- let(:attributes) do
1924
- collection.find({ name: "Test"}).first
1925
- end
1926
-
1927
- it "persists the versions" do
1928
- attributes["version"].should eq(3)
1929
- end
1930
-
1931
- it "persists the type" do
1932
- attributes["_type"].should eq("Browser")
1933
- end
1934
-
1935
- it "persists the attributes" do
1936
- attributes["name"].should eq("Test")
1937
- end
1938
- end
1939
-
1940
- context "when the document is a subclass of a subclass" do
1941
-
1942
- let!(:firefox) do
1943
- Firefox.create(version: 2, name: "Testy")
1944
- end
1945
-
1946
- let(:collection) do
1947
- Canvas.collection
1948
- end
1949
-
1950
- let(:attributes) do
1951
- collection.find({ name: "Testy"}).first
1952
- end
1953
-
1954
- before do
1955
- Browser.create(name: 'Safari', version: '4.0.0')
1956
- end
1957
-
1958
- it "persists the versions" do
1959
- attributes["version"].should eq(2)
1960
- end
1961
-
1962
- it "persists the type" do
1963
- attributes["_type"].should eq("Firefox")
1964
- end
1965
-
1966
- it "persists the attributes" do
1967
- attributes["name"].should eq("Testy")
1968
- end
1969
-
1970
- it "returns the document when querying for superclass" do
1971
- Browser.where(name: "Testy").first.should eq(firefox)
1972
- end
1973
-
1974
- it "returns the document when querying for root class" do
1975
- Canvas.where(name: "Testy").first.should eq(firefox)
1976
- end
1977
-
1978
- it 'returnss on of this subclasses if you find by _type' do
1979
- Canvas.where(:_type.in => ['Firefox']).count.should eq(1)
1980
- end
1981
- end
1982
-
1983
- context "when the document has associations" do
1984
-
1985
- let!(:firefox) do
1986
- Firefox.create(name: "firefox")
1987
- end
1988
-
1989
- let!(:writer) do
1990
- HtmlWriter.new(speed: 100)
1991
- end
1992
-
1993
- let!(:circle) do
1994
- Circle.new(radius: 50)
1995
- end
1996
-
1997
- let!(:square) do
1998
- Square.new(width: 300, height: 150)
1999
- end
2000
-
2001
- let(:from_db) do
2002
- Firefox.find(firefox.id)
2003
- end
2004
-
2005
- before do
2006
- firefox.writer = writer
2007
- firefox.shapes << [ circle, square ]
2008
- firefox.save!
2009
- end
2010
-
2011
- it "properly persists the one-to-one type" do
2012
- from_db.should be_a_kind_of(Firefox)
2013
- end
2014
-
2015
- it "properly persists the one-to-one relations" do
2016
- from_db.writer.should eq(writer)
2017
- end
2018
-
2019
- it "properly persists the one-to-many type" do
2020
- from_db.shapes.first.should eq(circle)
2021
- end
2022
-
2023
- it "properly persists the one-to-many relations" do
2024
- from_db.shapes.last.should eq(square)
2025
- end
2026
-
2027
- it "properly sets up the parent relation" do
2028
- from_db.shapes.first.should eq(circle)
2029
- end
2030
-
2031
- it "properly sets up the entire hierarchy" do
2032
- from_db.shapes.first.canvas.should eq(firefox)
2033
- end
2034
- end
2035
-
2036
- context "when the document is subclassed" do
2037
-
2038
- let!(:firefox) do
2039
- Firefox.create(name: "firefox")
2040
- end
2041
-
2042
- it "finds the document with String args" do
2043
- Firefox.find(firefox.id.to_s).should eq(firefox)
2044
- end
2045
-
2046
- context "when querying for parent documents" do
2047
-
2048
- let(:canvas) do
2049
- Canvas.where(name: "firefox").first
2050
- end
2051
-
2052
- it "returns matching subclasses" do
2053
- canvas.should eq(firefox)
2054
- end
2055
- end
2056
- end
2057
-
2058
- context "when deleting subclasses" do
2059
-
2060
- let!(:firefox) do
2061
- Firefox.create(name: "firefox")
2062
- end
2063
-
2064
- let!(:firefox2) do
2065
- Firefox.create(name: "firefox 2")
2066
- end
2067
-
2068
- let!(:browser) do
2069
- Browser.create(name: "browser")
2070
- end
2071
-
2072
- let!(:canvas) do
2073
- Canvas.create(name: "canvas")
2074
- end
2075
-
2076
- context "when deleting a single document" do
2077
-
2078
- before do
2079
- firefox.delete
2080
- end
2081
-
2082
- it "deletes from the parent class collection" do
2083
- Canvas.count.should eq(3)
2084
- end
2085
-
2086
- it "returns correct counts for child classes" do
2087
- Firefox.count.should eq(1)
2088
- end
2089
-
2090
- it "returns correct counts for root subclasses" do
2091
- Browser.count.should eq(2)
2092
- end
2093
- end
2094
-
2095
- context "when deleting all documents" do
2096
-
2097
- before do
2098
- Firefox.delete_all
2099
- end
2100
-
2101
- it "deletes from the parent class collection" do
2102
- Canvas.count.should eq(2)
2103
- end
2104
-
2105
- it "returns correct counts for child classes" do
2106
- Firefox.count.should eq(0)
2107
- end
2108
-
2109
- it "returns correct counts for root subclasses" do
2110
- Browser.count.should eq(1)
2111
- end
2112
- end
2113
- end
2114
-
2115
- context "when document is a subclass and its parent is an embedded document" do
2116
-
2117
- let!(:canvas) do
2118
- Canvas.create(name: "canvas")
2119
- end
2120
-
2121
- before do
2122
- canvas.create_palette
2123
- canvas.palette.tools << Pencil.new
2124
- canvas.palette.tools << Eraser.new
2125
- end
2126
-
2127
- let(:from_db) do
2128
- Canvas.find(canvas.id)
2129
- end
2130
-
2131
- it "properly saves the subclasses" do
2132
- from_db.palette.tools.map(&:class).should eq([Pencil, Eraser])
2133
- end
2134
- end
2135
-
2136
- context "Creating references_many documents from a parent association" do
2137
-
2138
- let!(:container) do
2139
- ShippingContainer.create
2140
- end
2141
-
2142
- let(:driver) do
2143
- Driver.create
2144
- end
2145
-
2146
- it "does not bleed relations from one subclass to another" do
2147
- Truck.relations.keys.should =~ %w/ shipping_container driver bed /
2148
- Car.relations.keys.should =~ %w/ shipping_container driver /
2149
- end
2150
-
2151
- context "when appending new documents" do
2152
-
2153
- before do
2154
- container.vehicles << Car.new
2155
- container.vehicles << Truck.new
2156
- end
2157
-
2158
- it "allows STI from << using model.new" do
2159
- container.vehicles.map(&:class).should eq([ Car, Truck ])
2160
- end
2161
- end
2162
-
2163
- context "when appending persisted documents" do
2164
-
2165
- before do
2166
- container.vehicles << Car.create
2167
- container.vehicles << Truck.create
2168
- end
2169
-
2170
- it "allows STI from << using model.create" do
2171
- container.vehicles.map(&:class).should eq([ Car, Truck ])
2172
- end
2173
- end
2174
-
2175
- context "when building related documents" do
2176
-
2177
- before do
2178
- container.vehicles.build({}, Car).save
2179
- container.vehicles.build({}, Truck).save
2180
- end
2181
-
2182
- it "allows STI from the build call" do
2183
- container.vehicles.map(&:class).should eq([ Car, Truck ])
2184
- end
2185
- end
2186
-
2187
- context "when building with a type attribute" do
2188
-
2189
- before do
2190
- container.vehicles.build({ "_type" => "Car" })
2191
- container.vehicles.build({ "_type" => "Truck" })
2192
- end
2193
-
2194
- it "respects the _type attribute from the build call" do
2195
- container.vehicles.map(&:class).should eq([ Car, Truck ])
2196
- end
2197
- end
2198
-
2199
- context "when creating related documents" do
2200
-
2201
- before do
2202
- container.vehicles.create({}, Car)
2203
- container.vehicles.create({}, Truck)
2204
- end
2205
-
2206
- it "allows STI from the create call" do
2207
- container.vehicles.map(&:class).should eq([ Car, Truck ])
2208
- end
2209
- end
2210
-
2211
- context "when creating with a type attribute" do
2212
-
2213
- before do
2214
- container.vehicles.create({ "_type" => "Car" })
2215
- container.vehicles.create({ "_type" => "Truck" })
2216
- end
2217
-
2218
- it "respects the _type attribute from the create call" do
2219
- container.vehicles.map(&:class).should eq([ Car, Truck ])
2220
- end
2221
- end
2222
-
2223
- context "#find_or_initialize_by" do
2224
-
2225
- before do
2226
- container.vehicles.find_or_initialize_by({ driver_id: driver.id }, Car)
2227
- end
2228
-
2229
- it "initializes the given type document" do
2230
- container.vehicles.map(&:class).should eq([ Car ])
2231
- end
2232
-
2233
- it "initializes with the given attributes" do
2234
- container.vehicles.map(&:driver).should eq([ driver ])
2235
- end
2236
- end
2237
-
2238
- context "#find_or_create_by" do
2239
-
2240
- before do
2241
- container.vehicles.find_or_create_by({ driver_id: driver.id }, Car)
2242
- end
2243
-
2244
- it "creates the given type document" do
2245
- container.vehicles.map(&:class).should eq([ Car ])
2246
- end
2247
-
2248
- it "creates with the given attributes" do
2249
- container.vehicles.map(&:driver).should eq([ driver ])
2250
- end
2251
-
2252
- it "creates the correct number of documents" do
2253
- container.vehicles.size.should eq(1)
2254
- end
2255
-
2256
- context "when executing with a found document" do
2257
-
2258
- before do
2259
- container.vehicles.find_or_create_by({ driver_id: driver.id }, Car)
2260
- end
2261
-
2262
- it "does not create an additional document" do
2263
- container.vehicles.size.should eq(1)
2264
- end
2265
- end
2266
-
2267
- context "when executing with an additional new document" do
2268
-
2269
- before do
2270
- container.vehicles.find_or_create_by({ driver_id: driver.id }, Truck)
2271
- end
2272
-
2273
- it "creates the new additional document" do
2274
- container.vehicles.size.should eq(2)
2275
- end
2276
- end
2277
- end
2278
- end
2279
- end