mongoid 3.1.6 → 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (571) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +479 -8
  3. data/README.md +10 -7
  4. data/lib/config/locales/en.yml +34 -20
  5. data/lib/mongoid.rb +10 -76
  6. data/lib/mongoid/atomic.rb +3 -14
  7. data/lib/mongoid/atomic/paths/embedded.rb +0 -30
  8. data/lib/mongoid/atomic/paths/embedded/many.rb +1 -1
  9. data/lib/mongoid/atomic/paths/embedded/one.rb +1 -1
  10. data/lib/mongoid/atomic/paths/root.rb +0 -13
  11. data/lib/mongoid/attributes.rb +65 -101
  12. data/lib/mongoid/attributes/dynamic.rb +154 -0
  13. data/lib/mongoid/attributes/nested.rb +82 -0
  14. data/lib/mongoid/attributes/processing.rb +13 -66
  15. data/lib/mongoid/{dirty.rb → changeable.rb} +32 -2
  16. data/lib/mongoid/composable.rb +105 -0
  17. data/lib/mongoid/config.rb +3 -9
  18. data/lib/mongoid/config/options.rb +1 -1
  19. data/lib/mongoid/contextual.rb +2 -0
  20. data/lib/mongoid/contextual/aggregable/memory.rb +2 -2
  21. data/lib/mongoid/contextual/aggregable/mongo.rb +7 -9
  22. data/lib/mongoid/contextual/atomic.rb +53 -53
  23. data/lib/mongoid/contextual/geo_near.rb +1 -1
  24. data/lib/mongoid/contextual/map_reduce.rb +4 -2
  25. data/lib/mongoid/contextual/memory.rb +23 -11
  26. data/lib/mongoid/contextual/mongo.rb +75 -57
  27. data/lib/mongoid/contextual/none.rb +90 -0
  28. data/lib/mongoid/contextual/text_search.rb +178 -0
  29. data/lib/mongoid/copyable.rb +2 -3
  30. data/lib/mongoid/criteria.rb +39 -34
  31. data/lib/mongoid/criteria/#findable.rb# +141 -0
  32. data/lib/mongoid/{criterion → criteria}/findable.rb +7 -47
  33. data/lib/mongoid/{criterion/inspection.rb → criteria/inspectable.rb} +2 -2
  34. data/lib/mongoid/{criterion → criteria}/marshalable.rb +3 -1
  35. data/lib/mongoid/{criterion → criteria}/modifiable.rb +28 -8
  36. data/lib/mongoid/criteria/permission.rb +70 -0
  37. data/lib/mongoid/{criterion/scoping.rb → criteria/scopable.rb} +2 -2
  38. data/lib/mongoid/document.rb +39 -24
  39. data/lib/mongoid/errors.rb +4 -1
  40. data/lib/mongoid/errors/document_not_destroyed.rb +25 -0
  41. data/lib/mongoid/errors/document_not_found.rb +2 -1
  42. data/lib/mongoid/errors/invalid_storage_options.rb +1 -1
  43. data/lib/mongoid/errors/invalid_storage_parent.rb +26 -0
  44. data/lib/mongoid/errors/invalid_value.rb +16 -0
  45. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  46. data/lib/mongoid/errors/readonly_document.rb +24 -0
  47. data/lib/mongoid/extensions.rb +15 -7
  48. data/lib/mongoid/extensions/array.rb +3 -3
  49. data/lib/mongoid/extensions/big_decimal.rb +1 -1
  50. data/lib/mongoid/extensions/boolean.rb +15 -17
  51. data/lib/mongoid/extensions/date.rb +1 -1
  52. data/lib/mongoid/extensions/date_time.rb +3 -3
  53. data/lib/mongoid/extensions/float.rb +2 -1
  54. data/lib/mongoid/extensions/hash.rb +3 -3
  55. data/lib/mongoid/extensions/integer.rb +1 -1
  56. data/lib/mongoid/extensions/object.rb +7 -7
  57. data/lib/mongoid/extensions/object_id.rb +5 -5
  58. data/lib/mongoid/extensions/range.rb +9 -3
  59. data/lib/mongoid/extensions/regexp.rb +1 -1
  60. data/lib/mongoid/extensions/set.rb +1 -1
  61. data/lib/mongoid/extensions/string.rb +6 -18
  62. data/lib/mongoid/extensions/symbol.rb +1 -1
  63. data/lib/mongoid/extensions/time.rb +3 -3
  64. data/lib/mongoid/extensions/time_with_zone.rb +1 -1
  65. data/lib/mongoid/factory.rb +8 -6
  66. data/lib/mongoid/fields.rb +41 -8
  67. data/lib/mongoid/fields/foreign_key.rb +3 -3
  68. data/lib/mongoid/fields/localized.rb +1 -1
  69. data/lib/mongoid/fields/standard.rb +5 -17
  70. data/lib/mongoid/fields/validators/macro.rb +15 -5
  71. data/lib/mongoid/{finders.rb → findable.rb} +35 -7
  72. data/lib/mongoid/{indexes.rb → indexable.rb} +50 -55
  73. data/lib/mongoid/indexable/specification.rb +104 -0
  74. data/lib/mongoid/{indexes → indexable}/validators/options.rb +2 -1
  75. data/lib/mongoid/{inspection.rb → inspectable.rb} +15 -11
  76. data/lib/mongoid/{callbacks.rb → interceptable.rb} +30 -62
  77. data/lib/mongoid/log_subscriber.rb +55 -0
  78. data/lib/mongoid/matchable.rb +152 -0
  79. data/lib/mongoid/{matchers → matchable}/all.rb +1 -1
  80. data/lib/mongoid/{matchers → matchable}/and.rb +2 -2
  81. data/lib/mongoid/{matchers → matchable}/default.rb +1 -1
  82. data/lib/mongoid/{matchers → matchable}/exists.rb +1 -1
  83. data/lib/mongoid/{matchers → matchable}/gt.rb +1 -1
  84. data/lib/mongoid/{matchers → matchable}/gte.rb +1 -1
  85. data/lib/mongoid/{matchers → matchable}/in.rb +2 -2
  86. data/lib/mongoid/{matchers → matchable}/lt.rb +1 -1
  87. data/lib/mongoid/{matchers → matchable}/lte.rb +1 -1
  88. data/lib/mongoid/{matchers → matchable}/ne.rb +2 -2
  89. data/lib/mongoid/{matchers → matchable}/nin.rb +3 -2
  90. data/lib/mongoid/{matchers → matchable}/or.rb +2 -2
  91. data/lib/mongoid/{matchers → matchable}/size.rb +1 -1
  92. data/lib/mongoid/persistable.rb +216 -0
  93. data/lib/mongoid/persistable/creatable.rb +189 -0
  94. data/lib/mongoid/persistable/deletable.rb +149 -0
  95. data/lib/mongoid/persistable/destroyable.rb +60 -0
  96. data/lib/mongoid/persistable/incrementable.rb +36 -0
  97. data/lib/mongoid/persistable/logical.rb +38 -0
  98. data/lib/mongoid/persistable/poppable.rb +39 -0
  99. data/lib/mongoid/persistable/pullable.rb +55 -0
  100. data/lib/mongoid/persistable/pushable.rb +62 -0
  101. data/lib/mongoid/persistable/renamable.rb +35 -0
  102. data/lib/mongoid/persistable/savable.rb +52 -0
  103. data/lib/mongoid/persistable/settable.rb +33 -0
  104. data/lib/mongoid/persistable/unsettable.rb +36 -0
  105. data/lib/mongoid/persistable/updatable.rb +153 -0
  106. data/lib/mongoid/persistable/upsertable.rb +55 -0
  107. data/lib/mongoid/positional.rb +71 -0
  108. data/lib/mongoid/query_cache.rb +255 -0
  109. data/lib/mongoid/railtie.rb +34 -60
  110. data/lib/mongoid/railties/database.rake +9 -25
  111. data/lib/mongoid/relations.rb +11 -25
  112. data/lib/mongoid/relations/accessors.rb +15 -51
  113. data/lib/mongoid/relations/auto_save.rb +15 -36
  114. data/lib/mongoid/relations/binding.rb +2 -25
  115. data/lib/mongoid/relations/bindings/embedded/in.rb +1 -1
  116. data/lib/mongoid/relations/bindings/embedded/many.rb +1 -3
  117. data/lib/mongoid/relations/bindings/referenced/in.rb +3 -8
  118. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +4 -2
  119. data/lib/mongoid/relations/builder.rb +1 -1
  120. data/lib/mongoid/relations/builders.rb +2 -2
  121. data/lib/mongoid/relations/builders/embedded/one.rb +1 -1
  122. data/lib/mongoid/relations/builders/nested_attributes/many.rb +10 -13
  123. data/lib/mongoid/relations/builders/nested_attributes/one.rb +5 -6
  124. data/lib/mongoid/relations/builders/referenced/in.rb +1 -1
  125. data/lib/mongoid/relations/builders/referenced/many.rb +1 -2
  126. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +1 -2
  127. data/lib/mongoid/relations/builders/referenced/one.rb +1 -1
  128. data/lib/mongoid/relations/cascading.rb +3 -5
  129. data/lib/mongoid/relations/constraint.rb +1 -1
  130. data/lib/mongoid/relations/conversions.rb +1 -1
  131. data/lib/mongoid/relations/counter_cache.rb +39 -15
  132. data/lib/mongoid/relations/eager.rb +46 -0
  133. data/lib/mongoid/relations/eager/base.rb +149 -0
  134. data/lib/mongoid/relations/eager/belongs_to.rb +31 -0
  135. data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +47 -0
  136. data/lib/mongoid/relations/eager/has_many.rb +38 -0
  137. data/lib/mongoid/relations/eager/has_one.rb +30 -0
  138. data/lib/mongoid/relations/embedded/batchable.rb +4 -5
  139. data/lib/mongoid/relations/embedded/in.rb +4 -4
  140. data/lib/mongoid/relations/embedded/many.rb +14 -32
  141. data/lib/mongoid/relations/embedded/one.rb +1 -1
  142. data/lib/mongoid/relations/macros.rb +3 -4
  143. data/lib/mongoid/relations/many.rb +51 -31
  144. data/lib/mongoid/relations/marshalable.rb +3 -3
  145. data/lib/mongoid/relations/metadata.rb +14 -79
  146. data/lib/mongoid/relations/nested_builder.rb +2 -2
  147. data/lib/mongoid/relations/one.rb +1 -1
  148. data/lib/mongoid/relations/options.rb +1 -0
  149. data/lib/mongoid/relations/polymorphic.rb +0 -1
  150. data/lib/mongoid/relations/proxy.rb +21 -41
  151. data/lib/mongoid/relations/referenced/in.rb +4 -20
  152. data/lib/mongoid/relations/referenced/many.rb +22 -35
  153. data/lib/mongoid/relations/referenced/many_to_many.rb +19 -42
  154. data/lib/mongoid/relations/referenced/one.rb +6 -25
  155. data/lib/mongoid/relations/synchronization.rb +4 -4
  156. data/lib/mongoid/relations/targets/enumerable.rb +10 -10
  157. data/lib/mongoid/relations/touchable.rb +34 -1
  158. data/lib/mongoid/{reloading.rb → reloadable.rb} +7 -5
  159. data/lib/mongoid/{scoping.rb → scopable.rb} +36 -36
  160. data/lib/mongoid/selectable.rb +59 -0
  161. data/lib/mongoid/{serialization.rb → serializable.rb} +11 -2
  162. data/lib/mongoid/sessions.rb +37 -345
  163. data/lib/mongoid/sessions/factory.rb +2 -0
  164. data/lib/mongoid/sessions/options.rb +185 -0
  165. data/lib/mongoid/sessions/storage_options.rb +140 -0
  166. data/lib/mongoid/sessions/thread_options.rb +19 -0
  167. data/lib/mongoid/sessions/validators/storage.rb +16 -3
  168. data/lib/mongoid/{sharding.rb → shardable.rb} +5 -1
  169. data/lib/mongoid/{state.rb → stateful.rb} +13 -1
  170. data/lib/mongoid/support/query_counter.rb +23 -0
  171. data/lib/mongoid/tasks/database.rake +31 -0
  172. data/lib/mongoid/tasks/database.rb +107 -0
  173. data/lib/mongoid/threaded.rb +26 -172
  174. data/lib/mongoid/threaded/lifecycle.rb +0 -28
  175. data/lib/mongoid/timestamps/updated/short.rb +2 -2
  176. data/lib/mongoid/{hierarchy.rb → traversable.rb} +15 -7
  177. data/lib/mongoid/{validations.rb → validatable.rb} +23 -10
  178. data/lib/mongoid/{validations → validatable}/associated.rb +4 -2
  179. data/lib/mongoid/{validations → validatable}/format.rb +1 -1
  180. data/lib/mongoid/{validations → validatable}/length.rb +1 -1
  181. data/lib/mongoid/{validations → validatable}/localizable.rb +1 -1
  182. data/lib/mongoid/{validations → validatable}/macros.rb +4 -3
  183. data/lib/mongoid/{validations → validatable}/presence.rb +1 -1
  184. data/lib/mongoid/{validations → validatable}/queryable.rb +1 -2
  185. data/lib/mongoid/{validations → validatable}/uniqueness.rb +25 -21
  186. data/lib/mongoid/version.rb +1 -1
  187. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +46 -25
  188. data/lib/rails/generators/mongoid/model/model_generator.rb +0 -1
  189. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +0 -3
  190. data/lib/rails/generators/mongoid_generator.rb +3 -40
  191. data/lib/rails/mongoid.rb +0 -122
  192. data/lib/support/ruby_version.rb +1 -1
  193. data/spec/app/models/account.rb +2 -6
  194. data/spec/app/models/acolyte.rb +2 -1
  195. data/spec/app/models/actor.rb +0 -1
  196. data/spec/app/models/address.rb +8 -3
  197. data/spec/app/models/animal.rb +1 -1
  198. data/spec/app/models/appointment.rb +3 -3
  199. data/spec/app/models/article.rb +1 -4
  200. data/spec/app/models/audio.rb +5 -0
  201. data/spec/app/models/author.rb +0 -2
  202. data/spec/app/models/band.rb +3 -2
  203. data/spec/app/models/bar.rb +1 -0
  204. data/spec/app/models/book.rb +1 -0
  205. data/spec/app/models/building.rb +0 -2
  206. data/spec/app/models/building_address.rb +0 -2
  207. data/spec/app/models/bus.rb +1 -1
  208. data/spec/app/models/canvas.rb +1 -1
  209. data/spec/app/models/contextable_item.rb +5 -0
  210. data/spec/app/models/contractor.rb +0 -2
  211. data/spec/app/models/country_code.rb +1 -1
  212. data/spec/app/models/definition.rb +2 -2
  213. data/spec/app/models/dog.rb +1 -1
  214. data/spec/app/models/draft.rb +9 -0
  215. data/spec/app/models/dragon.rb +4 -0
  216. data/spec/app/models/drug.rb +1 -3
  217. data/spec/app/models/dungeon.rb +4 -0
  218. data/spec/app/models/edit.rb +5 -0
  219. data/spec/app/models/even.rb +7 -0
  220. data/spec/app/models/event.rb +1 -1
  221. data/spec/app/models/filesystem.rb +1 -0
  222. data/spec/app/models/fish.rb +0 -1
  223. data/spec/app/models/fruits.rb +6 -0
  224. data/spec/app/models/game.rb +0 -2
  225. data/spec/app/models/house.rb +1 -3
  226. data/spec/app/models/id_key.rb +6 -0
  227. data/spec/app/models/item.rb +1 -5
  228. data/spec/app/models/jar.rb +1 -1
  229. data/spec/app/models/label.rb +4 -4
  230. data/spec/app/models/line_item.rb +1 -1
  231. data/spec/app/models/login.rb +1 -1
  232. data/spec/app/models/message.rb +8 -0
  233. data/spec/app/models/movie.rb +1 -0
  234. data/spec/app/models/name.rb +3 -3
  235. data/spec/app/models/note.rb +3 -1
  236. data/spec/app/models/odd.rb +7 -0
  237. data/spec/app/models/oscar.rb +1 -1
  238. data/spec/app/models/parent_doc.rb +1 -1
  239. data/spec/app/models/person.rb +16 -10
  240. data/spec/app/models/phone.rb +1 -3
  241. data/spec/app/models/player.rb +3 -3
  242. data/spec/app/models/post.rb +5 -3
  243. data/spec/app/models/preference.rb +1 -1
  244. data/spec/app/models/quiz.rb +0 -3
  245. data/spec/app/models/record.rb +10 -5
  246. data/spec/app/models/registry.rb +1 -1
  247. data/spec/app/models/server.rb +1 -1
  248. data/spec/app/models/service.rb +3 -3
  249. data/spec/app/models/sound.rb +5 -0
  250. data/spec/app/models/symptom.rb +1 -1
  251. data/spec/app/models/template.rb +1 -1
  252. data/spec/app/models/title.rb +0 -1
  253. data/spec/app/models/track.rb +5 -5
  254. data/spec/app/models/tree.rb +3 -3
  255. data/spec/app/models/video.rb +1 -5
  256. data/spec/app/models/wiki_page.rb +2 -5
  257. data/spec/app/models/word.rb +3 -0
  258. data/spec/app/models/word_origin.rb +1 -1
  259. data/spec/config/mongoid.yml +7 -8
  260. data/spec/helpers.rb +18 -0
  261. data/spec/mongoid/#atomic_spec.rb# +365 -0
  262. data/spec/mongoid/atomic/modifiers_spec.rb +22 -22
  263. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +8 -49
  264. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +7 -49
  265. data/spec/mongoid/atomic/paths/root_spec.rb +3 -61
  266. data/spec/mongoid/atomic/paths_spec.rb +19 -19
  267. data/spec/mongoid/atomic_spec.rb +19 -19
  268. data/spec/mongoid/{nested_attributes_spec.rb → attributes/nested_spec.rb} +474 -592
  269. data/spec/mongoid/attributes/readonly_spec.rb +58 -18
  270. data/spec/mongoid/attributes_spec.rb +349 -434
  271. data/spec/mongoid/{dirty_spec.rb → changeable_spec.rb} +203 -153
  272. data/spec/mongoid/{components_spec.rb → composable_spec.rb} +3 -3
  273. data/spec/mongoid/config/environment_spec.rb +3 -3
  274. data/spec/mongoid/config/options_spec.rb +6 -6
  275. data/spec/mongoid/config_spec.rb +24 -48
  276. data/spec/mongoid/contextual/aggregable/memory_spec.rb +12 -12
  277. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +78 -38
  278. data/spec/mongoid/contextual/atomic_spec.rb +60 -56
  279. data/spec/mongoid/contextual/find_and_modify_spec.rb +14 -14
  280. data/spec/mongoid/contextual/geo_near_spec.rb +22 -22
  281. data/spec/mongoid/contextual/map_reduce_spec.rb +27 -27
  282. data/spec/mongoid/contextual/memory_spec.rb +156 -94
  283. data/spec/mongoid/contextual/mongo_spec.rb +238 -150
  284. data/spec/mongoid/contextual/none_spec.rb +127 -0
  285. data/spec/mongoid/contextual/text_search_spec.rb +209 -0
  286. data/spec/mongoid/copyable_spec.rb +56 -68
  287. data/spec/mongoid/criteria/findable_spec.rb +991 -0
  288. data/spec/mongoid/{criterion/inspection_spec.rb → criteria/inspectable_spec.rb} +5 -5
  289. data/spec/mongoid/{criterion → criteria}/marshalable_spec.rb +2 -2
  290. data/spec/mongoid/criteria/modifiable_spec.rb +1252 -0
  291. data/spec/mongoid/{criterion/scoping_spec.rb → criteria/scopable_spec.rb} +37 -37
  292. data/spec/mongoid/criteria_spec.rb +715 -2421
  293. data/spec/mongoid/document_spec.rb +171 -121
  294. data/spec/mongoid/equality_spec.rb +22 -22
  295. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +3 -3
  296. data/spec/mongoid/errors/callback_spec.rb +3 -3
  297. data/spec/mongoid/errors/delete_restriction_spec.rb +3 -3
  298. data/spec/mongoid/errors/document_not_destroyed_spec.rb +33 -0
  299. data/spec/mongoid/errors/document_not_found_spec.rb +11 -11
  300. data/spec/mongoid/errors/eager_load_spec.rb +3 -3
  301. data/spec/mongoid/errors/invalid_collection_spec.rb +3 -3
  302. data/spec/mongoid/errors/invalid_config_option_spec.rb +3 -3
  303. data/spec/mongoid/errors/invalid_field_option_spec.rb +3 -3
  304. data/spec/mongoid/errors/invalid_field_spec.rb +3 -3
  305. data/spec/mongoid/errors/invalid_find_spec.rb +3 -3
  306. data/spec/mongoid/errors/invalid_includes_spec.rb +3 -3
  307. data/spec/mongoid/errors/invalid_index_spec.rb +3 -3
  308. data/spec/mongoid/errors/invalid_options_spec.rb +3 -3
  309. data/spec/mongoid/errors/invalid_path_spec.rb +3 -3
  310. data/spec/mongoid/errors/invalid_scope_spec.rb +5 -5
  311. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +3 -3
  312. data/spec/mongoid/errors/invalid_storage_options_spec.rb +3 -3
  313. data/spec/mongoid/errors/invalid_time_spec.rb +3 -3
  314. data/spec/mongoid/errors/inverse_not_found_spec.rb +3 -3
  315. data/spec/mongoid/errors/mixed_relations_spec.rb +3 -3
  316. data/spec/mongoid/errors/mixed_session_configuration_spec.rb +3 -3
  317. data/spec/mongoid/errors/mongoid_error_spec.rb +8 -8
  318. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +3 -3
  319. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  320. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +3 -3
  321. data/spec/mongoid/errors/no_metadata_spec.rb +3 -3
  322. data/spec/mongoid/errors/no_parent_spec.rb +3 -3
  323. data/spec/mongoid/errors/no_session_config_spec.rb +3 -3
  324. data/spec/mongoid/errors/no_session_database_spec.rb +3 -3
  325. data/spec/mongoid/errors/no_session_hosts_spec.rb +3 -3
  326. data/spec/mongoid/errors/no_sessions_config_spec.rb +3 -3
  327. data/spec/mongoid/errors/readonly_attribute_spec.rb +3 -3
  328. data/spec/mongoid/errors/readonly_document_spec.rb +29 -0
  329. data/spec/mongoid/errors/scope_overwrite_spec.rb +3 -3
  330. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +3 -3
  331. data/spec/mongoid/errors/unknown_attribute_spec.rb +5 -5
  332. data/spec/mongoid/errors/unsaved_document_spec.rb +3 -3
  333. data/spec/mongoid/errors/unsupported_javascript_spec.rb +3 -3
  334. data/spec/mongoid/errors/validations_spec.rb +7 -7
  335. data/spec/mongoid/extensions/array_spec.rb +61 -61
  336. data/spec/mongoid/extensions/big_decimal_spec.rb +11 -11
  337. data/spec/mongoid/extensions/binary_spec.rb +12 -12
  338. data/spec/mongoid/extensions/boolean_spec.rb +18 -18
  339. data/spec/mongoid/extensions/date_spec.rb +13 -13
  340. data/spec/mongoid/extensions/date_time_spec.rb +8 -8
  341. data/spec/mongoid/extensions/false_class_spec.rb +5 -5
  342. data/spec/mongoid/extensions/float_spec.rb +29 -15
  343. data/spec/mongoid/extensions/hash_spec.rb +29 -29
  344. data/spec/mongoid/extensions/integer_spec.rb +15 -15
  345. data/spec/mongoid/extensions/module_spec.rb +2 -2
  346. data/spec/mongoid/extensions/nil_class_spec.rb +1 -1
  347. data/spec/mongoid/extensions/object_id_spec.rb +134 -134
  348. data/spec/mongoid/extensions/object_spec.rb +26 -26
  349. data/spec/mongoid/extensions/range_spec.rb +61 -12
  350. data/spec/mongoid/extensions/regexp_spec.rb +4 -4
  351. data/spec/mongoid/extensions/set_spec.rb +4 -4
  352. data/spec/mongoid/extensions/string_spec.rb +35 -46
  353. data/spec/mongoid/extensions/symbol_spec.rb +9 -9
  354. data/spec/mongoid/extensions/time_spec.rb +49 -49
  355. data/spec/mongoid/extensions/time_with_zone_spec.rb +34 -34
  356. data/spec/mongoid/extensions/true_class_spec.rb +5 -5
  357. data/spec/mongoid/extensions_spec.rb +29 -0
  358. data/spec/mongoid/factory_spec.rb +15 -15
  359. data/spec/mongoid/fields/foreign_key_spec.rb +73 -66
  360. data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +15 -15
  361. data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +22 -22
  362. data/spec/mongoid/fields/localized_spec.rb +38 -23
  363. data/spec/mongoid/fields/standard_spec.rb +12 -12
  364. data/spec/mongoid/fields_spec.rb +263 -217
  365. data/spec/mongoid/findable_spec.rb +509 -0
  366. data/spec/mongoid/indexable/specification_spec.rb +102 -0
  367. data/spec/mongoid/{indexes_spec.rb → indexable_spec.rb} +171 -51
  368. data/spec/mongoid/{inspection_spec.rb → inspectable_spec.rb} +6 -14
  369. data/spec/mongoid/{callbacks_spec.rb → interceptable_spec.rb} +117 -116
  370. data/spec/mongoid/log_subscriber_spec.rb +75 -0
  371. data/spec/mongoid/loggable_spec.rb +1 -1
  372. data/spec/mongoid/{matchers → matchable}/all_spec.rb +4 -4
  373. data/spec/mongoid/{matchers → matchable}/and_spec.rb +11 -11
  374. data/spec/mongoid/{matchers → matchable}/default_spec.rb +15 -15
  375. data/spec/mongoid/{matchers → matchable}/exists_spec.rb +5 -5
  376. data/spec/mongoid/{matchers → matchable}/gt_spec.rb +9 -8
  377. data/spec/mongoid/{matchers → matchable}/gte_spec.rb +7 -7
  378. data/spec/mongoid/matchable/in_spec.rb +49 -0
  379. data/spec/mongoid/{matchers → matchable}/lt_spec.rb +7 -7
  380. data/spec/mongoid/{matchers → matchable}/lte_spec.rb +7 -7
  381. data/spec/mongoid/matchable/ne_spec.rb +46 -0
  382. data/spec/mongoid/matchable/nin_spec.rb +48 -0
  383. data/spec/mongoid/{matchers → matchable}/or_spec.rb +6 -6
  384. data/spec/mongoid/{matchers → matchable}/size_spec.rb +3 -3
  385. data/spec/mongoid/{matchers_spec.rb → matchable_spec.rb} +41 -41
  386. data/spec/mongoid/persistable/creatable_spec.rb +553 -0
  387. data/spec/mongoid/persistable/deletable_spec.rb +218 -0
  388. data/spec/mongoid/persistable/destroyable_spec.rb +192 -0
  389. data/spec/mongoid/persistable/incrementable_spec.rb +173 -0
  390. data/spec/mongoid/persistable/logical_spec.rb +143 -0
  391. data/spec/mongoid/persistable/poppable_spec.rb +115 -0
  392. data/spec/mongoid/persistable/pullable_spec.rb +228 -0
  393. data/spec/mongoid/persistable/pushable_spec.rb +258 -0
  394. data/spec/mongoid/persistable/renamable_spec.rb +135 -0
  395. data/spec/mongoid/persistable/savable_spec.rb +498 -0
  396. data/spec/mongoid/persistable/settable_spec.rb +162 -0
  397. data/spec/mongoid/persistable/unsettable_spec.rb +155 -0
  398. data/spec/mongoid/persistable/updatable_spec.rb +558 -0
  399. data/spec/mongoid/persistable/upsertable_spec.rb +106 -0
  400. data/spec/mongoid/persistable_spec.rb +206 -0
  401. data/spec/mongoid/{atomic/positionable_spec.rb → positional_spec.rb} +14 -19
  402. data/spec/mongoid/query_cache_spec.rb +263 -0
  403. data/spec/mongoid/railties/document_spec.rb +2 -2
  404. data/spec/mongoid/relations/accessors_spec.rb +53 -145
  405. data/spec/mongoid/relations/auto_save_spec.rb +37 -17
  406. data/spec/mongoid/relations/bindings/embedded/in_spec.rb +12 -12
  407. data/spec/mongoid/relations/bindings/embedded/many_spec.rb +3 -3
  408. data/spec/mongoid/relations/bindings/embedded/one_spec.rb +5 -5
  409. data/spec/mongoid/relations/bindings/referenced/in_spec.rb +26 -26
  410. data/spec/mongoid/relations/bindings/referenced/many_spec.rb +10 -10
  411. data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +19 -19
  412. data/spec/mongoid/relations/bindings/referenced/one_spec.rb +12 -12
  413. data/spec/mongoid/relations/builders/embedded/in_spec.rb +4 -4
  414. data/spec/mongoid/relations/builders/embedded/many_spec.rb +18 -18
  415. data/spec/mongoid/relations/builders/embedded/one_spec.rb +11 -11
  416. data/spec/mongoid/relations/builders/nested_attributes/many_spec.rb +12 -13
  417. data/spec/mongoid/relations/builders/nested_attributes/one_spec.rb +14 -14
  418. data/spec/mongoid/relations/builders/referenced/in_spec.rb +24 -35
  419. data/spec/mongoid/relations/builders/referenced/many_spec.rb +15 -15
  420. data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +18 -18
  421. data/spec/mongoid/relations/builders/referenced/one_spec.rb +12 -25
  422. data/spec/mongoid/relations/builders_spec.rb +21 -21
  423. data/spec/mongoid/relations/cascading/delete_spec.rb +9 -9
  424. data/spec/mongoid/relations/cascading/destroy_spec.rb +6 -6
  425. data/spec/mongoid/relations/cascading/nullify_spec.rb +4 -4
  426. data/spec/mongoid/relations/cascading/restrict_spec.rb +7 -7
  427. data/spec/mongoid/relations/cascading_spec.rb +16 -16
  428. data/spec/mongoid/relations/constraint_spec.rb +8 -7
  429. data/spec/mongoid/relations/conversions_spec.rb +16 -14
  430. data/spec/mongoid/relations/counter_cache_spec.rb +85 -0
  431. data/spec/mongoid/relations/cyclic_spec.rb +18 -18
  432. data/spec/mongoid/relations/eager/belongs_to_spec.rb +154 -0
  433. data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +117 -0
  434. data/spec/mongoid/relations/eager/has_many_spec.rb +207 -0
  435. data/spec/mongoid/relations/eager/has_one_spec.rb +163 -0
  436. data/spec/mongoid/relations/eager_spec.rb +228 -0
  437. data/spec/mongoid/relations/embedded/dirty_spec.rb +8 -8
  438. data/spec/mongoid/relations/embedded/in_spec.rb +56 -57
  439. data/spec/mongoid/relations/embedded/many_spec.rb +467 -372
  440. data/spec/mongoid/relations/embedded/one_spec.rb +108 -141
  441. data/spec/mongoid/relations/macros_spec.rb +108 -102
  442. data/spec/mongoid/relations/metadata_spec.rb +180 -255
  443. data/spec/mongoid/relations/options_spec.rb +1 -1
  444. data/spec/mongoid/relations/polymorphic_spec.rb +13 -17
  445. data/spec/mongoid/relations/proxy_spec.rb +2 -2
  446. data/spec/mongoid/relations/referenced/in_spec.rb +128 -303
  447. data/spec/mongoid/relations/referenced/many_spec.rb +587 -527
  448. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +401 -424
  449. data/spec/mongoid/relations/referenced/one_spec.rb +149 -264
  450. data/spec/mongoid/relations/reflections_spec.rb +6 -6
  451. data/spec/mongoid/relations/synchronization_spec.rb +46 -50
  452. data/spec/mongoid/relations/targets/enumerable_spec.rb +118 -118
  453. data/spec/mongoid/relations/touchable_spec.rb +333 -0
  454. data/spec/mongoid/relations_spec.rb +16 -15
  455. data/spec/mongoid/{reloading_spec.rb → reloadable_spec.rb} +38 -55
  456. data/spec/mongoid/{scoping_spec.rb → scopable_spec.rb} +89 -164
  457. data/spec/mongoid/selectable_spec.rb +134 -0
  458. data/spec/mongoid/{serialization_spec.rb → serializable_spec.rb} +129 -82
  459. data/spec/mongoid/sessions/factory_spec.rb +49 -28
  460. data/spec/mongoid/sessions/mongo_uri_spec.rb +7 -7
  461. data/spec/mongoid/sessions/options_spec.rb +108 -0
  462. data/spec/mongoid/sessions_spec.rb +319 -178
  463. data/spec/mongoid/{sharding_spec.rb → shardable_spec.rb} +8 -8
  464. data/spec/mongoid/{state_spec.rb → stateful_spec.rb} +36 -11
  465. data/spec/mongoid/tasks/database_rake_spec.rb +285 -0
  466. data/spec/mongoid/tasks/database_spec.rb +160 -0
  467. data/spec/mongoid/threaded_spec.rb +17 -70
  468. data/spec/mongoid/timestamps/created/short_spec.rb +6 -6
  469. data/spec/mongoid/timestamps/created_spec.rb +5 -5
  470. data/spec/mongoid/timestamps/timeless_spec.rb +6 -6
  471. data/spec/mongoid/timestamps/updated/short_spec.rb +11 -11
  472. data/spec/mongoid/timestamps/updated_spec.rb +9 -13
  473. data/spec/mongoid/timestamps_spec.rb +9 -13
  474. data/spec/mongoid/{hierarchy_spec.rb → traversable_spec.rb} +19 -19
  475. data/spec/mongoid/{validations → validatable}/associated_spec.rb +45 -22
  476. data/spec/mongoid/{validations → validatable}/format_spec.rb +6 -6
  477. data/spec/mongoid/{validations → validatable}/length_spec.rb +14 -14
  478. data/spec/mongoid/{validations → validatable}/numericality_spec.rb +1 -1
  479. data/spec/mongoid/{validations → validatable}/presence_spec.rb +37 -44
  480. data/spec/mongoid/{validations → validatable}/uniqueness_spec.rb +184 -192
  481. data/spec/mongoid/{validations_spec.rb → validatable_spec.rb} +28 -28
  482. data/spec/mongoid_spec.rb +8 -8
  483. data/spec/rails/mongoid_spec.rb +19 -335
  484. data/spec/spec_helper.rb +31 -13
  485. metadata +303 -283
  486. data/lib/mongoid/atomic/positionable.rb +0 -73
  487. data/lib/mongoid/components.rb +0 -92
  488. data/lib/mongoid/config/inflections.rb +0 -6
  489. data/lib/mongoid/contextual/eager.rb +0 -158
  490. data/lib/mongoid/errors/versioning_not_on_root.rb +0 -23
  491. data/lib/mongoid/identity_map.rb +0 -163
  492. data/lib/mongoid/json.rb +0 -16
  493. data/lib/mongoid/matchers.rb +0 -32
  494. data/lib/mongoid/matchers/strategies.rb +0 -97
  495. data/lib/mongoid/multi_parameter_attributes.rb +0 -105
  496. data/lib/mongoid/nested_attributes.rb +0 -78
  497. data/lib/mongoid/observer.rb +0 -192
  498. data/lib/mongoid/paranoia.rb +0 -136
  499. data/lib/mongoid/persistence.rb +0 -357
  500. data/lib/mongoid/persistence/atomic.rb +0 -231
  501. data/lib/mongoid/persistence/atomic/add_to_set.rb +0 -47
  502. data/lib/mongoid/persistence/atomic/bit.rb +0 -35
  503. data/lib/mongoid/persistence/atomic/inc.rb +0 -45
  504. data/lib/mongoid/persistence/atomic/operation.rb +0 -154
  505. data/lib/mongoid/persistence/atomic/pop.rb +0 -32
  506. data/lib/mongoid/persistence/atomic/pull.rb +0 -32
  507. data/lib/mongoid/persistence/atomic/pull_all.rb +0 -32
  508. data/lib/mongoid/persistence/atomic/push.rb +0 -25
  509. data/lib/mongoid/persistence/atomic/push_all.rb +0 -25
  510. data/lib/mongoid/persistence/atomic/rename.rb +0 -30
  511. data/lib/mongoid/persistence/atomic/sets.rb +0 -28
  512. data/lib/mongoid/persistence/atomic/unset.rb +0 -27
  513. data/lib/mongoid/persistence/deletion.rb +0 -31
  514. data/lib/mongoid/persistence/insertion.rb +0 -38
  515. data/lib/mongoid/persistence/modification.rb +0 -35
  516. data/lib/mongoid/persistence/operations.rb +0 -214
  517. data/lib/mongoid/persistence/operations/embedded/insert.rb +0 -46
  518. data/lib/mongoid/persistence/operations/embedded/remove.rb +0 -43
  519. data/lib/mongoid/persistence/operations/insert.rb +0 -34
  520. data/lib/mongoid/persistence/operations/remove.rb +0 -33
  521. data/lib/mongoid/persistence/operations/update.rb +0 -59
  522. data/lib/mongoid/persistence/operations/upsert.rb +0 -28
  523. data/lib/mongoid/persistence/upsertion.rb +0 -31
  524. data/lib/mongoid/unit_of_work.rb +0 -61
  525. data/lib/mongoid/versioning.rb +0 -217
  526. data/lib/rack/mongoid.rb +0 -2
  527. data/lib/rack/mongoid/middleware/identity_map.rb +0 -39
  528. data/lib/rails/generators/mongoid/observer/observer_generator.rb +0 -17
  529. data/lib/rails/generators/mongoid/observer/templates/observer.rb.tt +0 -4
  530. data/spec/app/models/actor_observer.rb +0 -15
  531. data/spec/app/models/callback_recorder.rb +0 -25
  532. data/spec/app/models/paranoid_phone.rb +0 -25
  533. data/spec/app/models/paranoid_post.rb +0 -36
  534. data/spec/app/models/phone_observer.rb +0 -6
  535. data/spec/mongoid/attributes/processing_spec.rb +0 -149
  536. data/spec/mongoid/criterion/destructive_spec.rb +0 -101
  537. data/spec/mongoid/criterion/modifiable_spec.rb +0 -409
  538. data/spec/mongoid/criterion/modification_spec.rb +0 -402
  539. data/spec/mongoid/errors/versioning_not_on_root_spec.rb +0 -29
  540. data/spec/mongoid/finders_spec.rb +0 -321
  541. data/spec/mongoid/identity_map_spec.rb +0 -564
  542. data/spec/mongoid/json_spec.rb +0 -33
  543. data/spec/mongoid/matchers/in_spec.rb +0 -25
  544. data/spec/mongoid/matchers/ne_spec.rb +0 -25
  545. data/spec/mongoid/matchers/nin_spec.rb +0 -25
  546. data/spec/mongoid/multi_parameter_attributes_spec.rb +0 -128
  547. data/spec/mongoid/observer_spec.rb +0 -290
  548. data/spec/mongoid/paranoia_spec.rb +0 -759
  549. data/spec/mongoid/persistence/atomic/add_to_set_spec.rb +0 -262
  550. data/spec/mongoid/persistence/atomic/bit_spec.rb +0 -88
  551. data/spec/mongoid/persistence/atomic/inc_spec.rb +0 -133
  552. data/spec/mongoid/persistence/atomic/pop_spec.rb +0 -111
  553. data/spec/mongoid/persistence/atomic/pull_all_spec.rb +0 -77
  554. data/spec/mongoid/persistence/atomic/pull_spec.rb +0 -80
  555. data/spec/mongoid/persistence/atomic/push_all_spec.rb +0 -77
  556. data/spec/mongoid/persistence/atomic/push_spec.rb +0 -77
  557. data/spec/mongoid/persistence/atomic/rename_spec.rb +0 -42
  558. data/spec/mongoid/persistence/atomic/sets_spec.rb +0 -154
  559. data/spec/mongoid/persistence/atomic/unset_spec.rb +0 -65
  560. data/spec/mongoid/persistence/atomic_spec.rb +0 -216
  561. data/spec/mongoid/persistence/operations/embedded/insert_spec.rb +0 -191
  562. data/spec/mongoid/persistence/operations/embedded/remove_spec.rb +0 -8
  563. data/spec/mongoid/persistence/operations/insert_spec.rb +0 -149
  564. data/spec/mongoid/persistence/operations/remove_spec.rb +0 -113
  565. data/spec/mongoid/persistence/operations/update_spec.rb +0 -141
  566. data/spec/mongoid/persistence/operations/upsert_spec.rb +0 -59
  567. data/spec/mongoid/persistence/operations_spec.rb +0 -313
  568. data/spec/mongoid/persistence_spec.rb +0 -2279
  569. data/spec/mongoid/unit_of_work_spec.rb +0 -196
  570. data/spec/mongoid/versioning_spec.rb +0 -540
  571. data/spec/rack/mongoid/middleware/identity_map_spec.rb +0 -72
