mongoid 3.1.6 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (562) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +432 -8
  3. data/README.md +5 -6
  4. data/lib/config/locales/en.yml +32 -18
  5. data/lib/mongoid/atomic/paths/embedded/many.rb +1 -1
  6. data/lib/mongoid/atomic/paths/embedded/one.rb +1 -1
  7. data/lib/mongoid/atomic/paths/embedded.rb +0 -30
  8. data/lib/mongoid/atomic/paths/root.rb +0 -13
  9. data/lib/mongoid/atomic.rb +1 -12
  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/attributes.rb +63 -101
  14. data/lib/mongoid/{dirty.rb → changeable.rb} +32 -2
  15. data/lib/mongoid/composable.rb +105 -0
  16. data/lib/mongoid/config/options.rb +1 -1
  17. data/lib/mongoid/config.rb +3 -9
  18. data/lib/mongoid/contextual/aggregable/mongo.rb +7 -9
  19. data/lib/mongoid/contextual/atomic.rb +53 -53
  20. data/lib/mongoid/contextual/geo_near.rb +1 -1
  21. data/lib/mongoid/contextual/map_reduce.rb +4 -2
  22. data/lib/mongoid/contextual/memory.rb +18 -6
  23. data/lib/mongoid/contextual/mongo.rb +64 -56
  24. data/lib/mongoid/contextual/none.rb +90 -0
  25. data/lib/mongoid/contextual/text_search.rb +178 -0
  26. data/lib/mongoid/contextual.rb +2 -0
  27. data/lib/mongoid/copyable.rb +2 -3
  28. data/lib/mongoid/{criterion → criteria}/findable.rb +7 -47
  29. data/lib/mongoid/{criterion/inspection.rb → criteria/inspectable.rb} +2 -2
  30. data/lib/mongoid/{criterion → criteria}/marshalable.rb +3 -1
  31. data/lib/mongoid/{criterion → criteria}/modifiable.rb +28 -8
  32. data/lib/mongoid/criteria/permission.rb +70 -0
  33. data/lib/mongoid/{criterion/scoping.rb → criteria/scopable.rb} +2 -2
  34. data/lib/mongoid/criteria.rb +39 -34
  35. data/lib/mongoid/document.rb +32 -17
  36. data/lib/mongoid/errors/document_not_destroyed.rb +25 -0
  37. data/lib/mongoid/errors/document_not_found.rb +2 -1
  38. data/lib/mongoid/errors/invalid_storage_options.rb +1 -1
  39. data/lib/mongoid/errors/invalid_storage_parent.rb +26 -0
  40. data/lib/mongoid/errors/invalid_value.rb +16 -0
  41. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  42. data/lib/mongoid/errors/readonly_document.rb +24 -0
  43. data/lib/mongoid/errors.rb +4 -1
  44. data/lib/mongoid/extensions/array.rb +3 -3
  45. data/lib/mongoid/extensions/big_decimal.rb +1 -1
  46. data/lib/mongoid/extensions/boolean.rb +15 -17
  47. data/lib/mongoid/extensions/date.rb +1 -1
  48. data/lib/mongoid/extensions/date_time.rb +3 -3
  49. data/lib/mongoid/extensions/float.rb +2 -1
  50. data/lib/mongoid/extensions/hash.rb +3 -3
  51. data/lib/mongoid/extensions/integer.rb +1 -1
  52. data/lib/mongoid/extensions/object.rb +7 -7
  53. data/lib/mongoid/extensions/object_id.rb +5 -5
  54. data/lib/mongoid/extensions/range.rb +9 -3
  55. data/lib/mongoid/extensions/regexp.rb +1 -1
  56. data/lib/mongoid/extensions/set.rb +1 -1
  57. data/lib/mongoid/extensions/string.rb +6 -18
  58. data/lib/mongoid/extensions/symbol.rb +1 -1
  59. data/lib/mongoid/extensions/time.rb +3 -3
  60. data/lib/mongoid/extensions/time_with_zone.rb +1 -1
  61. data/lib/mongoid/extensions.rb +2 -7
  62. data/lib/mongoid/factory.rb +8 -6
  63. data/lib/mongoid/fields/foreign_key.rb +3 -3
  64. data/lib/mongoid/fields/localized.rb +1 -1
  65. data/lib/mongoid/fields/standard.rb +5 -17
  66. data/lib/mongoid/fields/validators/macro.rb +15 -5
  67. data/lib/mongoid/fields.rb +41 -8
  68. data/lib/mongoid/{finders.rb → findable.rb} +8 -2
  69. data/lib/mongoid/indexable/specification.rb +104 -0
  70. data/lib/mongoid/{indexes → indexable}/validators/options.rb +2 -1
  71. data/lib/mongoid/{indexes.rb → indexable.rb} +50 -55
  72. data/lib/mongoid/{inspection.rb → inspectable.rb} +15 -11
  73. data/lib/mongoid/{callbacks.rb → interceptable.rb} +30 -62
  74. data/lib/mongoid/log_subscriber.rb +55 -0
  75. data/lib/mongoid/{matchers → matchable}/all.rb +1 -1
  76. data/lib/mongoid/{matchers → matchable}/and.rb +2 -2
  77. data/lib/mongoid/{matchers → matchable}/default.rb +1 -1
  78. data/lib/mongoid/{matchers → matchable}/exists.rb +1 -1
  79. data/lib/mongoid/{matchers → matchable}/gt.rb +1 -1
  80. data/lib/mongoid/{matchers → matchable}/gte.rb +1 -1
  81. data/lib/mongoid/{matchers → matchable}/in.rb +2 -2
  82. data/lib/mongoid/{matchers → matchable}/lt.rb +1 -1
  83. data/lib/mongoid/{matchers → matchable}/lte.rb +1 -1
  84. data/lib/mongoid/{matchers → matchable}/ne.rb +2 -2
  85. data/lib/mongoid/{matchers → matchable}/nin.rb +3 -2
  86. data/lib/mongoid/{matchers → matchable}/or.rb +2 -2
  87. data/lib/mongoid/{matchers → matchable}/size.rb +1 -1
  88. data/lib/mongoid/matchable.rb +152 -0
  89. data/lib/mongoid/persistable/creatable.rb +188 -0
  90. data/lib/mongoid/persistable/deletable.rb +149 -0
  91. data/lib/mongoid/persistable/destroyable.rb +60 -0
  92. data/lib/mongoid/persistable/incrementable.rb +36 -0
  93. data/lib/mongoid/persistable/logical.rb +38 -0
  94. data/lib/mongoid/persistable/poppable.rb +39 -0
  95. data/lib/mongoid/persistable/pullable.rb +55 -0
  96. data/lib/mongoid/persistable/pushable.rb +62 -0
  97. data/lib/mongoid/persistable/renamable.rb +35 -0
  98. data/lib/mongoid/persistable/savable.rb +52 -0
  99. data/lib/mongoid/persistable/settable.rb +33 -0
  100. data/lib/mongoid/persistable/unsettable.rb +36 -0
  101. data/lib/mongoid/persistable/updatable.rb +152 -0
  102. data/lib/mongoid/persistable/upsertable.rb +55 -0
  103. data/lib/mongoid/persistable.rb +216 -0
  104. data/lib/mongoid/positional.rb +71 -0
  105. data/lib/mongoid/query_cache.rb +247 -0
  106. data/lib/mongoid/railtie.rb +32 -45
  107. data/lib/mongoid/railties/database.rake +9 -25
  108. data/lib/mongoid/relations/accessors.rb +13 -49
  109. data/lib/mongoid/relations/auto_save.rb +15 -36
  110. data/lib/mongoid/relations/binding.rb +1 -24
  111. data/lib/mongoid/relations/bindings/embedded/in.rb +1 -1
  112. data/lib/mongoid/relations/bindings/embedded/many.rb +1 -3
  113. data/lib/mongoid/relations/bindings/referenced/in.rb +3 -8
  114. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +3 -1
  115. data/lib/mongoid/relations/builder.rb +1 -1
  116. data/lib/mongoid/relations/builders/nested_attributes/many.rb +10 -13
  117. data/lib/mongoid/relations/builders/nested_attributes/one.rb +4 -5
  118. data/lib/mongoid/relations/builders/referenced/in.rb +1 -1
  119. data/lib/mongoid/relations/builders/referenced/many.rb +1 -2
  120. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +1 -2
  121. data/lib/mongoid/relations/builders/referenced/one.rb +1 -1
  122. data/lib/mongoid/relations/builders.rb +2 -2
  123. data/lib/mongoid/relations/cascading.rb +3 -5
  124. data/lib/mongoid/relations/constraint.rb +1 -1
  125. data/lib/mongoid/relations/conversions.rb +1 -1
  126. data/lib/mongoid/relations/counter_cache.rb +39 -15
  127. data/lib/mongoid/relations/eager/base.rb +149 -0
  128. data/lib/mongoid/relations/eager/belongs_to.rb +31 -0
  129. data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +47 -0
  130. data/lib/mongoid/relations/eager/has_many.rb +38 -0
  131. data/lib/mongoid/relations/eager/has_one.rb +30 -0
  132. data/lib/mongoid/relations/eager.rb +46 -0
  133. data/lib/mongoid/relations/embedded/batchable.rb +4 -5
  134. data/lib/mongoid/relations/embedded/in.rb +4 -4
  135. data/lib/mongoid/relations/embedded/many.rb +14 -32
  136. data/lib/mongoid/relations/embedded/one.rb +1 -1
  137. data/lib/mongoid/relations/macros.rb +3 -4
  138. data/lib/mongoid/relations/many.rb +30 -31
  139. data/lib/mongoid/relations/marshalable.rb +3 -3
  140. data/lib/mongoid/relations/metadata.rb +14 -79
  141. data/lib/mongoid/relations/nested_builder.rb +2 -2
  142. data/lib/mongoid/relations/options.rb +1 -0
  143. data/lib/mongoid/relations/polymorphic.rb +0 -1
  144. data/lib/mongoid/relations/proxy.rb +21 -41
  145. data/lib/mongoid/relations/referenced/in.rb +4 -20
  146. data/lib/mongoid/relations/referenced/many.rb +19 -32
  147. data/lib/mongoid/relations/referenced/many_to_many.rb +15 -38
  148. data/lib/mongoid/relations/referenced/one.rb +6 -25
  149. data/lib/mongoid/relations/synchronization.rb +3 -3
  150. data/lib/mongoid/relations/touchable.rb +34 -1
  151. data/lib/mongoid/relations.rb +11 -25
  152. data/lib/mongoid/{reloading.rb → reloadable.rb} +6 -4
  153. data/lib/mongoid/{scoping.rb → scopable.rb} +36 -36
  154. data/lib/mongoid/selectable.rb +59 -0
  155. data/lib/mongoid/{serialization.rb → serializable.rb} +11 -2
  156. data/lib/mongoid/sessions/factory.rb +2 -0
  157. data/lib/mongoid/sessions/options.rb +180 -0
  158. data/lib/mongoid/sessions/storage_options.rb +140 -0
  159. data/lib/mongoid/sessions/thread_options.rb +19 -0
  160. data/lib/mongoid/sessions/validators/storage.rb +16 -3
  161. data/lib/mongoid/sessions.rb +37 -345
  162. data/lib/mongoid/{sharding.rb → shardable.rb} +5 -1
  163. data/lib/mongoid/{state.rb → stateful.rb} +13 -1
  164. data/lib/mongoid/support/query_counter.rb +23 -0
  165. data/lib/mongoid/tasks/database.rake +31 -0
  166. data/lib/mongoid/tasks/database.rb +107 -0
  167. data/lib/mongoid/threaded/lifecycle.rb +0 -28
  168. data/lib/mongoid/threaded.rb +0 -157
  169. data/lib/mongoid/timestamps/updated/short.rb +2 -2
  170. data/lib/mongoid/{hierarchy.rb → traversable.rb} +9 -5
  171. data/lib/mongoid/{validations → validatable}/associated.rb +4 -2
  172. data/lib/mongoid/{validations → validatable}/format.rb +1 -1
  173. data/lib/mongoid/{validations → validatable}/length.rb +1 -1
  174. data/lib/mongoid/{validations → validatable}/localizable.rb +1 -1
  175. data/lib/mongoid/{validations → validatable}/macros.rb +4 -3
  176. data/lib/mongoid/{validations → validatable}/presence.rb +1 -1
  177. data/lib/mongoid/{validations → validatable}/queryable.rb +1 -2
  178. data/lib/mongoid/{validations → validatable}/uniqueness.rb +23 -19
  179. data/lib/mongoid/{validations.rb → validatable.rb} +23 -10
  180. data/lib/mongoid/version.rb +1 -1
  181. data/lib/mongoid.rb +10 -76
  182. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +13 -24
  183. data/lib/rails/generators/mongoid/model/model_generator.rb +0 -1
  184. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +0 -3
  185. data/lib/rails/generators/mongoid_generator.rb +3 -40
  186. data/lib/rails/mongoid.rb +0 -122
  187. data/lib/support/ruby_version.rb +1 -1
  188. data/spec/app/models/account.rb +2 -6
  189. data/spec/app/models/acolyte.rb +2 -1
  190. data/spec/app/models/actor.rb +0 -1
  191. data/spec/app/models/address.rb +8 -3
  192. data/spec/app/models/animal.rb +1 -1
  193. data/spec/app/models/appointment.rb +3 -3
  194. data/spec/app/models/article.rb +1 -4
  195. data/spec/app/models/audio.rb +5 -0
  196. data/spec/app/models/author.rb +0 -2
  197. data/spec/app/models/band.rb +3 -2
  198. data/spec/app/models/bar.rb +1 -0
  199. data/spec/app/models/book.rb +1 -0
  200. data/spec/app/models/building.rb +0 -2
  201. data/spec/app/models/building_address.rb +0 -2
  202. data/spec/app/models/bus.rb +1 -1
  203. data/spec/app/models/canvas.rb +1 -1
  204. data/spec/app/models/contractor.rb +0 -2
  205. data/spec/app/models/country_code.rb +1 -1
  206. data/spec/app/models/definition.rb +2 -2
  207. data/spec/app/models/dog.rb +1 -1
  208. data/spec/app/models/draft.rb +9 -0
  209. data/spec/app/models/dragon.rb +4 -0
  210. data/spec/app/models/drug.rb +1 -3
  211. data/spec/app/models/dungeon.rb +4 -0
  212. data/spec/app/models/edit.rb +5 -0
  213. data/spec/app/models/even.rb +7 -0
  214. data/spec/app/models/event.rb +1 -1
  215. data/spec/app/models/filesystem.rb +1 -0
  216. data/spec/app/models/fish.rb +0 -1
  217. data/spec/app/models/fruits.rb +6 -0
  218. data/spec/app/models/game.rb +0 -2
  219. data/spec/app/models/house.rb +1 -3
  220. data/spec/app/models/item.rb +1 -5
  221. data/spec/app/models/jar.rb +1 -1
  222. data/spec/app/models/label.rb +4 -4
  223. data/spec/app/models/line_item.rb +1 -1
  224. data/spec/app/models/login.rb +1 -1
  225. data/spec/app/models/message.rb +8 -0
  226. data/spec/app/models/movie.rb +1 -0
  227. data/spec/app/models/name.rb +3 -3
  228. data/spec/app/models/note.rb +3 -1
  229. data/spec/app/models/odd.rb +7 -0
  230. data/spec/app/models/oscar.rb +1 -1
  231. data/spec/app/models/parent_doc.rb +1 -1
  232. data/spec/app/models/person.rb +16 -10
  233. data/spec/app/models/phone.rb +1 -3
  234. data/spec/app/models/player.rb +3 -3
  235. data/spec/app/models/post.rb +5 -3
  236. data/spec/app/models/preference.rb +1 -1
  237. data/spec/app/models/quiz.rb +0 -3
  238. data/spec/app/models/record.rb +10 -5
  239. data/spec/app/models/registry.rb +1 -1
  240. data/spec/app/models/server.rb +1 -1
  241. data/spec/app/models/service.rb +3 -3
  242. data/spec/app/models/sound.rb +5 -0
  243. data/spec/app/models/symptom.rb +1 -1
  244. data/spec/app/models/template.rb +1 -1
  245. data/spec/app/models/title.rb +0 -1
  246. data/spec/app/models/track.rb +5 -5
  247. data/spec/app/models/tree.rb +3 -3
  248. data/spec/app/models/video.rb +1 -5
  249. data/spec/app/models/wiki_page.rb +2 -5
  250. data/spec/app/models/word.rb +3 -0
  251. data/spec/app/models/word_origin.rb +1 -1
  252. data/spec/config/mongoid.yml +7 -8
  253. data/spec/helpers.rb +18 -0
  254. data/spec/mongoid/atomic/modifiers_spec.rb +22 -22
  255. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +8 -49
  256. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +7 -49
  257. data/spec/mongoid/atomic/paths/root_spec.rb +3 -61
  258. data/spec/mongoid/atomic/paths_spec.rb +19 -19
  259. data/spec/mongoid/atomic_spec.rb +19 -19
  260. data/spec/mongoid/{nested_attributes_spec.rb → attributes/nested_spec.rb} +335 -448
  261. data/spec/mongoid/attributes/readonly_spec.rb +58 -18
  262. data/spec/mongoid/attributes_spec.rb +315 -436
  263. data/spec/mongoid/{dirty_spec.rb → changeable_spec.rb} +203 -153
  264. data/spec/mongoid/{components_spec.rb → composable_spec.rb} +3 -3
  265. data/spec/mongoid/config/environment_spec.rb +3 -3
  266. data/spec/mongoid/config/options_spec.rb +6 -6
  267. data/spec/mongoid/config_spec.rb +24 -48
  268. data/spec/mongoid/contextual/aggregable/memory_spec.rb +12 -12
  269. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +78 -38
  270. data/spec/mongoid/contextual/atomic_spec.rb +68 -58
  271. data/spec/mongoid/contextual/find_and_modify_spec.rb +14 -14
  272. data/spec/mongoid/contextual/geo_near_spec.rb +22 -22
  273. data/spec/mongoid/contextual/map_reduce_spec.rb +27 -27
  274. data/spec/mongoid/contextual/memory_spec.rb +151 -94
  275. data/spec/mongoid/contextual/mongo_spec.rb +238 -150
  276. data/spec/mongoid/contextual/none_spec.rb +127 -0
  277. data/spec/mongoid/contextual/text_search_spec.rb +209 -0
  278. data/spec/mongoid/copyable_spec.rb +56 -68
  279. data/spec/mongoid/criteria/findable_spec.rb +991 -0
  280. data/spec/mongoid/{criterion/inspection_spec.rb → criteria/inspectable_spec.rb} +5 -5
  281. data/spec/mongoid/{criterion → criteria}/marshalable_spec.rb +2 -2
  282. data/spec/mongoid/criteria/modifiable_spec.rb +1255 -0
  283. data/spec/mongoid/{criterion/scoping_spec.rb → criteria/scopable_spec.rb} +37 -37
  284. data/spec/mongoid/criteria_spec.rb +578 -2295
  285. data/spec/mongoid/document_spec.rb +166 -120
  286. data/spec/mongoid/equality_spec.rb +22 -22
  287. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +3 -3
  288. data/spec/mongoid/errors/callback_spec.rb +3 -3
  289. data/spec/mongoid/errors/delete_restriction_spec.rb +3 -3
  290. data/spec/mongoid/errors/document_not_destroyed_spec.rb +33 -0
  291. data/spec/mongoid/errors/document_not_found_spec.rb +11 -11
  292. data/spec/mongoid/errors/eager_load_spec.rb +3 -3
  293. data/spec/mongoid/errors/invalid_collection_spec.rb +3 -3
  294. data/spec/mongoid/errors/invalid_config_option_spec.rb +3 -3
  295. data/spec/mongoid/errors/invalid_field_option_spec.rb +3 -3
  296. data/spec/mongoid/errors/invalid_field_spec.rb +3 -3
  297. data/spec/mongoid/errors/invalid_find_spec.rb +3 -3
  298. data/spec/mongoid/errors/invalid_includes_spec.rb +3 -3
  299. data/spec/mongoid/errors/invalid_index_spec.rb +3 -3
  300. data/spec/mongoid/errors/invalid_options_spec.rb +3 -3
  301. data/spec/mongoid/errors/invalid_path_spec.rb +3 -3
  302. data/spec/mongoid/errors/invalid_scope_spec.rb +5 -5
  303. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +3 -3
  304. data/spec/mongoid/errors/invalid_storage_options_spec.rb +3 -3
  305. data/spec/mongoid/errors/invalid_time_spec.rb +3 -3
  306. data/spec/mongoid/errors/inverse_not_found_spec.rb +3 -3
  307. data/spec/mongoid/errors/mixed_relations_spec.rb +3 -3
  308. data/spec/mongoid/errors/mixed_session_configuration_spec.rb +3 -3
  309. data/spec/mongoid/errors/mongoid_error_spec.rb +8 -8
  310. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +3 -3
  311. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  312. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +3 -3
  313. data/spec/mongoid/errors/no_metadata_spec.rb +3 -3
  314. data/spec/mongoid/errors/no_parent_spec.rb +3 -3
  315. data/spec/mongoid/errors/no_session_config_spec.rb +3 -3
  316. data/spec/mongoid/errors/no_session_database_spec.rb +3 -3
  317. data/spec/mongoid/errors/no_session_hosts_spec.rb +3 -3
  318. data/spec/mongoid/errors/no_sessions_config_spec.rb +3 -3
  319. data/spec/mongoid/errors/readonly_attribute_spec.rb +3 -3
  320. data/spec/mongoid/errors/readonly_document_spec.rb +29 -0
  321. data/spec/mongoid/errors/scope_overwrite_spec.rb +3 -3
  322. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +3 -3
  323. data/spec/mongoid/errors/unknown_attribute_spec.rb +5 -5
  324. data/spec/mongoid/errors/unsaved_document_spec.rb +3 -3
  325. data/spec/mongoid/errors/unsupported_javascript_spec.rb +3 -3
  326. data/spec/mongoid/errors/validations_spec.rb +7 -7
  327. data/spec/mongoid/extensions/array_spec.rb +61 -61
  328. data/spec/mongoid/extensions/big_decimal_spec.rb +11 -11
  329. data/spec/mongoid/extensions/binary_spec.rb +12 -12
  330. data/spec/mongoid/extensions/boolean_spec.rb +18 -18
  331. data/spec/mongoid/extensions/date_spec.rb +13 -13
  332. data/spec/mongoid/extensions/date_time_spec.rb +8 -8
  333. data/spec/mongoid/extensions/false_class_spec.rb +5 -5
  334. data/spec/mongoid/extensions/float_spec.rb +29 -15
  335. data/spec/mongoid/extensions/hash_spec.rb +29 -29
  336. data/spec/mongoid/extensions/integer_spec.rb +15 -15
  337. data/spec/mongoid/extensions/module_spec.rb +2 -2
  338. data/spec/mongoid/extensions/nil_class_spec.rb +1 -1
  339. data/spec/mongoid/extensions/object_id_spec.rb +134 -134
  340. data/spec/mongoid/extensions/object_spec.rb +26 -26
  341. data/spec/mongoid/extensions/range_spec.rb +61 -12
  342. data/spec/mongoid/extensions/regexp_spec.rb +4 -4
  343. data/spec/mongoid/extensions/set_spec.rb +4 -4
  344. data/spec/mongoid/extensions/string_spec.rb +35 -46
  345. data/spec/mongoid/extensions/symbol_spec.rb +9 -9
  346. data/spec/mongoid/extensions/time_spec.rb +49 -49
  347. data/spec/mongoid/extensions/time_with_zone_spec.rb +34 -34
  348. data/spec/mongoid/extensions/true_class_spec.rb +5 -5
  349. data/spec/mongoid/extensions_spec.rb +15 -0
  350. data/spec/mongoid/factory_spec.rb +15 -15
  351. data/spec/mongoid/fields/foreign_key_spec.rb +73 -66
  352. data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +15 -15
  353. data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +22 -22
  354. data/spec/mongoid/fields/localized_spec.rb +38 -23
  355. data/spec/mongoid/fields/standard_spec.rb +12 -12
  356. data/spec/mongoid/fields_spec.rb +263 -217
  357. data/spec/mongoid/{finders_spec.rb → findable_spec.rb} +127 -27
  358. data/spec/mongoid/indexable/specification_spec.rb +102 -0
  359. data/spec/mongoid/{indexes_spec.rb → indexable_spec.rb} +171 -51
  360. data/spec/mongoid/{inspection_spec.rb → inspectable_spec.rb} +6 -14
  361. data/spec/mongoid/{callbacks_spec.rb → interceptable_spec.rb} +117 -116
  362. data/spec/mongoid/log_subscriber_spec.rb +75 -0
  363. data/spec/mongoid/loggable_spec.rb +1 -1
  364. data/spec/mongoid/{matchers → matchable}/all_spec.rb +4 -4
  365. data/spec/mongoid/{matchers → matchable}/and_spec.rb +11 -11
  366. data/spec/mongoid/{matchers → matchable}/default_spec.rb +15 -15
  367. data/spec/mongoid/{matchers → matchable}/exists_spec.rb +5 -5
  368. data/spec/mongoid/{matchers → matchable}/gt_spec.rb +9 -8
  369. data/spec/mongoid/{matchers → matchable}/gte_spec.rb +7 -7
  370. data/spec/mongoid/matchable/in_spec.rb +49 -0
  371. data/spec/mongoid/{matchers → matchable}/lt_spec.rb +7 -7
  372. data/spec/mongoid/{matchers → matchable}/lte_spec.rb +7 -7
  373. data/spec/mongoid/matchable/ne_spec.rb +46 -0
  374. data/spec/mongoid/matchable/nin_spec.rb +48 -0
  375. data/spec/mongoid/{matchers → matchable}/or_spec.rb +6 -6
  376. data/spec/mongoid/{matchers → matchable}/size_spec.rb +3 -3
  377. data/spec/mongoid/{matchers_spec.rb → matchable_spec.rb} +41 -41
  378. data/spec/mongoid/persistable/creatable_spec.rb +512 -0
  379. data/spec/mongoid/persistable/deletable_spec.rb +218 -0
  380. data/spec/mongoid/persistable/destroyable_spec.rb +192 -0
  381. data/spec/mongoid/persistable/incrementable_spec.rb +173 -0
  382. data/spec/mongoid/persistable/logical_spec.rb +143 -0
  383. data/spec/mongoid/persistable/poppable_spec.rb +115 -0
  384. data/spec/mongoid/persistable/pullable_spec.rb +228 -0
  385. data/spec/mongoid/persistable/pushable_spec.rb +258 -0
  386. data/spec/mongoid/persistable/renamable_spec.rb +135 -0
  387. data/spec/mongoid/persistable/savable_spec.rb +461 -0
  388. data/spec/mongoid/persistable/settable_spec.rb +139 -0
  389. data/spec/mongoid/persistable/unsettable_spec.rb +155 -0
  390. data/spec/mongoid/persistable/updatable_spec.rb +558 -0
  391. data/spec/mongoid/persistable/upsertable_spec.rb +106 -0
  392. data/spec/mongoid/persistable_spec.rb +206 -0
  393. data/spec/mongoid/{atomic/positionable_spec.rb → positional_spec.rb} +9 -9
  394. data/spec/mongoid/query_cache_spec.rb +231 -0
  395. data/spec/mongoid/railties/document_spec.rb +2 -2
  396. data/spec/mongoid/relations/accessors_spec.rb +53 -145
  397. data/spec/mongoid/relations/auto_save_spec.rb +37 -17
  398. data/spec/mongoid/relations/bindings/embedded/in_spec.rb +12 -12
  399. data/spec/mongoid/relations/bindings/embedded/many_spec.rb +3 -3
  400. data/spec/mongoid/relations/bindings/embedded/one_spec.rb +5 -5
  401. data/spec/mongoid/relations/bindings/referenced/in_spec.rb +26 -26
  402. data/spec/mongoid/relations/bindings/referenced/many_spec.rb +10 -10
  403. data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +19 -19
  404. data/spec/mongoid/relations/bindings/referenced/one_spec.rb +12 -12
  405. data/spec/mongoid/relations/builders/embedded/in_spec.rb +4 -4
  406. data/spec/mongoid/relations/builders/embedded/many_spec.rb +18 -18
  407. data/spec/mongoid/relations/builders/embedded/one_spec.rb +11 -11
  408. data/spec/mongoid/relations/builders/nested_attributes/many_spec.rb +12 -13
  409. data/spec/mongoid/relations/builders/nested_attributes/one_spec.rb +14 -14
  410. data/spec/mongoid/relations/builders/referenced/in_spec.rb +24 -35
  411. data/spec/mongoid/relations/builders/referenced/many_spec.rb +15 -15
  412. data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +18 -18
  413. data/spec/mongoid/relations/builders/referenced/one_spec.rb +12 -25
  414. data/spec/mongoid/relations/builders_spec.rb +21 -21
  415. data/spec/mongoid/relations/cascading/delete_spec.rb +9 -9
  416. data/spec/mongoid/relations/cascading/destroy_spec.rb +6 -6
  417. data/spec/mongoid/relations/cascading/nullify_spec.rb +4 -4
  418. data/spec/mongoid/relations/cascading/restrict_spec.rb +7 -7
  419. data/spec/mongoid/relations/cascading_spec.rb +16 -16
  420. data/spec/mongoid/relations/constraint_spec.rb +8 -7
  421. data/spec/mongoid/relations/conversions_spec.rb +16 -14
  422. data/spec/mongoid/relations/counter_cache_spec.rb +85 -0
  423. data/spec/mongoid/relations/cyclic_spec.rb +18 -18
  424. data/spec/mongoid/relations/eager/belongs_to_spec.rb +154 -0
  425. data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +117 -0
  426. data/spec/mongoid/relations/eager/has_many_spec.rb +207 -0
  427. data/spec/mongoid/relations/eager/has_one_spec.rb +163 -0
  428. data/spec/mongoid/relations/eager_spec.rb +228 -0
  429. data/spec/mongoid/relations/embedded/dirty_spec.rb +8 -8
  430. data/spec/mongoid/relations/embedded/in_spec.rb +56 -57
  431. data/spec/mongoid/relations/embedded/many_spec.rb +393 -372
  432. data/spec/mongoid/relations/embedded/one_spec.rb +108 -141
  433. data/spec/mongoid/relations/macros_spec.rb +108 -102
  434. data/spec/mongoid/relations/metadata_spec.rb +180 -255
  435. data/spec/mongoid/relations/options_spec.rb +1 -1
  436. data/spec/mongoid/relations/polymorphic_spec.rb +13 -17
  437. data/spec/mongoid/relations/proxy_spec.rb +2 -2
  438. data/spec/mongoid/relations/referenced/in_spec.rb +128 -303
  439. data/spec/mongoid/relations/referenced/many_spec.rb +434 -527
  440. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +352 -424
  441. data/spec/mongoid/relations/referenced/one_spec.rb +149 -264
  442. data/spec/mongoid/relations/reflections_spec.rb +6 -6
  443. data/spec/mongoid/relations/synchronization_spec.rb +46 -50
  444. data/spec/mongoid/relations/targets/enumerable_spec.rb +118 -118
  445. data/spec/mongoid/relations/touchable_spec.rb +333 -0
  446. data/spec/mongoid/relations_spec.rb +16 -15
  447. data/spec/mongoid/{reloading_spec.rb → reloadable_spec.rb} +20 -60
  448. data/spec/mongoid/{scoping_spec.rb → scopable_spec.rb} +89 -164
  449. data/spec/mongoid/selectable_spec.rb +134 -0
  450. data/spec/mongoid/{serialization_spec.rb → serializable_spec.rb} +129 -82
  451. data/spec/mongoid/sessions/factory_spec.rb +49 -28
  452. data/spec/mongoid/sessions/mongo_uri_spec.rb +7 -7
  453. data/spec/mongoid/sessions/options_spec.rb +107 -0
  454. data/spec/mongoid/sessions_spec.rb +289 -178
  455. data/spec/mongoid/{sharding_spec.rb → shardable_spec.rb} +8 -8
  456. data/spec/mongoid/{state_spec.rb → stateful_spec.rb} +36 -11
  457. data/spec/mongoid/tasks/database_rake_spec.rb +285 -0
  458. data/spec/mongoid/tasks/database_spec.rb +160 -0
  459. data/spec/mongoid/threaded_spec.rb +17 -70
  460. data/spec/mongoid/timestamps/created/short_spec.rb +6 -6
  461. data/spec/mongoid/timestamps/created_spec.rb +5 -5
  462. data/spec/mongoid/timestamps/timeless_spec.rb +6 -6
  463. data/spec/mongoid/timestamps/updated/short_spec.rb +11 -11
  464. data/spec/mongoid/timestamps/updated_spec.rb +9 -13
  465. data/spec/mongoid/timestamps_spec.rb +9 -13
  466. data/spec/mongoid/{hierarchy_spec.rb → traversable_spec.rb} +19 -19
  467. data/spec/mongoid/{validations → validatable}/associated_spec.rb +45 -22
  468. data/spec/mongoid/{validations → validatable}/format_spec.rb +6 -6
  469. data/spec/mongoid/{validations → validatable}/length_spec.rb +14 -14
  470. data/spec/mongoid/{validations → validatable}/numericality_spec.rb +1 -1
  471. data/spec/mongoid/{validations → validatable}/presence_spec.rb +37 -44
  472. data/spec/mongoid/{validations → validatable}/uniqueness_spec.rb +184 -192
  473. data/spec/mongoid/{validations_spec.rb → validatable_spec.rb} +28 -28
  474. data/spec/mongoid_spec.rb +8 -8
  475. data/spec/rails/mongoid_spec.rb +19 -335
  476. data/spec/spec_helper.rb +29 -13
  477. metadata +296 -283
  478. data/lib/mongoid/atomic/positionable.rb +0 -73
  479. data/lib/mongoid/components.rb +0 -92
  480. data/lib/mongoid/config/inflections.rb +0 -6
  481. data/lib/mongoid/contextual/eager.rb +0 -158
  482. data/lib/mongoid/errors/versioning_not_on_root.rb +0 -23
  483. data/lib/mongoid/identity_map.rb +0 -163
  484. data/lib/mongoid/json.rb +0 -16
  485. data/lib/mongoid/matchers/strategies.rb +0 -97
  486. data/lib/mongoid/matchers.rb +0 -32
  487. data/lib/mongoid/multi_parameter_attributes.rb +0 -105
  488. data/lib/mongoid/nested_attributes.rb +0 -78
  489. data/lib/mongoid/observer.rb +0 -192
  490. data/lib/mongoid/paranoia.rb +0 -136
  491. data/lib/mongoid/persistence/atomic/add_to_set.rb +0 -47
  492. data/lib/mongoid/persistence/atomic/bit.rb +0 -35
  493. data/lib/mongoid/persistence/atomic/inc.rb +0 -45
  494. data/lib/mongoid/persistence/atomic/operation.rb +0 -154
  495. data/lib/mongoid/persistence/atomic/pop.rb +0 -32
  496. data/lib/mongoid/persistence/atomic/pull.rb +0 -32
  497. data/lib/mongoid/persistence/atomic/pull_all.rb +0 -32
  498. data/lib/mongoid/persistence/atomic/push.rb +0 -25
  499. data/lib/mongoid/persistence/atomic/push_all.rb +0 -25
  500. data/lib/mongoid/persistence/atomic/rename.rb +0 -30
  501. data/lib/mongoid/persistence/atomic/sets.rb +0 -28
  502. data/lib/mongoid/persistence/atomic/unset.rb +0 -27
  503. data/lib/mongoid/persistence/atomic.rb +0 -231
  504. data/lib/mongoid/persistence/deletion.rb +0 -31
  505. data/lib/mongoid/persistence/insertion.rb +0 -38
  506. data/lib/mongoid/persistence/modification.rb +0 -35
  507. data/lib/mongoid/persistence/operations/embedded/insert.rb +0 -46
  508. data/lib/mongoid/persistence/operations/embedded/remove.rb +0 -43
  509. data/lib/mongoid/persistence/operations/insert.rb +0 -34
  510. data/lib/mongoid/persistence/operations/remove.rb +0 -33
  511. data/lib/mongoid/persistence/operations/update.rb +0 -59
  512. data/lib/mongoid/persistence/operations/upsert.rb +0 -28
  513. data/lib/mongoid/persistence/operations.rb +0 -214
  514. data/lib/mongoid/persistence/upsertion.rb +0 -31
  515. data/lib/mongoid/persistence.rb +0 -357
  516. data/lib/mongoid/unit_of_work.rb +0 -61
  517. data/lib/mongoid/versioning.rb +0 -217
  518. data/lib/rack/mongoid/middleware/identity_map.rb +0 -39
  519. data/lib/rack/mongoid.rb +0 -2
  520. data/lib/rails/generators/mongoid/observer/observer_generator.rb +0 -17
  521. data/lib/rails/generators/mongoid/observer/templates/observer.rb.tt +0 -4
  522. data/spec/app/models/actor_observer.rb +0 -15
  523. data/spec/app/models/callback_recorder.rb +0 -25
  524. data/spec/app/models/paranoid_phone.rb +0 -25
  525. data/spec/app/models/paranoid_post.rb +0 -36
  526. data/spec/app/models/phone_observer.rb +0 -6
  527. data/spec/mongoid/attributes/processing_spec.rb +0 -149
  528. data/spec/mongoid/criterion/destructive_spec.rb +0 -101
  529. data/spec/mongoid/criterion/modifiable_spec.rb +0 -409
  530. data/spec/mongoid/criterion/modification_spec.rb +0 -402
  531. data/spec/mongoid/errors/versioning_not_on_root_spec.rb +0 -29
  532. data/spec/mongoid/identity_map_spec.rb +0 -564
  533. data/spec/mongoid/json_spec.rb +0 -33
  534. data/spec/mongoid/matchers/in_spec.rb +0 -25
  535. data/spec/mongoid/matchers/ne_spec.rb +0 -25
  536. data/spec/mongoid/matchers/nin_spec.rb +0 -25
  537. data/spec/mongoid/multi_parameter_attributes_spec.rb +0 -128
  538. data/spec/mongoid/observer_spec.rb +0 -290
  539. data/spec/mongoid/paranoia_spec.rb +0 -759
  540. data/spec/mongoid/persistence/atomic/add_to_set_spec.rb +0 -262
  541. data/spec/mongoid/persistence/atomic/bit_spec.rb +0 -88
  542. data/spec/mongoid/persistence/atomic/inc_spec.rb +0 -133
  543. data/spec/mongoid/persistence/atomic/pop_spec.rb +0 -111
  544. data/spec/mongoid/persistence/atomic/pull_all_spec.rb +0 -77
  545. data/spec/mongoid/persistence/atomic/pull_spec.rb +0 -80
  546. data/spec/mongoid/persistence/atomic/push_all_spec.rb +0 -77
  547. data/spec/mongoid/persistence/atomic/push_spec.rb +0 -77
  548. data/spec/mongoid/persistence/atomic/rename_spec.rb +0 -42
  549. data/spec/mongoid/persistence/atomic/sets_spec.rb +0 -154
  550. data/spec/mongoid/persistence/atomic/unset_spec.rb +0 -65
  551. data/spec/mongoid/persistence/atomic_spec.rb +0 -216
  552. data/spec/mongoid/persistence/operations/embedded/insert_spec.rb +0 -191
  553. data/spec/mongoid/persistence/operations/embedded/remove_spec.rb +0 -8
  554. data/spec/mongoid/persistence/operations/insert_spec.rb +0 -149
  555. data/spec/mongoid/persistence/operations/remove_spec.rb +0 -113
  556. data/spec/mongoid/persistence/operations/update_spec.rb +0 -141
  557. data/spec/mongoid/persistence/operations/upsert_spec.rb +0 -59
  558. data/spec/mongoid/persistence/operations_spec.rb +0 -313
  559. data/spec/mongoid/persistence_spec.rb +0 -2279
  560. data/spec/mongoid/unit_of_work_spec.rb +0 -196
  561. data/spec/mongoid/versioning_spec.rb +0 -540
  562. data/spec/rack/mongoid/middleware/identity_map_spec.rb +0 -72
