mongoid 3.1.7 → 4.0.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (521) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +317 -11
  3. data/README.md +4 -5
  4. data/lib/config/locales/en.yml +9 -12
  5. data/lib/mongoid.rb +6 -75
  6. data/lib/mongoid/atomic.rb +0 -11
  7. data/lib/mongoid/atomic/paths/embedded.rb +0 -30
  8. data/lib/mongoid/atomic/paths/root.rb +0 -13
  9. data/lib/mongoid/attributes.rb +30 -108
  10. data/lib/mongoid/attributes/dynamic.rb +154 -0
  11. data/lib/mongoid/attributes/nested.rb +82 -0
  12. data/lib/mongoid/attributes/processing.rb +13 -66
  13. data/lib/mongoid/{dirty.rb → changeable.rb} +5 -2
  14. data/lib/mongoid/composable.rb +104 -0
  15. data/lib/mongoid/config.rb +3 -9
  16. data/lib/mongoid/config/options.rb +1 -1
  17. data/lib/mongoid/contextual/aggregable/mongo.rb +5 -9
  18. data/lib/mongoid/contextual/atomic.rb +53 -53
  19. data/lib/mongoid/contextual/command.rb +26 -0
  20. data/lib/mongoid/contextual/map_reduce.rb +1 -1
  21. data/lib/mongoid/contextual/memory.rb +6 -5
  22. data/lib/mongoid/contextual/mongo.rb +59 -28
  23. data/lib/mongoid/contextual/text_search.rb +180 -0
  24. data/lib/mongoid/copyable.rb +2 -3
  25. data/lib/mongoid/criteria.rb +13 -33
  26. data/lib/mongoid/criteria/{#findable.rb# → findable.rb} +0 -2
  27. data/lib/mongoid/{criterion/inspection.rb → criteria/inspectable.rb} +2 -2
  28. data/lib/mongoid/{criterion → criteria}/marshalable.rb +3 -1
  29. data/lib/mongoid/{criterion → criteria}/modifiable.rb +1 -1
  30. data/lib/mongoid/{criterion/scoping.rb → criteria/scopable.rb} +2 -2
  31. data/lib/mongoid/document.rb +28 -12
  32. data/lib/mongoid/errors.rb +1 -1
  33. data/lib/mongoid/errors/document_not_found.rb +2 -1
  34. data/lib/mongoid/errors/invalid_value.rb +16 -0
  35. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  36. data/lib/mongoid/extensions.rb +2 -7
  37. data/lib/mongoid/extensions/array.rb +2 -2
  38. data/lib/mongoid/extensions/boolean.rb +14 -17
  39. data/lib/mongoid/extensions/float.rb +1 -0
  40. data/lib/mongoid/extensions/hash.rb +1 -1
  41. data/lib/mongoid/extensions/object.rb +4 -4
  42. data/lib/mongoid/extensions/object_id.rb +5 -5
  43. data/lib/mongoid/extensions/range.rb +8 -2
  44. data/lib/mongoid/extensions/string.rb +5 -17
  45. data/lib/mongoid/extensions/time.rb +2 -2
  46. data/lib/mongoid/factory.rb +3 -3
  47. data/lib/mongoid/fields.rb +9 -8
  48. data/lib/mongoid/fields/foreign_key.rb +3 -3
  49. data/lib/mongoid/fields/standard.rb +4 -16
  50. data/lib/mongoid/fields/validators/macro.rb +11 -3
  51. data/lib/mongoid/{finders.rb → findable.rb} +6 -2
  52. data/lib/mongoid/{indexes.rb → indexable.rb} +50 -55
  53. data/lib/mongoid/indexable/specification.rb +104 -0
  54. data/lib/mongoid/{indexes → indexable}/validators/options.rb +2 -1
  55. data/lib/mongoid/{inspection.rb → inspectable.rb} +15 -11
  56. data/lib/mongoid/{callbacks.rb → interceptable.rb} +3 -52
  57. data/lib/mongoid/log_subscriber.rb +22 -0
  58. data/lib/mongoid/matchable.rb +152 -0
  59. data/lib/mongoid/{matchers → matchable}/all.rb +1 -1
  60. data/lib/mongoid/{matchers → matchable}/and.rb +2 -2
  61. data/lib/mongoid/{matchers → matchable}/default.rb +1 -1
  62. data/lib/mongoid/{matchers → matchable}/exists.rb +1 -1
  63. data/lib/mongoid/{matchers → matchable}/gt.rb +1 -1
  64. data/lib/mongoid/{matchers → matchable}/gte.rb +1 -1
  65. data/lib/mongoid/{matchers → matchable}/in.rb +2 -2
  66. data/lib/mongoid/{matchers → matchable}/lt.rb +1 -1
  67. data/lib/mongoid/{matchers → matchable}/lte.rb +1 -1
  68. data/lib/mongoid/{matchers → matchable}/ne.rb +1 -1
  69. data/lib/mongoid/{matchers → matchable}/nin.rb +3 -2
  70. data/lib/mongoid/{matchers → matchable}/or.rb +2 -2
  71. data/lib/mongoid/{matchers → matchable}/size.rb +1 -1
  72. data/lib/mongoid/persistable.rb +212 -0
  73. data/lib/mongoid/persistable/creatable.rb +188 -0
  74. data/lib/mongoid/persistable/deletable.rb +148 -0
  75. data/lib/mongoid/persistable/destroyable.rb +55 -0
  76. data/lib/mongoid/persistable/incrementable.rb +36 -0
  77. data/lib/mongoid/persistable/logical.rb +38 -0
  78. data/lib/mongoid/persistable/poppable.rb +39 -0
  79. data/lib/mongoid/persistable/pullable.rb +55 -0
  80. data/lib/mongoid/persistable/pushable.rb +62 -0
  81. data/lib/mongoid/persistable/renamable.rb +35 -0
  82. data/lib/mongoid/persistable/savable.rb +52 -0
  83. data/lib/mongoid/persistable/settable.rb +33 -0
  84. data/lib/mongoid/persistable/unsettable.rb +36 -0
  85. data/lib/mongoid/persistable/updatable.rb +151 -0
  86. data/lib/mongoid/persistable/upsertable.rb +55 -0
  87. data/lib/mongoid/positional.rb +71 -0
  88. data/lib/mongoid/railtie.rb +32 -45
  89. data/lib/mongoid/railties/database.rake +12 -6
  90. data/lib/mongoid/relations.rb +3 -3
  91. data/lib/mongoid/relations/accessors.rb +13 -46
  92. data/lib/mongoid/relations/auto_save.rb +15 -36
  93. data/lib/mongoid/relations/binding.rb +0 -23
  94. data/lib/mongoid/relations/bindings/embedded/many.rb +1 -3
  95. data/lib/mongoid/relations/bindings/referenced/in.rb +3 -8
  96. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +3 -1
  97. data/lib/mongoid/relations/builder.rb +1 -1
  98. data/lib/mongoid/relations/builders.rb +2 -2
  99. data/lib/mongoid/relations/builders/nested_attributes/many.rb +10 -13
  100. data/lib/mongoid/relations/builders/nested_attributes/one.rb +4 -5
  101. data/lib/mongoid/relations/builders/referenced/in.rb +1 -1
  102. data/lib/mongoid/relations/builders/referenced/many.rb +1 -2
  103. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +1 -2
  104. data/lib/mongoid/relations/builders/referenced/one.rb +1 -1
  105. data/lib/mongoid/relations/cascading.rb +3 -5
  106. data/lib/mongoid/relations/constraint.rb +1 -1
  107. data/lib/mongoid/relations/conversions.rb +1 -1
  108. data/lib/mongoid/relations/counter_cache.rb +39 -15
  109. data/lib/mongoid/relations/eager.rb +47 -0
  110. data/lib/mongoid/relations/eager/base.rb +57 -0
  111. data/lib/mongoid/relations/eager/belongs_to.rb +30 -0
  112. data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +40 -0
  113. data/lib/mongoid/relations/eager/has_many.rb +37 -0
  114. data/lib/mongoid/relations/eager/has_one.rb +29 -0
  115. data/lib/mongoid/relations/embedded/batchable.rb +3 -4
  116. data/lib/mongoid/relations/embedded/many.rb +7 -27
  117. data/lib/mongoid/relations/macros.rb +2 -4
  118. data/lib/mongoid/relations/many.rb +30 -31
  119. data/lib/mongoid/relations/metadata.rb +6 -75
  120. data/lib/mongoid/relations/nested_builder.rb +2 -2
  121. data/lib/mongoid/relations/options.rb +1 -0
  122. data/lib/mongoid/relations/polymorphic.rb +0 -1
  123. data/lib/mongoid/relations/proxy.rb +10 -32
  124. data/lib/mongoid/relations/referenced/in.rb +2 -18
  125. data/lib/mongoid/relations/referenced/many.rb +9 -22
  126. data/lib/mongoid/relations/referenced/many_to_many.rb +10 -33
  127. data/lib/mongoid/relations/referenced/one.rb +2 -21
  128. data/lib/mongoid/relations/synchronization.rb +3 -3
  129. data/lib/mongoid/relations/touchable.rb +33 -0
  130. data/lib/mongoid/{reloading.rb → reloadable.rb} +6 -4
  131. data/lib/mongoid/{scoping.rb → scopable.rb} +26 -3
  132. data/lib/mongoid/selectable.rb +59 -0
  133. data/lib/mongoid/{serialization.rb → serializable.rb} +10 -1
  134. data/lib/mongoid/sessions.rb +37 -345
  135. data/lib/mongoid/sessions/factory.rb +2 -0
  136. data/lib/mongoid/sessions/options.rb +176 -0
  137. data/lib/mongoid/sessions/storage_options.rb +140 -0
  138. data/lib/mongoid/sessions/thread_options.rb +19 -0
  139. data/lib/mongoid/sessions/validators/storage.rb +15 -1
  140. data/lib/mongoid/{sharding.rb → shardable.rb} +5 -1
  141. data/lib/mongoid/support/query_counter.rb +23 -0
  142. data/lib/mongoid/threaded.rb +0 -110
  143. data/lib/mongoid/threaded/lifecycle.rb +0 -28
  144. data/lib/mongoid/timestamps/updated/short.rb +2 -2
  145. data/lib/mongoid/{hierarchy.rb → traversable.rb} +9 -5
  146. data/lib/mongoid/{validations.rb → validatable.rb} +23 -9
  147. data/lib/mongoid/{validations → validatable}/associated.rb +3 -1
  148. data/lib/mongoid/{validations → validatable}/format.rb +1 -1
  149. data/lib/mongoid/{validations → validatable}/length.rb +1 -1
  150. data/lib/mongoid/{validations → validatable}/localizable.rb +1 -1
  151. data/lib/mongoid/{validations → validatable}/macros.rb +4 -3
  152. data/lib/mongoid/{validations → validatable}/presence.rb +1 -1
  153. data/lib/mongoid/{validations → validatable}/queryable.rb +1 -2
  154. data/lib/mongoid/{validations → validatable}/uniqueness.rb +3 -3
  155. data/lib/mongoid/version.rb +1 -1
  156. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +9 -13
  157. data/lib/rails/generators/mongoid/model/model_generator.rb +0 -1
  158. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +0 -3
  159. data/lib/rails/generators/mongoid_generator.rb +3 -40
  160. data/lib/rails/mongoid.rb +59 -57
  161. data/lib/support/ruby_version.rb +1 -1
  162. data/spec/app/models/account.rb +2 -6
  163. data/spec/app/models/acolyte.rb +1 -0
  164. data/spec/app/models/actor.rb +0 -1
  165. data/spec/app/models/address.rb +6 -1
  166. data/spec/app/models/animal.rb +1 -1
  167. data/spec/app/models/appointment.rb +2 -2
  168. data/spec/app/models/article.rb +1 -4
  169. data/spec/app/models/audio.rb +5 -0
  170. data/spec/app/models/author.rb +0 -2
  171. data/spec/app/models/band.rb +3 -2
  172. data/spec/app/models/bar.rb +1 -0
  173. data/spec/app/models/book.rb +1 -0
  174. data/spec/app/models/building.rb +0 -2
  175. data/spec/app/models/building_address.rb +0 -2
  176. data/spec/app/models/bus.rb +1 -1
  177. data/spec/app/models/canvas.rb +1 -1
  178. data/spec/app/models/contractor.rb +0 -2
  179. data/spec/app/models/country_code.rb +1 -1
  180. data/spec/app/models/definition.rb +2 -2
  181. data/spec/app/models/dragon.rb +4 -0
  182. data/spec/app/models/drug.rb +1 -3
  183. data/spec/app/models/dungeon.rb +4 -0
  184. data/spec/app/models/filesystem.rb +1 -0
  185. data/spec/app/models/fish.rb +0 -1
  186. data/spec/app/models/fruits.rb +6 -0
  187. data/spec/app/models/game.rb +0 -2
  188. data/spec/app/models/house.rb +0 -2
  189. data/spec/app/models/item.rb +1 -5
  190. data/spec/app/models/jar.rb +1 -1
  191. data/spec/app/models/label.rb +4 -4
  192. data/spec/app/models/login.rb +1 -1
  193. data/spec/app/models/movie.rb +1 -0
  194. data/spec/app/models/name.rb +3 -3
  195. data/spec/app/models/note.rb +1 -1
  196. data/spec/app/models/oscar.rb +1 -1
  197. data/spec/app/models/parent_doc.rb +1 -1
  198. data/spec/app/models/person.rb +13 -8
  199. data/spec/app/models/phone.rb +1 -3
  200. data/spec/app/models/player.rb +1 -1
  201. data/spec/app/models/post.rb +2 -1
  202. data/spec/app/models/quiz.rb +0 -3
  203. data/spec/app/models/record.rb +5 -5
  204. data/spec/app/models/registry.rb +1 -1
  205. data/spec/app/models/server.rb +1 -1
  206. data/spec/app/models/service.rb +3 -3
  207. data/spec/app/models/sound.rb +5 -0
  208. data/spec/app/models/template.rb +1 -1
  209. data/spec/app/models/title.rb +0 -1
  210. data/spec/app/models/track.rb +5 -5
  211. data/spec/app/models/tree.rb +1 -1
  212. data/spec/app/models/video.rb +0 -4
  213. data/spec/app/models/wiki_page.rb +1 -4
  214. data/spec/app/models/word.rb +3 -0
  215. data/spec/app/models/word_origin.rb +1 -1
  216. data/spec/config/mongoid.yml +7 -8
  217. data/spec/helpers.rb +18 -0
  218. data/spec/mongoid/atomic/modifiers_spec.rb +22 -22
  219. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +8 -49
  220. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +7 -49
  221. data/spec/mongoid/atomic/paths/root_spec.rb +3 -61
  222. data/spec/mongoid/atomic/paths_spec.rb +19 -19
  223. data/spec/mongoid/atomic_spec.rb +19 -19
  224. data/spec/mongoid/{nested_attributes_spec.rb → attributes/nested_spec.rb} +335 -448
  225. data/spec/mongoid/attributes/readonly_spec.rb +16 -16
  226. data/spec/mongoid/attributes_spec.rb +188 -434
  227. data/spec/mongoid/{dirty_spec.rb → changeable_spec.rb} +117 -148
  228. data/spec/mongoid/{components_spec.rb → composable_spec.rb} +3 -3
  229. data/spec/mongoid/config/environment_spec.rb +3 -3
  230. data/spec/mongoid/config/options_spec.rb +6 -6
  231. data/spec/mongoid/config_spec.rb +24 -48
  232. data/spec/mongoid/contextual/aggregable/memory_spec.rb +12 -12
  233. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +46 -38
  234. data/spec/mongoid/contextual/atomic_spec.rb +60 -56
  235. data/spec/mongoid/contextual/find_and_modify_spec.rb +14 -14
  236. data/spec/mongoid/contextual/geo_near_spec.rb +22 -22
  237. data/spec/mongoid/contextual/map_reduce_spec.rb +27 -27
  238. data/spec/mongoid/contextual/memory_spec.rb +94 -94
  239. data/spec/mongoid/contextual/mongo_spec.rb +225 -139
  240. data/spec/mongoid/contextual/text_search_spec.rb +207 -0
  241. data/spec/mongoid/copyable_spec.rb +56 -68
  242. data/spec/mongoid/criteria/findable_spec.rb +991 -0
  243. data/spec/mongoid/{criterion/inspection_spec.rb → criteria/inspectable_spec.rb} +5 -5
  244. data/spec/mongoid/{criterion → criteria}/marshalable_spec.rb +2 -2
  245. data/spec/mongoid/criteria/modifiable_spec.rb +1063 -0
  246. data/spec/mongoid/{criterion/scoping_spec.rb → criteria/scopable_spec.rb} +31 -31
  247. data/spec/mongoid/criteria_spec.rb +530 -2207
  248. data/spec/mongoid/document_spec.rb +166 -120
  249. data/spec/mongoid/equality_spec.rb +22 -22
  250. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +3 -3
  251. data/spec/mongoid/errors/callback_spec.rb +3 -3
  252. data/spec/mongoid/errors/delete_restriction_spec.rb +3 -3
  253. data/spec/mongoid/errors/document_not_found_spec.rb +11 -11
  254. data/spec/mongoid/errors/eager_load_spec.rb +3 -3
  255. data/spec/mongoid/errors/invalid_collection_spec.rb +3 -3
  256. data/spec/mongoid/errors/invalid_config_option_spec.rb +3 -3
  257. data/spec/mongoid/errors/invalid_field_option_spec.rb +3 -3
  258. data/spec/mongoid/errors/invalid_field_spec.rb +3 -3
  259. data/spec/mongoid/errors/invalid_find_spec.rb +3 -3
  260. data/spec/mongoid/errors/invalid_includes_spec.rb +3 -3
  261. data/spec/mongoid/errors/invalid_index_spec.rb +3 -3
  262. data/spec/mongoid/errors/invalid_options_spec.rb +3 -3
  263. data/spec/mongoid/errors/invalid_path_spec.rb +3 -3
  264. data/spec/mongoid/errors/invalid_scope_spec.rb +3 -3
  265. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +3 -3
  266. data/spec/mongoid/errors/invalid_storage_options_spec.rb +3 -3
  267. data/spec/mongoid/errors/invalid_time_spec.rb +3 -3
  268. data/spec/mongoid/errors/inverse_not_found_spec.rb +3 -3
  269. data/spec/mongoid/errors/mixed_relations_spec.rb +3 -3
  270. data/spec/mongoid/errors/mixed_session_configuration_spec.rb +3 -3
  271. data/spec/mongoid/errors/mongoid_error_spec.rb +7 -7
  272. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +3 -3
  273. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  274. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +3 -3
  275. data/spec/mongoid/errors/no_metadata_spec.rb +3 -3
  276. data/spec/mongoid/errors/no_parent_spec.rb +3 -3
  277. data/spec/mongoid/errors/no_session_config_spec.rb +3 -3
  278. data/spec/mongoid/errors/no_session_database_spec.rb +3 -3
  279. data/spec/mongoid/errors/no_session_hosts_spec.rb +3 -3
  280. data/spec/mongoid/errors/no_sessions_config_spec.rb +3 -3
  281. data/spec/mongoid/errors/readonly_attribute_spec.rb +3 -3
  282. data/spec/mongoid/errors/scope_overwrite_spec.rb +3 -3
  283. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +3 -3
  284. data/spec/mongoid/errors/unknown_attribute_spec.rb +5 -5
  285. data/spec/mongoid/errors/unsaved_document_spec.rb +3 -3
  286. data/spec/mongoid/errors/unsupported_javascript_spec.rb +3 -3
  287. data/spec/mongoid/errors/validations_spec.rb +7 -7
  288. data/spec/mongoid/extensions/array_spec.rb +61 -61
  289. data/spec/mongoid/extensions/big_decimal_spec.rb +11 -11
  290. data/spec/mongoid/extensions/binary_spec.rb +12 -12
  291. data/spec/mongoid/extensions/boolean_spec.rb +18 -18
  292. data/spec/mongoid/extensions/date_spec.rb +13 -13
  293. data/spec/mongoid/extensions/date_time_spec.rb +9 -9
  294. data/spec/mongoid/extensions/false_class_spec.rb +5 -5
  295. data/spec/mongoid/extensions/float_spec.rb +29 -15
  296. data/spec/mongoid/extensions/hash_spec.rb +29 -29
  297. data/spec/mongoid/extensions/integer_spec.rb +15 -15
  298. data/spec/mongoid/extensions/module_spec.rb +2 -2
  299. data/spec/mongoid/extensions/nil_class_spec.rb +1 -1
  300. data/spec/mongoid/extensions/object_id_spec.rb +134 -134
  301. data/spec/mongoid/extensions/object_spec.rb +26 -26
  302. data/spec/mongoid/extensions/range_spec.rb +61 -12
  303. data/spec/mongoid/extensions/regexp_spec.rb +4 -4
  304. data/spec/mongoid/extensions/set_spec.rb +4 -4
  305. data/spec/mongoid/extensions/string_spec.rb +35 -46
  306. data/spec/mongoid/extensions/symbol_spec.rb +9 -9
  307. data/spec/mongoid/extensions/time_spec.rb +49 -49
  308. data/spec/mongoid/extensions/time_with_zone_spec.rb +34 -34
  309. data/spec/mongoid/extensions/true_class_spec.rb +5 -5
  310. data/spec/mongoid/extensions_spec.rb +15 -0
  311. data/spec/mongoid/factory_spec.rb +15 -15
  312. data/spec/mongoid/fields/foreign_key_spec.rb +73 -66
  313. data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +15 -15
  314. data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +22 -22
  315. data/spec/mongoid/fields/localized_spec.rb +23 -23
  316. data/spec/mongoid/fields/standard_spec.rb +12 -12
  317. data/spec/mongoid/fields_spec.rb +168 -209
  318. data/spec/mongoid/{finders_spec.rb → findable_spec.rb} +62 -27
  319. data/spec/mongoid/indexable/specification_spec.rb +102 -0
  320. data/spec/mongoid/{indexes_spec.rb → indexable_spec.rb} +171 -51
  321. data/spec/mongoid/{inspection_spec.rb → inspectable_spec.rb} +6 -14
  322. data/spec/mongoid/{callbacks_spec.rb → interceptable_spec.rb} +105 -105
  323. data/spec/mongoid/log_subscriber_spec.rb +74 -0
  324. data/spec/mongoid/loggable_spec.rb +1 -1
  325. data/spec/mongoid/{matchers → matchable}/all_spec.rb +4 -4
  326. data/spec/mongoid/{matchers → matchable}/and_spec.rb +11 -11
  327. data/spec/mongoid/{matchers → matchable}/default_spec.rb +15 -15
  328. data/spec/mongoid/{matchers → matchable}/exists_spec.rb +5 -5
  329. data/spec/mongoid/{matchers → matchable}/gt_spec.rb +9 -8
  330. data/spec/mongoid/{matchers → matchable}/gte_spec.rb +7 -7
  331. data/spec/mongoid/matchable/in_spec.rb +49 -0
  332. data/spec/mongoid/{matchers → matchable}/lt_spec.rb +7 -7
  333. data/spec/mongoid/{matchers → matchable}/lte_spec.rb +7 -7
  334. data/spec/mongoid/{matchers → matchable}/ne_spec.rb +3 -3
  335. data/spec/mongoid/matchable/nin_spec.rb +48 -0
  336. data/spec/mongoid/{matchers → matchable}/or_spec.rb +6 -6
  337. data/spec/mongoid/{matchers → matchable}/size_spec.rb +3 -3
  338. data/spec/mongoid/{matchers_spec.rb → matchable_spec.rb} +41 -41
  339. data/spec/mongoid/persistable/creatable_spec.rb +512 -0
  340. data/spec/mongoid/persistable/deletable_spec.rb +205 -0
  341. data/spec/mongoid/persistable/destroyable_spec.rb +148 -0
  342. data/spec/mongoid/persistable/incrementable_spec.rb +173 -0
  343. data/spec/mongoid/persistable/logical_spec.rb +143 -0
  344. data/spec/mongoid/persistable/poppable_spec.rb +115 -0
  345. data/spec/mongoid/persistable/pullable_spec.rb +228 -0
  346. data/spec/mongoid/persistable/pushable_spec.rb +258 -0
  347. data/spec/mongoid/persistable/renamable_spec.rb +135 -0
  348. data/spec/mongoid/persistable/savable_spec.rb +432 -0
  349. data/spec/mongoid/persistable/settable_spec.rb +139 -0
  350. data/spec/mongoid/persistable/unsettable_spec.rb +155 -0
  351. data/spec/mongoid/persistable/updatable_spec.rb +558 -0
  352. data/spec/mongoid/persistable/upsertable_spec.rb +106 -0
  353. data/spec/mongoid/persistable_spec.rb +206 -0
  354. data/spec/mongoid/{atomic/positionable_spec.rb → positional_spec.rb} +19 -14
  355. data/spec/mongoid/railties/document_spec.rb +2 -2
  356. data/spec/mongoid/relations/accessors_spec.rb +53 -145
  357. data/spec/mongoid/relations/auto_save_spec.rb +36 -16
  358. data/spec/mongoid/relations/bindings/embedded/in_spec.rb +6 -6
  359. data/spec/mongoid/relations/bindings/embedded/many_spec.rb +2 -2
  360. data/spec/mongoid/relations/bindings/embedded/one_spec.rb +3 -3
  361. data/spec/mongoid/relations/bindings/referenced/in_spec.rb +12 -12
  362. data/spec/mongoid/relations/bindings/referenced/many_spec.rb +6 -6
  363. data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +9 -9
  364. data/spec/mongoid/relations/bindings/referenced/one_spec.rb +6 -6
  365. data/spec/mongoid/relations/builders/embedded/in_spec.rb +4 -4
  366. data/spec/mongoid/relations/builders/embedded/many_spec.rb +18 -18
  367. data/spec/mongoid/relations/builders/embedded/one_spec.rb +11 -11
  368. data/spec/mongoid/relations/builders/nested_attributes/many_spec.rb +12 -13
  369. data/spec/mongoid/relations/builders/nested_attributes/one_spec.rb +14 -14
  370. data/spec/mongoid/relations/builders/referenced/in_spec.rb +22 -33
  371. data/spec/mongoid/relations/builders/referenced/many_spec.rb +15 -15
  372. data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +18 -18
  373. data/spec/mongoid/relations/builders/referenced/one_spec.rb +11 -24
  374. data/spec/mongoid/relations/builders_spec.rb +21 -21
  375. data/spec/mongoid/relations/cascading/delete_spec.rb +7 -7
  376. data/spec/mongoid/relations/cascading/destroy_spec.rb +2 -2
  377. data/spec/mongoid/relations/cascading/nullify_spec.rb +2 -2
  378. data/spec/mongoid/relations/cascading/restrict_spec.rb +3 -3
  379. data/spec/mongoid/relations/cascading_spec.rb +16 -16
  380. data/spec/mongoid/relations/constraint_spec.rb +8 -7
  381. data/spec/mongoid/relations/conversions_spec.rb +16 -14
  382. data/spec/mongoid/relations/counter_cache_spec.rb +85 -0
  383. data/spec/mongoid/relations/cyclic_spec.rb +18 -18
  384. data/spec/mongoid/relations/eager/belongs_to_spec.rb +154 -0
  385. data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +143 -0
  386. data/spec/mongoid/relations/eager/has_many_spec.rb +207 -0
  387. data/spec/mongoid/relations/eager/has_one_spec.rb +163 -0
  388. data/spec/mongoid/relations/eager_spec.rb +228 -0
  389. data/spec/mongoid/relations/embedded/dirty_spec.rb +8 -8
  390. data/spec/mongoid/relations/embedded/in_spec.rb +55 -56
  391. data/spec/mongoid/relations/embedded/many_spec.rb +357 -367
  392. data/spec/mongoid/relations/embedded/one_spec.rb +98 -139
  393. data/spec/mongoid/relations/macros_spec.rb +108 -102
  394. data/spec/mongoid/relations/metadata_spec.rb +147 -241
  395. data/spec/mongoid/relations/options_spec.rb +1 -1
  396. data/spec/mongoid/relations/polymorphic_spec.rb +13 -17
  397. data/spec/mongoid/relations/proxy_spec.rb +2 -2
  398. data/spec/mongoid/relations/referenced/in_spec.rb +128 -303
  399. data/spec/mongoid/relations/referenced/many_spec.rb +379 -522
  400. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +345 -417
  401. data/spec/mongoid/relations/referenced/one_spec.rb +148 -263
  402. data/spec/mongoid/relations/reflections_spec.rb +6 -6
  403. data/spec/mongoid/relations/synchronization_spec.rb +46 -50
  404. data/spec/mongoid/relations/targets/enumerable_spec.rb +116 -116
  405. data/spec/mongoid/relations/touchable_spec.rb +296 -0
  406. data/spec/mongoid/relations_spec.rb +16 -15
  407. data/spec/mongoid/{reloading_spec.rb → reloadable_spec.rb} +20 -60
  408. data/spec/mongoid/{scoping_spec.rb → scopable_spec.rb} +74 -126
  409. data/spec/mongoid/selectable_spec.rb +134 -0
  410. data/spec/mongoid/{serialization_spec.rb → serializable_spec.rb} +111 -82
  411. data/spec/mongoid/sessions/factory_spec.rb +49 -28
  412. data/spec/mongoid/sessions/mongo_uri_spec.rb +7 -7
  413. data/spec/mongoid/sessions/options_spec.rb +92 -0
  414. data/spec/mongoid/sessions_spec.rb +288 -177
  415. data/spec/mongoid/{sharding_spec.rb → shardable_spec.rb} +8 -8
  416. data/spec/mongoid/state_spec.rb +10 -10
  417. data/spec/mongoid/threaded_spec.rb +17 -70
  418. data/spec/mongoid/timestamps/created/short_spec.rb +6 -6
  419. data/spec/mongoid/timestamps/created_spec.rb +5 -5
  420. data/spec/mongoid/timestamps/updated/short_spec.rb +10 -10
  421. data/spec/mongoid/timestamps/updated_spec.rb +8 -12
  422. data/spec/mongoid/timestamps_spec.rb +7 -11
  423. data/spec/mongoid/{hierarchy_spec.rb → traversable_spec.rb} +19 -19
  424. data/spec/mongoid/{validations → validatable}/associated_spec.rb +18 -18
  425. data/spec/mongoid/{validations → validatable}/format_spec.rb +6 -6
  426. data/spec/mongoid/{validations → validatable}/length_spec.rb +7 -7
  427. data/spec/mongoid/{validations → validatable}/numericality_spec.rb +1 -1
  428. data/spec/mongoid/{validations → validatable}/presence_spec.rb +31 -38
  429. data/spec/mongoid/{validations → validatable}/uniqueness_spec.rb +126 -183
  430. data/spec/mongoid/{validations_spec.rb → validatable_spec.rb} +28 -28
  431. data/spec/mongoid_spec.rb +8 -8
  432. data/spec/rails/mongoid_spec.rb +72 -87
  433. data/spec/spec_helper.rb +19 -17
  434. metadata +261 -283
  435. data/lib/mongoid/atomic/positionable.rb +0 -73
  436. data/lib/mongoid/components.rb +0 -92
  437. data/lib/mongoid/config/inflections.rb +0 -6
  438. data/lib/mongoid/contextual/eager.rb +0 -158
  439. data/lib/mongoid/criterion/findable.rb +0 -179
  440. data/lib/mongoid/errors/versioning_not_on_root.rb +0 -23
  441. data/lib/mongoid/identity_map.rb +0 -163
  442. data/lib/mongoid/json.rb +0 -16
  443. data/lib/mongoid/matchers.rb +0 -32
  444. data/lib/mongoid/matchers/strategies.rb +0 -97
  445. data/lib/mongoid/multi_parameter_attributes.rb +0 -105
  446. data/lib/mongoid/nested_attributes.rb +0 -78
  447. data/lib/mongoid/observer.rb +0 -192
  448. data/lib/mongoid/paranoia.rb +0 -136
  449. data/lib/mongoid/persistence.rb +0 -357
  450. data/lib/mongoid/persistence/atomic.rb +0 -231
  451. data/lib/mongoid/persistence/atomic/add_to_set.rb +0 -47
  452. data/lib/mongoid/persistence/atomic/bit.rb +0 -35
  453. data/lib/mongoid/persistence/atomic/inc.rb +0 -45
  454. data/lib/mongoid/persistence/atomic/operation.rb +0 -154
  455. data/lib/mongoid/persistence/atomic/pop.rb +0 -32
  456. data/lib/mongoid/persistence/atomic/pull.rb +0 -32
  457. data/lib/mongoid/persistence/atomic/pull_all.rb +0 -32
  458. data/lib/mongoid/persistence/atomic/push.rb +0 -25
  459. data/lib/mongoid/persistence/atomic/push_all.rb +0 -25
  460. data/lib/mongoid/persistence/atomic/rename.rb +0 -30
  461. data/lib/mongoid/persistence/atomic/sets.rb +0 -28
  462. data/lib/mongoid/persistence/atomic/unset.rb +0 -27
  463. data/lib/mongoid/persistence/deletion.rb +0 -31
  464. data/lib/mongoid/persistence/insertion.rb +0 -38
  465. data/lib/mongoid/persistence/modification.rb +0 -35
  466. data/lib/mongoid/persistence/operations.rb +0 -214
  467. data/lib/mongoid/persistence/operations/embedded/insert.rb +0 -46
  468. data/lib/mongoid/persistence/operations/embedded/remove.rb +0 -43
  469. data/lib/mongoid/persistence/operations/insert.rb +0 -34
  470. data/lib/mongoid/persistence/operations/remove.rb +0 -33
  471. data/lib/mongoid/persistence/operations/update.rb +0 -59
  472. data/lib/mongoid/persistence/operations/upsert.rb +0 -28
  473. data/lib/mongoid/persistence/upsertion.rb +0 -31
  474. data/lib/mongoid/unit_of_work.rb +0 -61
  475. data/lib/mongoid/versioning.rb +0 -217
  476. data/lib/rack/mongoid.rb +0 -2
  477. data/lib/rack/mongoid/middleware/identity_map.rb +0 -39
  478. data/lib/rails/generators/mongoid/observer/observer_generator.rb +0 -17
  479. data/lib/rails/generators/mongoid/observer/templates/observer.rb.tt +0 -4
  480. data/spec/app/models/actor_observer.rb +0 -15
  481. data/spec/app/models/callback_recorder.rb +0 -25
  482. data/spec/app/models/draft.rb +0 -9
  483. data/spec/app/models/paranoid_phone.rb +0 -25
  484. data/spec/app/models/paranoid_post.rb +0 -36
  485. data/spec/app/models/phone_observer.rb +0 -6
  486. data/spec/mongoid/#atomic_spec.rb# +0 -365
  487. data/spec/mongoid/attributes/processing_spec.rb +0 -149
  488. data/spec/mongoid/criterion/destructive_spec.rb +0 -101
  489. data/spec/mongoid/criterion/modifiable_spec.rb +0 -409
  490. data/spec/mongoid/criterion/modification_spec.rb +0 -402
  491. data/spec/mongoid/errors/versioning_not_on_root_spec.rb +0 -29
  492. data/spec/mongoid/identity_map_spec.rb +0 -564
  493. data/spec/mongoid/json_spec.rb +0 -33
  494. data/spec/mongoid/matchers/in_spec.rb +0 -25
  495. data/spec/mongoid/matchers/nin_spec.rb +0 -25
  496. data/spec/mongoid/multi_parameter_attributes_spec.rb +0 -128
  497. data/spec/mongoid/observer_spec.rb +0 -290
  498. data/spec/mongoid/paranoia_spec.rb +0 -759
  499. data/spec/mongoid/persistence/atomic/add_to_set_spec.rb +0 -262
  500. data/spec/mongoid/persistence/atomic/bit_spec.rb +0 -88
  501. data/spec/mongoid/persistence/atomic/inc_spec.rb +0 -133
  502. data/spec/mongoid/persistence/atomic/pop_spec.rb +0 -111
  503. data/spec/mongoid/persistence/atomic/pull_all_spec.rb +0 -77
  504. data/spec/mongoid/persistence/atomic/pull_spec.rb +0 -80
  505. data/spec/mongoid/persistence/atomic/push_all_spec.rb +0 -77
  506. data/spec/mongoid/persistence/atomic/push_spec.rb +0 -77
  507. data/spec/mongoid/persistence/atomic/rename_spec.rb +0 -42
  508. data/spec/mongoid/persistence/atomic/sets_spec.rb +0 -154
  509. data/spec/mongoid/persistence/atomic/unset_spec.rb +0 -65
  510. data/spec/mongoid/persistence/atomic_spec.rb +0 -216
  511. data/spec/mongoid/persistence/operations/embedded/insert_spec.rb +0 -191
  512. data/spec/mongoid/persistence/operations/embedded/remove_spec.rb +0 -8
  513. data/spec/mongoid/persistence/operations/insert_spec.rb +0 -149
  514. data/spec/mongoid/persistence/operations/remove_spec.rb +0 -113
  515. data/spec/mongoid/persistence/operations/update_spec.rb +0 -141
  516. data/spec/mongoid/persistence/operations/upsert_spec.rb +0 -59
  517. data/spec/mongoid/persistence/operations_spec.rb +0 -313
  518. data/spec/mongoid/persistence_spec.rb +0 -2279
  519. data/spec/mongoid/unit_of_work_spec.rb +0 -196
  520. data/spec/mongoid/versioning_spec.rb +0 -540
  521. 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