@@ -1,6 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
- describe Mongoid::Criterion::Inspection do
3
+ describe Mongoid::Criteria::Inspectable do
4
4
 
5
5
  describe "#inspect" do
6
6
 
@@ -9,19 +9,19 @@ describe Mongoid::Criterion::Inspection do
9
9
  end
10
10
 
11
11
  it "includes the selector" do
12
- criteria.inspect.should include("selector")
12
+ expect(criteria.inspect).to include("selector")
13
13
  end
14
14
 
15
15
  it "includes the options" do
16
- criteria.inspect.should include("options")
16
+ expect(criteria.inspect).to include("options")
17
17
  end
18
18
 
19
19
  it "includes the class" do
20
- criteria.inspect.should include("class")
20
+ expect(criteria.inspect).to include("class")
21
21
  end
22
22
 
23
23
  it "includes the embedded flag" do
24
- criteria.inspect.should include("embedded")
24
+ expect(criteria.inspect).to include("embedded")
25
25
  end
26
26
  end
27
27
  end
@@ -1,6 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
- describe Mongoid::Criterion::Marshalable do
3
+ describe Mongoid::Criteria::Marshalable do
4
4
 
5
5
  describe "Marshal.dump" do
6
6
 
@@ -22,7 +22,7 @@ describe Mongoid::Criterion::Marshalable do
22
22
  end