@@ -0,0 +1,512 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Persistable::Creatable 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
+ expect(people.first.title).to eq("sir")
17
+ end
18
+
19
+ it "persists the first document" do
20
+ expect(people.first).to be_persisted
21
+ end
22
+
23
+ it "creates the second document" do
24
+ expect(people.last.title).to eq("madam")
25
+ end
26
+
27
+ it "persists the second document" do
28
+ expect(people.last).to 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
+ expect(people.first.title).to eq("sir")
42
+ end
43
+
44
+ it "persists the first document" do
45
+ expect(people.first).to be_persisted
46
+ end
47
+
48
+ it "passes the block to the first document" do
49
+ expect(people.first.age).to eq(36)
50
+ end
51
+
52
+ it "creates the second document" do
53
+ expect(people.last.title).to eq("madam")
54
+ end
55
+
56
+ it "persists the second document" do
57
+ expect(people.last).to be_persisted
58
+ end
59
+
60
+ it "passes the block to the second document" do
61
+ expect(people.last.age).to 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
+ expect(person).to be_persisted
74
+ end
75
+
76
+ it "returns the document" do
77
+ expect(person).to 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
+ expect(address).to 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
+ expect(document.keys).to_not include("addresses")
117
+ end
118
+
119
+ it "should persist on user_addesses key on User document" do
120
+ expect(document.keys).to 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
+ expect(person.ssn).to eq("666-66-6666")
135
+ end
136
+
137
+ it "persists the document" do
138
+ expect(person).to be_persisted
139
+ end
140
+ end
141
+
142
+ context "when the document is a subclass of a root class" do
143
+
144
+ let!(:browser) do
145
+ Browser.create(version: 3, name: "Test")
146
+ end
147
+
148
+ let(:collection) do
149
+ Canvas.collection
150
+ end
151
+
152
+ let(:attributes) do
153
+ collection.find({ name: "Test"}).first
154
+ end
155
+
156
+ it "persists the versions" do
157
+ expect(attributes["version"]).to eq(3)
158
+ end
159
+
160
+ it "persists the type" do
161
+ expect(attributes["_type"]).to eq("Browser")
162
+ end
163
+
164
+ it "persists the attributes" do
165
+ expect(attributes["name"]).to eq("Test")
166
+ end
167
+ end
168
+
169
+ context "when the document is a subclass of a subclass" do
170
+
171
+ let!(:firefox) do
172
+ Firefox.create(version: 2, name: "Testy")
173
+ end
174
+
175
+ let(:collection) do
176
+ Canvas.collection
177
+ end
178
+
179
+ let(:attributes) do
180
+ collection.find({ name: "Testy"}).first
181
+ end
182
+
183
+ before do
184
+ Browser.create(name: 'Safari', version: '4.0.0')
185
+ end
186
+
187
+ it "persists the versions" do
188
+ expect(attributes["version"]).to eq(2)
189
+ end
190
+
191
+ it "persists the type" do
192
+ expect(attributes["_type"]).to eq("Firefox")
193
+ end
194
+
195
+ it "persists the attributes" do
196
+ expect(attributes["name"]).to eq("Testy")
197
+ end
198
+
199
+ it "returns the document when querying for superclass" do
200
+ expect(Browser.where(name: "Testy").first).to eq(firefox)
201
+ end
202
+
203
+ it "returns the document when querying for root class" do
204
+ expect(Canvas.where(name: "Testy").first).to eq(firefox)
205
+ end
206
+
207
+ it "returnss on of this subclasses if you find by _type" do
208
+ expect(Canvas.where(:_type.in => ['Firefox']).count).to eq(1)
209
+ end
210
+ end
211
+
212
+ context "when the document is subclassed" do
213
+
214
+ let!(:firefox) do
215
+ Firefox.create(name: "firefox")
216
+ end
217
+
218
+ it "finds the document with String args" do
219
+ expect(Firefox.find(firefox.id.to_s)).to eq(firefox)
220
+ end
221
+
222
+ context "when querying for parent documents" do
223
+
224
+ let(:canvas) do
225
+ Canvas.where(name: "firefox").first
226
+ end
227
+
228
+ it "returns matching subclasses" do
229
+ expect(canvas).to eq(firefox)
230
+ end
231
+ end
232
+ end
233
+
234
+ context "when document is a subclass and its parent is an embedded document" do
235
+
236
+ let!(:canvas) do
237
+ Canvas.create(name: "canvas")
238
+ end
239
+
240
+ before do
241
+ canvas.create_palette
242
+ canvas.palette.tools << Pencil.new
243
+ canvas.palette.tools << Eraser.new
244
+ end
245
+
246
+ let(:from_db) do
247
+ Canvas.find(canvas.id)
248
+ end
249
+
250
+ it "properly saves the subclasses" do
251
+ expect(from_db.palette.tools.map(&:class)).to eq([Pencil, Eraser])
252
+ end
253
+ end
254
+
255
+ context "when creating references_many documents from a parent association" do
256
+
257
+ let!(:container) do
258
+ ShippingContainer.create
259
+ end
260
+
261
+ let(:driver) do
262
+ Driver.create
263
+ end
264
+
265
+ it "does not bleed relations from one subclass to another" do
266
+ expect(Truck.relations.keys).to eq(%w/ shipping_container driver bed /)
267
+ expect(Car.relations.keys).to eq(%w/ shipping_container driver /)
268
+ end
269
+
270
+ context "when appending new documents" do
271
+
272
+ before do
273
+ container.vehicles << Car.new
274
+ container.vehicles << Truck.new
275
+ end
276
+
277
+ it "allows STI from << using model.new" do
278
+ expect(container.vehicles.map(&:class)).to eq([ Car, Truck ])
279
+ end
280
+ end
281
+
282
+ context "when appending persisted documents" do
283
+
284
+ before do
285
+ container.vehicles << Car.create
286
+ container.vehicles << Truck.create
287
+ end
288
+
289
+ it "allows STI from << using model.create" do
290
+ expect(container.vehicles.map(&:class)).to eq([ Car, Truck ])
291
+ end
292
+ end
293
+
294
+ context "when building related documents" do
295
+
296
+ before do
297
+ container.vehicles.build({}, Car).save
298
+ container.vehicles.build({}, Truck).save
299
+ end
300
+
301
+ it "allows STI from the build call" do
302
+ expect(container.vehicles.map(&:class)).to eq([ Car, Truck ])
303
+ end
304
+ end
305
+
306
+ context "when building with a type attribute" do
307
+
308
+ before do
309
+ container.vehicles.build({ "_type" => "Car" })
310
+ container.vehicles.build({ "_type" => "Truck" })
311
+ end
312
+
313
+ it "respects the _type attribute from the build call" do
314
+ expect(container.vehicles.map(&:class)).to eq([ Car, Truck ])
315
+ end
316
+ end
317
+
318
+ context "when creating related documents" do
319
+
320
+ before do
321
+ container.vehicles.create({}, Car)
322
+ container.vehicles.create({}, Truck)
323
+ end
324
+
325
+ it "allows STI from the create call" do
326
+ expect(container.vehicles.map(&:class)).to eq([ Car, Truck ])
327
+ end
328
+ end
329
+
330
+ context "when creating with a type attribute" do
331
+
332
+ before do
333
+ container.vehicles.create({ "_type" => "Car" })
334
+ container.vehicles.create({ "_type" => "Truck" })
335
+ end
336
+
337
+ it "respects the _type attribute from the create call" do
338
+ expect(container.vehicles.map(&:class)).to eq([ Car, Truck ])
339
+ end
340
+ end
341
+
342
+ context "#find_or_initialize_by" do
343
+
344
+ before do
345
+ container.vehicles.find_or_initialize_by({ driver_id: driver.id }, Car)
346
+ end
347
+
348
+ it "initializes the given type document" do
349
+ expect(container.vehicles.map(&:class)).to eq([ Car ])
350
+ end
351
+
352
+ it "initializes with the given attributes" do
353
+ expect(container.vehicles.map(&:driver)).to eq([ driver ])
354
+ end
355
+ end
356
+
357
+ context "#find_or_create_by" do
358
+
359
+ before do
360
+ container.vehicles.find_or_create_by({ driver_id: driver.id }, Car)
361
+ end
362
+
363
+ it "creates the given type document" do
364
+ expect(container.vehicles.map(&:class)).to eq([ Car ])
365
+ end
366
+
367
+ it "creates with the given attributes" do
368
+ expect(container.vehicles.map(&:driver)).to eq([ driver ])
369
+ end
370
+
371
+ it "creates the correct number of documents" do
372
+ expect(container.vehicles.size).to eq(1)
373
+ end
374
+
375
+ context "when executing with a found document" do
376
+
377
+ before do
378
+ container.vehicles.find_or_create_by({ driver_id: driver.id }, Car)
379
+ end
380
+
381
+ it "does not create an additional document" do
382
+ expect(container.vehicles.size).to eq(1)
383
+ end
384
+ end
385
+
386
+ context "when executing with an additional new document" do
387
+
388
+ before do
389
+ container.vehicles.find_or_create_by({ driver_id: driver.id }, Truck)
390
+ end
391
+
392
+ it "creates the new additional document" do
393
+ expect(container.vehicles.size).to eq(2)
394
+ end
395
+ end
396
+ end
397
+ end
398
+ end
399
+
400
+ describe ".create!" do
401
+
402
+ context "when provided an array of attributes" do
403
+
404
+ context "when no block is passed" do
405
+
406
+ let(:people) do
407
+ Person.create!([{ title: "sir" }, { title: "madam" }])
408
+ end
409
+
410
+ it "creates the first document" do
411
+ expect(people.first.title).to eq("sir")
412
+ end
413
+
414
+ it "persists the first document" do
415
+ expect(people.first).to be_persisted
416
+ end
417
+
418
+ it "creates the second document" do
419
+ expect(people.last.title).to eq("madam")
420
+ end
421
+
422
+ it "persists the second document" do
423
+ expect(people.last).to be_persisted
424
+ end
425
+ end
426
+
427
+ context "when no block is passed" do
428
+
429
+ let(:people) do
430
+ Person.create!([{ title: "sir" }, { title: "madam" }]) do |person|
431
+ person.age = 36
432
+ end
433
+ end
434
+
435
+ it "creates the first document" do
436
+ expect(people.first.title).to eq("sir")
437
+ end
438
+
439
+ it "persists the first document" do
440
+ expect(people.first).to be_persisted
441
+ end
442
+
443
+ it "passes the block to the first document" do
444
+ expect(people.first.age).to eq(36)
445
+ end
446
+
447
+ it "creates the second document" do
448
+ expect(people.last.title).to eq("madam")
449
+ end
450
+
451
+ it "persists the second document" do
452
+ expect(people.last).to be_persisted
453
+ end
454
+
455
+ it "passes the block to the second document" do
456
+ expect(people.last.age).to eq(36)
457
+ end
458
+ end
459
+ end
460
+
461
+ context "inserting with a field that is not unique" do
462
+
463
+ context "when a unique index exists" do
464
+
465
+ before do
466
+ Person.create_indexes
467
+ end
468
+
469
+ it "raises an error" do
470
+ expect {
471
+ 4.times { Person.create!(ssn: "555-55-1029") }
472
+ }.to raise_error
473
+ end
474
+ end
475
+ end
476
+
477
+ context "when passing in a block" do
478
+
479
+ let(:person) do
480
+ Person.create! do |peep|
481
+ peep.ssn = "666-66-6666"
482
+ end
483
+ end
484
+
485
+ it "sets the attributes" do
486
+ expect(person.ssn).to eq("666-66-6666")
487
+ end
488
+
489
+ it "persists the document" do
490
+ expect(person).to be_persisted
491
+ end
492
+ end
493
+
494
+ context "when setting the composite key" do
495
+
496
+ let(:account) do
497
+ Account.create!(name: "Hello")
498
+ end
499
+
500
+ it "saves the document" do
501
+ expect(account).to be_persisted
502
+ end
503
+ end
504
+
505
+ context "when a callback returns false" do
506
+
507
+ it "raises a callback error" do
508
+ expect { Oscar.create! }.to raise_error(Mongoid::Errors::Callback)
509
+ end
510
+ end
511
+ end
512
+ end
@@ -0,0 +1,218 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Persistable::Deletable do
4
+
5
+ describe "#delete" do
6
+
7
+ let!(:person) do
8
+ Person.create
9
+ end
10
+
11
+ context "when deleting a readonly document" do
12
+
13
+ let(:from_db) do
14
+ Person.only(:_id).first
15
+ end
16
+
17
+ it "raises an error" do
18
+ expect {
19
+ from_db.delete
20
+ }.to raise_error(Mongoid::Errors::ReadonlyDocument)
21
+ end
22
+ end
23
+
24
+ context "when removing a root document" do
25
+
26
+ let!(:deleted) do
27
+ person.delete
28
+ end
29
+
30
+ it "deletes the document from the collection" do
31
+ expect {
32
+ Person.find(person.id)
33
+ }.to raise_error
34
+ end
35
+
36
+ it "returns true" do
37
+ expect(deleted).to be true
38
+ end
39
+
40
+ it "resets the flagged for destroy flag" do
41
+ expect(person).to_not be_flagged_for_destroy
42
+ end
43
+ end
44
+
45
+ context "when removing an embedded document" do
46
+
47
+ let(:address) do
48
+ person.addresses.build(street: "Bond Street")
49
+ end
50
+
51
+ context "when the document is not yet saved" do
52
+
53
+ before do
54
+ address.delete
55
+ end
56
+
57
+ it "removes the document from the parent" do
58
+ expect(person.addresses).to be_empty
59
+ end
60
+
61
+ it "removes the attributes from the parent" do
62
+ expect(person.raw_attributes["addresses"]).to be_nil
63
+ end
64
+
65
+ it "resets the flagged for destroy flag" do
66
+ expect(address).to_not be_flagged_for_destroy
67
+ end
68
+ end
69
+
70
+ context "when the document has been saved" do
71
+
72
+ before do
73
+ address.save
74
+ address.delete
75
+ end
76
+
77
+ let(:from_db) do
78
+ Person.find(person.id)
79
+ end
80
+
81
+ it "removes the object from the parent and database" do
82
+ expect(from_db.addresses).to be_empty
83
+ end
84
+ end
85
+ end
86
+
87
+ context "when removing deeply embedded documents" do
88
+
89
+ context "when the document has been saved" do
90
+
91
+ let(:address) do
92
+ person.addresses.create(street: "Bond Street")
93
+ end
94
+
95
+ let(:location) do
96
+ address.locations.create(name: "Home")
97
+ end
98
+
99
+ let(:from_db) do
100
+ Person.find(person.id)
101
+ end
102
+
103
+ before do
104
+ location.delete
105
+ end
106
+
107
+ it "removes the object from the parent and database" do
108
+ expect(from_db.addresses.first.locations).to be_empty
109
+ end
110
+
111
+ it "resets the flagged for destroy flag" do
112
+ expect(location).to_not be_flagged_for_destroy
113
+ end
114
+ end
115
+ end
116
+
117
+ context "when deleting subclasses" do
118
+
119
+ let!(:firefox) do
120
+ Firefox.create(name: "firefox")
121
+ end
122
+
123
+ let!(:firefox2) do
124
+ Firefox.create(name: "firefox 2")
125
+ end
126
+
127
+ let!(:browser) do
128
+ Browser.create(name: "browser")
129
+ end
130
+
131
+ let!(:canvas) do
132
+ Canvas.create(name: "canvas")
133
+ end
134
+
135
+ context "when deleting a single document" do
136
+
137
+ before do
138
+ firefox.delete
139
+ end
140
+
141
+ it "deletes from the parent class collection" do
142
+ expect(Canvas.count).to eq(3)
143
+ end
144
+
145
+ it "returns correct counts for child classes" do
146
+ expect(Firefox.count).to eq(1)
147
+ end
148
+
149
+ it "returns correct counts for root subclasses" do
150
+ expect(Browser.count).to eq(2)
151
+ end
152
+ end
153
+
154
+ context "when deleting all documents" do
155
+
156
+ before do
157
+ Firefox.delete_all
158
+ end
159
+
160
+ it "deletes from the parent class collection" do
161
+ expect(Canvas.count).to eq(2)
162
+ end
163
+
164
+ it "returns correct counts for child classes" do
165
+ expect(Firefox.count).to eq(0)
166
+ end
167
+
168
+ it "returns correct counts for root subclasses" do
169
+ expect(Browser.count).to eq(1)
170
+ end
171
+ end
172
+ end
173
+ end
174
+
175
+ describe "#delete_all" do
176
+
177
+ let!(:person) do
178
+ Person.create(title: "sir")
179
+ end
180
+
181
+ context "when no conditions are provided" do
182
+
183
+ let!(:removed) do
184
+ Person.delete_all
185
+ end
186
+
187
+ it "removes all the documents" do
188
+ expect(Person.count).to eq(0)
189
+ end
190
+
191
+ it "returns the number of documents removed" do
192
+ expect(removed).to eq(1)
193
+ end
194
+ end
195
+
196
+ context "when conditions are provided" do
197
+
198
+ let!(:person_two) do
199
+ Person.create
200
+ end
201
+
202
+ context "when no conditions attribute provided" do
203
+
204
+ let!(:removed) do
205
+ Person.delete_all(title: "sir")
206
+ end
207
+
208
+ it "removes the matching documents" do
209
+ expect(Person.count).to eq(1)
210
+ end
211
+
212
+ it "returns the number of documents removed" do
213
+ expect(removed).to eq(1)
214
+ end
215
+ end
216
+ end
217
+ end
218
+ end