23
23
 
24
24
  it "loads the proper attributes" do
25
- Marshal.load(Marshal.dump(criteria)).should eq(criteria)
25
+ expect(Marshal.load(Marshal.dump(criteria))).to eq(criteria)
26
26
  end
27
27
  end
28
28
  end
@@ -0,0 +1,1252 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Criteria::Modifiable do
4
+
5
+ describe "#create" do
6
+
7
+ let(:criteria) do
8
+ Band.where(name: "Depeche Mode")
9
+ end
10
+
11
+ context "when provided valid attributes" do
12
+ let(:band) do
13
+ criteria.create(genres: [ "electro" ])
14
+ end
15
+
16
+ it "returns the created document" do
17
+ expect(band).to be_persisted
18
+ end
19
+
20
+ it "sets the criteria attributes" do
21
+ expect(band.name).to eq("Depeche Mode")
22
+ end
23
+
24
+ it "sets the attributes passed to build" do
25
+ expect(band.genres).to eq([ "electro" ])
26
+ end
27
+ end
28
+
29
+ context "when provided a block" do
30
+
31
+ context "when provided valid attributes & using block" do
32
+
33
+ let(:band) do
34
+ criteria.create do |c|
35
+ c.genres = [ "electro" ]
36
+ end
37
+ end
38
+
39
+ it "returns the created document" do
40
+ expect(band).to be_persisted
41
+ end
42
+
43
+ it "sets the criteria attributes" do
44
+ expect(band.name).to eq("Depeche Mode")
45
+ end
46
+
47
+ it "sets the attributes passed to build" do
48
+ expect(band.genres).to eq([ "electro" ])
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ describe "#create!" do
55
+
56
+ let(:criteria) do
57
+ Account.where(number: "11123213")
58
+ end
59
+
60
+ context "when provided invalid attributes" do
61
+
62
+ it "raises an error" do
63
+ expect {
64
+ criteria.create!
65
+ }.to raise_error(Mongoid::Errors::Validations)
66
+ end
67
+ end
68
+ end
69
+
70
+ [ :delete, :delete_all, :destroy, :destroy_all ].each do |method|
71
+
72
+ describe "##{method}" do
73
+
74
+ let(:name) do
75
+ Name.new(first_name: "Durran")
76
+ end
77
+
78
+ let(:address_one) do
79
+ Address.new(street: "Forsterstr")
80
+ end
81
+
82
+ let(:address_two) do
83
+ Address.new(street: "Hobrechtstr")
84
+ end
85
+
86
+ before do
87
+ Person.create(title: "Madam")
88
+ 2.times do |n|
89
+ Person.create(
90
+ title: "Sir",
91
+ name: name,
92
+ addresses: [ address_one, address_two ]
93
+ )
94
+ end
95
+ end
96
+
97
+ context "when removing root documents" do
98
+
99
+ let(:criteria) do
100
+ Person.where(title: "Sir", :age.gt => 5)
101
+ end
102
+
103
+ let!(:removed) do
104
+ criteria.send(method)
105
+ end
106
+
107
+ it "deletes the removes the documents from the database" do
108
+ expect(Person.count).to eq(1)
109
+ end
110
+
111
+ it "returns the number removed" do
112
+ expect(removed).to eq(2)
113
+ end
114
+ end
115
+
116
+ context "when removing embedded documents" do
117
+
118
+ context "when removing a single document" do
119
+
120
+ let(:person) do
121
+ Person.where(title: "Sir").first
122
+ end
123
+
124
+ let(:criteria) do
125
+ person.addresses.where(street: "Forsterstr")
126
+ end
127
+
128
+ let!(:removed) do
129
+ criteria.send(method)
130
+ end
131
+
132
+ it "deletes the removes the documents from the database" do
133
+ expect(person.addresses.count).to eq(1)
134
+ end
135
+
136
+ it "returns the number removed" do
137
+ expect(removed).to eq(1)
138
+ end
139
+ end
140
+
141
+ context "when removing multiple documents" do
142
+
143
+ let(:person) do
144
+ Person.where(title: "Sir").first
145
+ end
146
+
147
+ let(:criteria) do
148
+ person.addresses.where(city: nil)
149
+ end
150
+
151
+ let!(:removed) do
152
+ criteria.send(method)
153
+ end
154
+
155
+ it "deletes the removes the documents from the database" do
156
+ expect(person.addresses.count).to eq(0)
157
+ end
158
+
159
+ it "returns the number removed" do
160
+ expect(removed).to eq(2)
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
166
+
167
+ describe ".find_or_create_by" do
168
+
169
+ context "when the document is found" do
170
+
171
+ context "when providing an attribute" do
172
+
173
+ let!(:person) do
174
+ Person.create(title: "Senior")
175
+ end
176
+
177
+ it "returns the document" do
178
+ expect(Person.find_or_create_by(title: "Senior")).to eq(person)
179
+ end
180
+ end
181
+
182
+ context "when providing a document" do
183
+
184
+ context "with an owner with a BSON identity type" do
185
+
186
+ let!(:person) do
187
+ Person.create
188
+ end
189
+
190
+ let!(:game) do
191
+ Game.create(person: person)
192
+ end
193
+
194
+ context "when providing the object directly" do
195
+
196
+ let(:from_db) do
197
+ Game.find_or_create_by(person: person)
198
+ end
199
+
200
+ it "returns the document" do
201
+ expect(from_db).to eq(game)
202
+ end
203
+ end
204
+
205
+ context "when providing the proxy relation" do
206
+
207
+ let(:from_db) do
208
+ Game.find_or_create_by(person: game.person)
209
+ end
210
+
211
+ it "returns the document" do
212
+ expect(from_db).to eq(game)
213
+ end
214
+ end
215
+ end
216
+
217
+ context "with an owner with an Integer identity type" do
218
+
219
+ let!(:jar) do
220
+ Jar.create
221
+ end
222
+
223
+ let!(:cookie) do
224
+ Cookie.create(jar: jar)
225
+ end
226
+
227
+ let(:from_db) do
228
+ Cookie.find_or_create_by(jar: jar)
229
+ end
230
+
231
+ it "returns the document" do
232
+ expect(from_db).to eq(cookie)
233
+ end
234
+ end
235
+ end
236
+ end
237
+
238
+ context "when the document is not found" do
239
+
240
+ context "when providing a document" do
241
+
242
+ let!(:person) do
243
+ Person.create
244
+ end
245
+
246
+ let!(:game) do
247
+ Game.create
248
+ end
249
+
250
+ let(:from_db) do
251
+ Game.find_or_create_by(person: person)
252
+ end
253
+
254
+ it "returns the new document" do
255
+ expect(from_db.person).to eq(person)
256
+ end
257
+
258
+ it "does not return an existing false document" do
259
+ expect(from_db).to_not eq(game)
260
+ end
261
+ end
262
+
263
+ context "when not providing a block" do
264
+
265
+ let!(:person) do
266
+ Person.find_or_create_by(title: "Senorita")
267
+ end
268
+
269
+ it "creates a persisted document" do
270
+ expect(person).to be_persisted
271
+ end
272
+
273
+ it "sets the attributes" do
274
+ expect(person.title).to eq("Senorita")
275
+ end
276
+ end
277
+
278
+ context "when providing a block" do
279
+
280
+ let!(:person) do
281
+ Person.find_or_create_by(title: "Senorita") do |person|
282
+ person.pets = true
283
+ end
284
+ end
285
+
286
+ it "creates a persisted document" do
287
+ expect(person).to be_persisted
288
+ end
289
+
290
+ it "sets the attributes" do
291
+ expect(person.title).to eq("Senorita")
292
+ end
293
+
294
+ it "calls the block" do
295
+ expect(person.pets).to be true
296
+ end
297
+ end
298
+ end
299
+ end
300
+
301
+ describe ".find_or_create_by!" do
302
+
303
+ context "when the document is found" do
304
+
305
+ context "when providing an attribute" do
306
+
307
+ let!(:person) do
308
+ Person.create(title: "Senior")
309
+ end
310
+
311
+ it "returns the document" do
312
+ expect(Person.find_or_create_by!(title: "Senior")).to eq(person)
313
+ end
314
+ end
315
+
316
+ context "when providing a document" do
317
+
318
+ context "with an owner with a BSON identity type" do
319
+
320
+ let!(:person) do
321
+ Person.create
322
+ end
323
+
324
+ let!(:game) do
325
+ Game.create(person: person)
326
+ end
327
+
328
+ context "when providing the object directly" do
329
+
330
+ let(:from_db) do
331
+ Game.find_or_create_by!(person: person)
332
+ end
333
+
334
+ it "returns the document" do
335
+ expect(from_db).to eq(game)
336
+ end
337
+ end
338
+
339
+ context "when providing the proxy relation" do
340
+
341
+ let(:from_db) do
342
+ Game.find_or_create_by!(person: game.person)
343
+ end
344
+
345
+ it "returns the document" do
346
+ expect(from_db).to eq(game)
347
+ end
348
+ end
349
+ end
350
+
351
+ context "with an owner with an Integer identity type" do
352
+
353
+ let!(:jar) do
354
+ Jar.create
355
+ end
356
+
357
+ let!(:cookie) do
358
+ Cookie.create(jar: jar)
359
+ end
360
+
361
+ let(:from_db) do
362
+ Cookie.find_or_create_by!(jar: jar)
363
+ end
364
+
365
+ it "returns the document" do
366
+ expect(from_db).to eq(cookie)
367
+ end
368
+ end
369
+ end
370
+ end
371
+
372
+ context "when the document is not found" do
373
+
374
+ context "when providing a document" do
375
+
376
+ let!(:person) do
377
+ Person.create
378
+ end
379
+
380
+ let!(:game) do
381
+ Game.create
382
+ end
383
+
384
+ let(:from_db) do
385
+ Game.find_or_create_by!(person: person)
386
+ end
387
+
388
+ it "returns the new document" do
389
+ expect(from_db.person).to eq(person)
390
+ end
391
+
392
+ it "does not return an existing false document" do
393
+ expect(from_db).to_not eq(game)
394
+ end
395
+ end
396
+
397
+ context "when not providing a block" do
398
+
399
+ let!(:person) do
400
+ Person.find_or_create_by!(title: "Senorita")
401
+ end
402
+
403
+ it "creates a persisted document" do
404
+ expect(person).to be_persisted
405
+ end
406
+
407
+ it "sets the attributes" do
408
+ expect(person.title).to eq("Senorita")
409
+ end
410
+ end
411
+
412
+ context "when validation fails" do
413
+
414
+ before do
415
+ Person.validates_presence_of(:title)
416
+ end
417
+
418
+ after do
419
+ Person.reset_callbacks(:validate)
420
+ end
421
+
422
+ it "raises an exception" do
423
+ expect {
424
+ Person.find_or_create_by!(ssn: "test")
425
+ }.to raise_error(Mongoid::Errors::Validations)
426
+ end
427
+ end
428
+
429
+ context "when providing a block" do
430
+
431
+ let!(:person) do
432
+ Person.find_or_create_by!(title: "Senorita") do |person|
433
+ person.pets = true
434
+ end
435
+ end
436
+
437
+ it "creates a persisted document" do
438
+ expect(person).to be_persisted
439
+ end
440
+
441
+ it "sets the attributes" do
442
+ expect(person.title).to eq("Senorita")
443
+ end
444
+
445
+ it "calls the block" do
446
+ expect(person.pets).to be true
447
+ end
448
+ end
449
+ end
450
+ end
451
+
452
+ describe ".find_or_initialize_by" do
453
+
454
+ context "when the document is found" do
455
+
456
+ let!(:person) do
457
+ Person.create(title: "Senior")
458
+ end
459
+
460
+ it "returns the document" do
461
+ expect(Person.find_or_initialize_by(title: "Senior")).to eq(person)
462
+ end
463
+ end
464
+
465
+ context "when the document is not found" do
466
+
467
+ context "when not providing a block" do
468
+
469
+ let!(:person) do
470
+ Person.find_or_initialize_by(title: "Senorita")
471
+ end
472
+
473
+ it "creates a new document" do
474
+ expect(person).to be_new_record
475
+ end
476
+
477
+ it "sets the attributes" do
478
+ expect(person.title).to eq("Senorita")
479
+ end
480
+ end
481
+
482
+ context "when providing a block" do
483
+
484
+ let!(:person) do
485
+ Person.find_or_initialize_by(title: "Senorita") do |person|
486
+ person.pets = true
487
+ end
488
+ end
489
+
490
+ it "creates a new document" do
491
+ expect(person).to be_new_record
492
+ end
493
+
494
+ it "sets the attributes" do
495
+ expect(person.title).to eq("Senorita")
496
+ end
497
+
498
+ it "calls the block" do
499
+ expect(person.pets).to be true
500
+ end
501
+ end
502
+ end
503
+ end
504
+
505
+ describe "first_or_create" do
506
+
507
+ let!(:band) do
508
+ Band.create(name: "Depeche Mode")
509
+ end
510
+
511
+ context "when the document is found" do
512
+
513
+ let(:found) do
514
+ Band.where(name: "Depeche Mode").first_or_create
515
+ end
516
+
517
+ it "returns the document" do
518
+ expect(found).to eq(band)
519
+ end
520
+ end
521
+
522
+ context "when the document is not found" do
523
+
524
+ context "when attributes are provided" do
525
+
526
+ let(:document) do
527
+ Band.where(name: "Tool").first_or_create(origin: "Essex")
528
+ end
529
+
530
+ it "returns a new document" do
531
+ expect(document.name).to eq("Tool")
532
+ end
533
+
534
+ it "returns a persisted document" do
535
+ expect(document).to be_persisted
536
+ end
537
+
538
+ it "sets the additional attributes" do
539
+ expect(document.origin).to eq("Essex")
540
+ end
541
+ end
542
+
543
+ context "when attributes are not provided" do
544
+
545
+ let(:document) do
546
+ Band.where(name: "Tool").first_or_create
547
+ end
548
+
549
+ it "returns a new document" do
550
+ expect(document.name).to eq("Tool")
551
+ end
552
+
553
+ it "returns a persisted document" do
554
+ expect(document).to be_persisted
555
+ end
556
+ end
557
+
558
+ context "when the criteria is on an embedded relation" do
559
+
560
+ let!(:band) do
561
+ Band.create(name: "Placebo")
562
+ end
563
+
564
+ let(:document) do
565
+ band.notes.permanent.first_or_create(text: "test")
566
+ end
567
+
568
+ it "returns a new document" do
569
+ expect(document.text).to eq("test")
570
+ end
571
+
572
+ it "returns a persisted document" do
573
+ expect(document).to be_persisted
574
+ end
575
+ end
576
+
577
+ context "when a block is provided" do
578
+
579
+ let(:document) do
580
+ Band.where(name: "Tool").first_or_create do |doc|
581
+ doc.active = false
582
+ end
583
+ end
584
+
585
+ it "returns a new document" do
586
+ expect(document.name).to eq("Tool")
587
+ end
588
+
589
+ it "returns a persisted document" do
590
+ expect(document).to be_persisted
591
+ end
592
+
593
+ it "yields to the block" do
594
+ expect(document.active).to be false
595
+ end
596
+ end
597
+
598
+ context "when the criteria is complex" do
599
+
600
+ context "when the document is not found" do
601
+
602
+ let(:document) do
603
+ Band.in(name: [ "New Order" ]).first_or_create(active: false)
604
+ end
605
+
606
+ it "returns a new document" do
607
+ expect(document.active).to be false
608
+ end
609
+
610
+ it "returns a persisted document" do
611
+ expect(document).to be_persisted
612
+ end
613
+ end
614
+ end
615
+ end
616
+ end
617
+
618
+ describe "first_or_create!" do
619
+
620
+ context "when validation fails on the new document" do
621
+
622
+ it "raises an error" do
623
+ expect {
624
+ Account.where(number: "12345").first_or_create!
625
+ }.to raise_error(Mongoid::Errors::Validations)
626
+ end
627
+ end
628
+
629
+ context "when passing a block" do
630
+
631
+ let(:account) do
632
+ Account.where(number: "12345").first_or_create! do |account|
633
+ account.name = "testing"
634
+ end
635
+ end
636
+
637
+ it "passes the block to the create call" do
638
+ expect(account.name).to eq("testing")
639
+ end
640
+
641
+ it "persists the new document" do
642
+ expect(account).to be_persisted
643
+ end
644
+ end
645
+
646
+ context "when the document is found" do
647
+
648
+ let!(:band) do
649
+ Band.create!(name: "Depeche Mode")
650
+ end
651
+
652
+ let(:found) do
653
+ Band.where(name: "Depeche Mode").first_or_create!
654
+ end
655
+
656
+ it "returns the document" do
657
+ expect(found).to eq(band)
658
+ end
659
+ end
660
+
661
+ context "when the document is not found" do
662
+
663
+ let!(:band) do
664
+ Band.create!(name: "Depeche Mode")
665
+ end
666
+
667
+ context "when attributes are provided" do
668
+
669
+ let(:document) do
670
+ Band.where(name: "Tool").first_or_create!(origin: "Essex")
671
+ end
672
+
673
+ it "returns a new document" do
674
+ expect(document.name).to eq("Tool")
675
+ end
676
+
677
+ it "returns a persisted document" do
678
+ expect(document).to be_persisted
679
+ end
680
+
681
+ it "sets the additional attributes" do
682
+ expect(document.origin).to eq("Essex")
683
+ end
684
+ end
685
+
686
+ context "when attributes are not provided" do
687
+
688
+ let(:document) do
689
+ Band.where(name: "Tool").first_or_create!
690
+ end
691
+
692
+ it "returns a new document" do
693
+ expect(document.name).to eq("Tool")
694
+ end
695
+
696
+ it "returns a persisted document" do
697
+ expect(document).to be_persisted
698
+ end
699
+ end
700
+
701
+ context "when a block is provided" do
702
+
703
+ let(:document) do
704
+ Band.where(name: "Tool").first_or_create! do |doc|
705
+ doc.active = false
706
+ end
707
+ end
708
+
709
+ it "returns a new document" do
710
+ expect(document.name).to eq("Tool")
711
+ end
712
+
713
+ it "returns a persisted document" do
714
+ expect(document).to be_persisted
715
+ end
716
+
717
+ it "yields to the block" do
718
+ expect(document.active).to be false
719
+ end
720
+ end
721
+
722
+ context "when the criteria is complex" do
723
+
724
+ context "when the document is not found" do
725
+
726
+ let(:document) do
727
+ Band.in(name: [ "New Order" ]).first_or_create!(active: false)
728
+ end
729
+
730
+ it "returns a new document" do
731
+ expect(document.active).to be false
732
+ end
733
+
734
+ it "returns a persisted document" do
735
+ expect(document).to be_persisted
736
+ end
737
+ end
738
+ end
739
+ end
740
+ end
741
+
742
+ describe "first_or_initialize" do
743
+
744
+ let!(:band) do
745
+ Band.create(name: "Depeche Mode")
746
+ end
747
+
748
+ context "when the document is found" do
749
+
750
+ let(:found) do
751
+ Band.where(name: "Depeche Mode").first_or_initialize
752
+ end
753
+
754
+ it "returns the document" do
755
+ expect(found).to eq(band)
756
+ end
757
+ end
758
+
759
+ context "when the document is not found" do
760
+
761
+ context "when attributes are provided" do
762
+
763
+ let(:document) do
764
+ Band.where(name: "Tool").first_or_initialize(origin: "Essex")
765
+ end
766
+
767
+ it "returns a new document" do
768
+ expect(document.name).to eq("Tool")
769
+ end
770
+
771
+ it "returns a non persisted document" do
772
+ expect(document).to_not be_persisted
773
+ end
774
+
775
+ it "sets the additional attributes" do
776
+ expect(document.origin).to eq("Essex")
777
+ end
778
+ end
779
+
780
+ context "when attributes are not provided" do
781
+
782
+ let(:document) do
783
+ Band.where(name: "Tool").first_or_initialize
784
+ end
785
+
786
+ it "returns a new document" do
787
+ expect(document.name).to eq("Tool")
788
+ end
789
+
790
+ it "returns a non persisted document" do
791
+ expect(document).to_not be_persisted
792
+ end
793
+ end
794
+
795
+ context "when a block is provided" do
796
+
797
+ let(:document) do
798
+ Band.where(name: "Tool").first_or_initialize do |doc|
799
+ doc.active = false
800
+ end
801
+ end
802
+
803
+ it "returns a new document" do
804
+ expect(document.name).to eq("Tool")
805
+ end
806
+
807
+ it "returns a non persisted document" do
808
+ expect(document).to_not be_persisted
809
+ end
810
+
811
+ it "yields to the block" do
812
+ expect(document.active).to be false
813
+ end
814
+ end
815
+
816
+ context "when the criteria is complex" do
817
+
818
+ context "when the document is not found" do
819
+
820
+ let(:document) do
821
+ Band.in(name: [ "New Order" ]).first_or_initialize(active: false)
822
+ end
823
+
824
+ it "returns a new document" do
825
+ expect(document.active).to be false
826
+ end
827
+
828
+ it "returns a non persisted document" do
829
+ expect(document).to_not be_persisted
830
+ end
831
+ end
832
+ end
833
+ end
834
+ end
835
+
836
+ describe "#update" do
837
+
838
+ let!(:person) do
839
+ Person.create!(title: "Sir")
840
+ end
841
+
842
+ let!(:address_one) do
843
+ person.addresses.create(street: "Oranienstr")
844
+ end
845
+
846
+ let!(:address_two) do
847
+ person.addresses.create(street: "Wienerstr")
848
+ end
849
+
850
+ context "when updating the root document" do
851
+
852
+ context "when updating with a criteria" do
853
+
854
+ before do
855
+ Person.where(title: "Sir").update(title: "Madam")
856
+ end
857
+
858
+ it "updates all the matching documents" do
859
+ expect(person.reload.title).to eq("Madam")
860
+ end
861
+ end
862
+
863
+ context "when updating all directly" do
864
+
865
+ before do
866
+ Person.update(title: "Madam")
867
+ end
868
+
869
+ it "updates all the matching documents" do
870
+ expect(person.reload.title).to eq("Madam")
871
+ end
872
+ end
873
+ end
874
+
875
+ context "when updating an embedded document" do
876
+
877
+ before do
878
+ Person.where(title: "Sir").update(
879
+ "addresses.0.city" => "Berlin"
880
+ )
881
+ end
882
+
883
+ let!(:from_db) do
884
+ Person.first
885
+ end
886
+
887
+ it "updates all the matching documents" do
888
+ expect(from_db.addresses.first.city).to eq("Berlin")
889
+ end
890
+
891
+ it "does not update non matching documents" do
892
+ expect(from_db.addresses.last.city).to be_nil
893
+ end
894
+ end
895
+
896
+ context "when updating a relation" do
897
+
898
+ context "when the relation is an embeds many" do
899
+
900
+ let(:from_db) do
901
+ Person.first
902
+ end
903
+
904
+ context "when updating the relation directly" do
905
+
906
+ before do
907
+ person.addresses.update(city: "London")
908
+ end
909
+
910
+ it "updates the first document" do
911
+ expect(from_db.addresses.first.city).to eq("London")
912
+ end
913
+
914
+ it "does not update the last document" do
915
+ expect(from_db.addresses.last.city).to be_nil
916
+ end
917
+ end
918
+
919
+ context "when updating the relation through a criteria" do
920
+
921
+ before do
922
+ person.addresses.where(street: "Oranienstr").update(city: "Berlin")
923
+ end
924
+
925
+ it "updates the matching documents" do
926
+ expect(from_db.addresses.first.city).to eq("Berlin")
927
+ end
928
+
929
+ it "does not update non matching documents" do
930
+ expect(from_db.addresses.last.city).to be_nil
931
+ end
932
+ end
933
+ end
934
+
935
+ context "when the relation is a references many" do
936
+
937
+ before do
938
+ person.posts.create!(title: "First")
939
+ person.posts.create!(title: "Second")
940
+ end
941
+
942
+ context "when updating the relation directly" do
943
+
944
+ before do
945
+ person.posts.update(title: "London")
946
+ end
947
+
948
+ let(:from_db) do
949
+ Person.first
950
+ end
951
+
952
+ it "updates the first document" do
953
+ expect(from_db.posts.map(&:title)).to eq(["London", "Second"])
954
+ end
955
+
956
+ it "does not update the last document" do
957
+ expect(from_db.posts.last.title).to eq("Second")
958
+ end
959
+ end
960
+
961
+ context "when updating the relation through a criteria" do
962
+
963
+ before do
964
+ person.posts.where(title: "First").update(title: "Berlin")
965
+ end
966
+
967
+ let!(:from_db) do
968
+ Person.first
969
+ end
970
+
971
+ it "updates the matching documents" do
972
+ expect(from_db.posts.where(title: "Berlin").count).to eq(1)
973
+ end
974
+
975
+ it "does not update non matching documents" do
976
+ expect(from_db.posts.where(title: "Second").count).to eq(1)
977
+ end
978
+ end
979
+ end
980
+
981
+ context "when the relation is a references many to many" do
982
+
983
+ let(:from_db) do
984
+ Person.first
985
+ end
986
+
987
+ let!(:preference_one) do
988
+ person.preferences.create(name: "First")
989
+ end
990
+
991
+ let!(:preference_two) do
992
+ person.preferences.create(name: "Second")
993
+ end
994
+
995
+ context "when updating the relation directly" do
996
+
997
+ before do
998
+ person.preferences.update(name: "London")
999
+ end
1000
+
1001
+ it "updates the first document" do
1002
+ expect(from_db.preferences.first.name).to eq("London")
1003
+ end
1004
+
1005
+ it "does not update the last document" do
1006
+ expect(from_db.preferences.last.name).to eq("Second")
1007
+ end
1008
+ end
1009
+
1010
+ context "when updating the relation through a criteria" do
1011
+
1012
+ before do
1013
+ person.preferences.where(name: "First").update(name: "Berlin")
1014
+ end
1015
+
1016
+ it "updates the matching documents" do
1017
+ expect(from_db.preferences.first.name).to eq("Berlin")
1018
+ end
1019
+
1020
+ it "does not update non matching documents" do
1021
+ expect(from_db.preferences.last.name).to eq("Second")
1022
+ end
1023
+ end
1024
+ end
1025
+ end
1026
+ end
1027
+
1028
+ describe "#update_all" do
1029
+
1030
+ let!(:person) do
1031
+ Person.create(title: "Sir")
1032
+ end
1033
+
1034
+ let!(:address_one) do
1035
+ person.addresses.create(street: "Oranienstr")
1036
+ end
1037
+
1038
+ let!(:address_two) do
1039
+ person.addresses.create(street: "Wienerstr")
1040
+ end
1041
+
1042
+ context "when updating the root document" do
1043
+
1044
+ context "when updating with a criteria" do
1045
+
1046
+ let(:from_db) do
1047
+ Person.first
1048
+ end
1049
+
1050
+ before do
1051
+ Person.where(title: "Sir").update_all(title: "Madam")
1052
+ end
1053
+
1054
+ it "updates all the matching documents" do
1055
+ expect(from_db.title).to eq("Madam")
1056
+ end
1057
+ end
1058
+
1059
+ context "when updating all directly" do
1060
+
1061
+ let(:from_db) do
1062
+ Person.first
1063
+ end
1064
+
1065
+ before do
1066
+ Person.update_all(title: "Madam")
1067
+ end
1068
+
1069
+ it "updates all the matching documents" do
1070
+ expect(from_db.title).to eq("Madam")
1071
+ end
1072
+ end
1073
+ end
1074
+
1075
+ context "when updating an embedded document" do
1076
+
1077
+ before do
1078
+ Person.where(title: "Sir").update_all(
1079
+ "addresses.0.city" => "Berlin"
1080
+ )
1081
+ end
1082
+
1083
+ let!(:from_db) do
1084
+ Person.first
1085
+ end
1086
+
1087
+ it "updates all the matching documents" do
1088
+ expect(from_db.addresses.first.city).to eq("Berlin")
1089
+ end
1090
+
1091
+ it "does not update non matching documents" do
1092
+ expect(from_db.addresses.last.city).to be_nil
1093
+ end
1094
+ end
1095
+
1096
+ context "when updating a relation" do
1097
+
1098
+ context "when the relation is an embeds many" do
1099
+
1100
+ let(:from_db) do
1101
+ Person.first
1102
+ end
1103
+
1104
+ context "when updating the relation directly" do
1105
+
1106
+ before do
1107
+ person.addresses.update_all(city: "London")
1108
+ end
1109
+
1110
+ it "updates the first document" do
1111
+ expect(from_db.addresses.first.city).to eq("London")
1112
+ end
1113
+
1114
+ it "updates the last document" do
1115
+ expect(from_db.addresses.last.city).to eq("London")
1116
+ end
1117
+ end
1118
+
1119
+ context "when updating the relation through a criteria" do
1120
+
1121
+ before do
1122
+ person.addresses.where(street: "Oranienstr").update_all(city: "Berlin")
1123
+ end
1124
+
1125
+ it "updates the matching documents" do
1126
+ expect(from_db.addresses.first.city).to eq("Berlin")
1127
+ end
1128
+
1129
+ it "does not update non matching documents" do
1130
+ expect(from_db.addresses.last.city).to be_nil
1131
+ end
1132
+ end
1133
+ end
1134
+
1135
+ context "when the relation is a references many" do
1136
+
1137
+ let!(:post_one) do
1138
+ person.posts.create(title: "First")
1139
+ end
1140
+
1141
+ let!(:post_two) do
1142
+ person.posts.create(title: "Second")
1143
+ end
1144
+
1145
+ context "when updating the relation directly" do
1146
+
1147
+ before do
1148
+ person.posts.update_all(title: "London")
1149
+ end
1150
+
1151
+ let!(:from_db) do
1152
+ Person.first
1153
+ end
1154
+
1155
+ it "updates the first document" do
1156
+ expect(from_db.posts.first.title).to eq("London")
1157
+ end
1158
+
1159
+ it "updates the last document" do
1160
+ expect(from_db.posts.last.title).to eq("London")
1161
+ end
1162
+ end
1163
+
1164
+ context "when updating the relation through a criteria" do
1165
+
1166
+ before do
1167
+ person.posts.where(title: "First").update_all(title: "Berlin")
1168
+ end
1169
+
1170
+ let!(:from_db) do
1171
+ Person.first
1172
+ end
1173
+
1174
+ it "updates the matching documents" do
1175
+ expect(from_db.posts.where(title: "Berlin").count).to eq(1)
1176
+ end
1177
+
1178
+ it "does not update non matching documents" do
1179
+ expect(from_db.posts.where(title: "Second").count).to eq(1)
1180
+ end
1181
+ end
1182
+ end
1183
+
1184
+ context "when the relation is a references many to many" do
1185
+
1186
+ let(:from_db) do
1187
+ Person.first
1188
+ end
1189
+
1190
+ let!(:preference_one) do
1191
+ person.preferences.create(name: "First")
1192
+ end
1193
+
1194
+ let!(:preference_two) do
1195
+ person.preferences.create(name: "Second")
1196
+ end
1197
+
1198
+ context "when updating the relation directly" do
1199
+
1200
+ before do
1201
+ person.preferences.update_all(name: "London")
1202
+ end
1203
+
1204
+ it "updates the first document" do
1205
+ expect(from_db.preferences.first.name).to eq("London")
1206
+ end
1207
+
1208
+ it "updates the last document" do
1209
+ expect(from_db.preferences.last.name).to eq("London")
1210
+ end
1211
+ end
1212
+
1213
+ context "when updating the relation through a criteria" do
1214
+
1215
+ before do
1216
+ person.preferences.where(name: "First").update_all(name: "Berlin")
1217
+ end
1218
+
1219
+ it "updates the matching documents" do
1220
+ expect(from_db.preferences.first.name).to eq("Berlin")
1221
+ end
1222
+
1223
+ it "does not update non matching documents" do
1224
+ expect(from_db.preferences.last.name).to eq("Second")
1225
+ end
1226
+ end
1227
+ end
1228
+ end
1229
+
1230
+ context "when update document structure" do
1231
+
1232
+ before do
1233
+ person = Person.new(username: "user_title", score: 25)
1234
+ person.save
1235
+ end
1236
+
1237
+ let(:from_db) do
1238
+ Person.last
1239
+ end
1240
+
1241
+ it "rename document string field" do
1242
+ Person.where(username: "user_title").update_all("$rename" => { username: "title" })
1243
+ expect(from_db.title).to eq("user_title")
1244
+ end
1245
+
1246
+ it "rename document integer field" do
1247
+ Person.where(score: 25).update_all("$rename" => { score: "age" })
1248
+ expect(from_db.age).to eq( 25 )
1249
+ end
1250
+ end
1251
+ end
1252
+ end