mongoid 3.1.7 → 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 (567) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +470 -9
  3. data/README.md +10 -7
  4. data/lib/config/locales/en.yml +34 -20
  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 +3 -14
  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 -99
  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/memory.rb +2 -2
  19. data/lib/mongoid/contextual/aggregable/mongo.rb +5 -9
  20. data/lib/mongoid/contextual/atomic.rb +53 -53
  21. data/lib/mongoid/contextual/geo_near.rb +1 -1
  22. data/lib/mongoid/contextual/map_reduce.rb +4 -2
  23. data/lib/mongoid/contextual/memory.rb +23 -11
  24. data/lib/mongoid/contextual/mongo.rb +75 -57
  25. data/lib/mongoid/contextual/none.rb +90 -0
  26. data/lib/mongoid/contextual/text_search.rb +178 -0
  27. data/lib/mongoid/contextual.rb +2 -0
  28. data/lib/mongoid/copyable.rb +2 -3
  29. data/lib/mongoid/{criterion → criteria}/findable.rb +7 -47
  30. data/lib/mongoid/{criterion/inspection.rb → criteria/inspectable.rb} +2 -2
  31. data/lib/mongoid/{criterion → criteria}/marshalable.rb +3 -1
  32. data/lib/mongoid/{criterion → criteria}/modifiable.rb +28 -8
  33. data/lib/mongoid/criteria/permission.rb +70 -0
  34. data/lib/mongoid/{criterion/scoping.rb → criteria/scopable.rb} +2 -2
  35. data/lib/mongoid/criteria.rb +39 -34
  36. data/lib/mongoid/document.rb +39 -24
  37. data/lib/mongoid/errors/document_not_destroyed.rb +25 -0
  38. data/lib/mongoid/errors/document_not_found.rb +2 -1
  39. data/lib/mongoid/errors/invalid_storage_options.rb +1 -1
  40. data/lib/mongoid/errors/invalid_storage_parent.rb +26 -0
  41. data/lib/mongoid/errors/invalid_value.rb +16 -0
  42. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  43. data/lib/mongoid/errors/readonly_document.rb +24 -0
  44. data/lib/mongoid/errors.rb +4 -1
  45. data/lib/mongoid/extensions/array.rb +3 -3
  46. data/lib/mongoid/extensions/big_decimal.rb +1 -1
  47. data/lib/mongoid/extensions/boolean.rb +15 -17
  48. data/lib/mongoid/extensions/date.rb +1 -1
  49. data/lib/mongoid/extensions/date_time.rb +3 -3
  50. data/lib/mongoid/extensions/float.rb +2 -1
  51. data/lib/mongoid/extensions/hash.rb +3 -3
  52. data/lib/mongoid/extensions/integer.rb +1 -1
  53. data/lib/mongoid/extensions/object.rb +7 -7
  54. data/lib/mongoid/extensions/object_id.rb +5 -5
  55. data/lib/mongoid/extensions/range.rb +9 -3
  56. data/lib/mongoid/extensions/regexp.rb +1 -1
  57. data/lib/mongoid/extensions/set.rb +1 -1
  58. data/lib/mongoid/extensions/string.rb +6 -18
  59. data/lib/mongoid/extensions/symbol.rb +1 -1
  60. data/lib/mongoid/extensions/time.rb +3 -3
  61. data/lib/mongoid/extensions/time_with_zone.rb +1 -1
  62. data/lib/mongoid/extensions.rb +15 -7
  63. data/lib/mongoid/factory.rb +8 -6
  64. data/lib/mongoid/fields/foreign_key.rb +3 -3
  65. data/lib/mongoid/fields/localized.rb +1 -1
  66. data/lib/mongoid/fields/standard.rb +5 -17
  67. data/lib/mongoid/fields/validators/macro.rb +15 -5
  68. data/lib/mongoid/fields.rb +41 -8
  69. data/lib/mongoid/{finders.rb → findable.rb} +35 -7
  70. data/lib/mongoid/indexable/specification.rb +104 -0
  71. data/lib/mongoid/{indexes → indexable}/validators/options.rb +2 -1
  72. data/lib/mongoid/{indexes.rb → indexable.rb} +50 -55
  73. data/lib/mongoid/{inspection.rb → inspectable.rb} +15 -11
  74. data/lib/mongoid/{callbacks.rb → interceptable.rb} +30 -62
  75. data/lib/mongoid/log_subscriber.rb +55 -0
  76. data/lib/mongoid/{matchers → matchable}/all.rb +1 -1
  77. data/lib/mongoid/{matchers → matchable}/and.rb +2 -2
  78. data/lib/mongoid/{matchers → matchable}/default.rb +1 -1
  79. data/lib/mongoid/{matchers → matchable}/exists.rb +1 -1
  80. data/lib/mongoid/{matchers → matchable}/gt.rb +1 -1
  81. data/lib/mongoid/{matchers → matchable}/gte.rb +1 -1
  82. data/lib/mongoid/{matchers → matchable}/in.rb +2 -2
  83. data/lib/mongoid/{matchers → matchable}/lt.rb +1 -1
  84. data/lib/mongoid/{matchers → matchable}/lte.rb +1 -1
  85. data/lib/mongoid/{matchers → matchable}/ne.rb +1 -1
  86. data/lib/mongoid/{matchers → matchable}/nin.rb +3 -2
  87. data/lib/mongoid/{matchers → matchable}/or.rb +2 -2
  88. data/lib/mongoid/{matchers → matchable}/size.rb +1 -1
  89. data/lib/mongoid/matchable.rb +152 -0
  90. data/lib/mongoid/persistable/creatable.rb +189 -0
  91. data/lib/mongoid/persistable/deletable.rb +149 -0
  92. data/lib/mongoid/persistable/destroyable.rb +60 -0
  93. data/lib/mongoid/persistable/incrementable.rb +36 -0
  94. data/lib/mongoid/persistable/logical.rb +38 -0
  95. data/lib/mongoid/persistable/poppable.rb +39 -0
  96. data/lib/mongoid/persistable/pullable.rb +55 -0
  97. data/lib/mongoid/persistable/pushable.rb +62 -0
  98. data/lib/mongoid/persistable/renamable.rb +35 -0
  99. data/lib/mongoid/persistable/savable.rb +52 -0
  100. data/lib/mongoid/persistable/settable.rb +33 -0
  101. data/lib/mongoid/persistable/unsettable.rb +36 -0
  102. data/lib/mongoid/persistable/updatable.rb +153 -0
  103. data/lib/mongoid/persistable/upsertable.rb +55 -0
  104. data/lib/mongoid/persistable.rb +216 -0
  105. data/lib/mongoid/positional.rb +71 -0
  106. data/lib/mongoid/query_cache.rb +255 -0
  107. data/lib/mongoid/railtie.rb +34 -60
  108. data/lib/mongoid/railties/database.rake +9 -25
  109. data/lib/mongoid/relations/accessors.rb +15 -51
  110. data/lib/mongoid/relations/auto_save.rb +15 -36
  111. data/lib/mongoid/relations/binding.rb +2 -25
  112. data/lib/mongoid/relations/bindings/embedded/in.rb +1 -1
  113. data/lib/mongoid/relations/bindings/embedded/many.rb +1 -3
  114. data/lib/mongoid/relations/bindings/referenced/in.rb +3 -8
  115. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +4 -2
  116. data/lib/mongoid/relations/builder.rb +1 -1
  117. data/lib/mongoid/relations/builders/embedded/one.rb +1 -1
  118. data/lib/mongoid/relations/builders/nested_attributes/many.rb +10 -13
  119. data/lib/mongoid/relations/builders/nested_attributes/one.rb +5 -6
  120. data/lib/mongoid/relations/builders/referenced/in.rb +1 -1
  121. data/lib/mongoid/relations/builders/referenced/many.rb +1 -2
  122. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +1 -2
  123. data/lib/mongoid/relations/builders/referenced/one.rb +1 -1
  124. data/lib/mongoid/relations/builders.rb +2 -2
  125. data/lib/mongoid/relations/cascading.rb +3 -5
  126. data/lib/mongoid/relations/constraint.rb +1 -1
  127. data/lib/mongoid/relations/conversions.rb +1 -1
  128. data/lib/mongoid/relations/counter_cache.rb +39 -15
  129. data/lib/mongoid/relations/eager/base.rb +149 -0
  130. data/lib/mongoid/relations/eager/belongs_to.rb +31 -0
  131. data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +47 -0
  132. data/lib/mongoid/relations/eager/has_many.rb +38 -0
  133. data/lib/mongoid/relations/eager/has_one.rb +30 -0
  134. data/lib/mongoid/relations/eager.rb +46 -0
  135. data/lib/mongoid/relations/embedded/batchable.rb +4 -5
  136. data/lib/mongoid/relations/embedded/in.rb +4 -4
  137. data/lib/mongoid/relations/embedded/many.rb +14 -32
  138. data/lib/mongoid/relations/embedded/one.rb +1 -1
  139. data/lib/mongoid/relations/macros.rb +3 -4
  140. data/lib/mongoid/relations/many.rb +51 -31
  141. data/lib/mongoid/relations/marshalable.rb +3 -3
  142. data/lib/mongoid/relations/metadata.rb +14 -79
  143. data/lib/mongoid/relations/nested_builder.rb +2 -2
  144. data/lib/mongoid/relations/one.rb +1 -1
  145. data/lib/mongoid/relations/options.rb +1 -0
  146. data/lib/mongoid/relations/polymorphic.rb +0 -1
  147. data/lib/mongoid/relations/proxy.rb +21 -41
  148. data/lib/mongoid/relations/referenced/in.rb +4 -20
  149. data/lib/mongoid/relations/referenced/many.rb +22 -35
  150. data/lib/mongoid/relations/referenced/many_to_many.rb +19 -42
  151. data/lib/mongoid/relations/referenced/one.rb +6 -25
  152. data/lib/mongoid/relations/synchronization.rb +4 -4
  153. data/lib/mongoid/relations/targets/enumerable.rb +10 -10
  154. data/lib/mongoid/relations/touchable.rb +34 -1
  155. data/lib/mongoid/relations.rb +11 -25
  156. data/lib/mongoid/{reloading.rb → reloadable.rb} +7 -5
  157. data/lib/mongoid/{scoping.rb → scopable.rb} +36 -36
  158. data/lib/mongoid/selectable.rb +59 -0
  159. data/lib/mongoid/{serialization.rb → serializable.rb} +11 -2
  160. data/lib/mongoid/sessions/factory.rb +2 -0
  161. data/lib/mongoid/sessions/options.rb +185 -0
  162. data/lib/mongoid/sessions/storage_options.rb +140 -0
  163. data/lib/mongoid/sessions/thread_options.rb +19 -0
  164. data/lib/mongoid/sessions/validators/storage.rb +16 -3
  165. data/lib/mongoid/sessions.rb +37 -345
  166. data/lib/mongoid/{sharding.rb → shardable.rb} +5 -1
  167. data/lib/mongoid/{state.rb → stateful.rb} +13 -1
  168. data/lib/mongoid/support/query_counter.rb +23 -0
  169. data/lib/mongoid/tasks/database.rake +31 -0
  170. data/lib/mongoid/tasks/database.rb +107 -0
  171. data/lib/mongoid/threaded/lifecycle.rb +0 -28
  172. data/lib/mongoid/threaded.rb +26 -172
  173. data/lib/mongoid/timestamps/updated/short.rb +2 -2
  174. data/lib/mongoid/{hierarchy.rb → traversable.rb} +15 -7
  175. data/lib/mongoid/{validations → validatable}/associated.rb +4 -2
  176. data/lib/mongoid/{validations → validatable}/format.rb +1 -1
  177. data/lib/mongoid/{validations → validatable}/length.rb +1 -1
  178. data/lib/mongoid/{validations → validatable}/localizable.rb +1 -1
  179. data/lib/mongoid/{validations → validatable}/macros.rb +4 -3
  180. data/lib/mongoid/{validations → validatable}/presence.rb +1 -1
  181. data/lib/mongoid/{validations → validatable}/queryable.rb +1 -2
  182. data/lib/mongoid/{validations → validatable}/uniqueness.rb +25 -21
  183. data/lib/mongoid/{validations.rb → validatable.rb} +23 -10
  184. data/lib/mongoid/version.rb +1 -1
  185. data/lib/mongoid.rb +10 -76
  186. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +46 -25
  187. data/lib/rails/generators/mongoid/model/model_generator.rb +0 -1
  188. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +0 -3
  189. data/lib/rails/generators/mongoid_generator.rb +3 -40
  190. data/lib/rails/mongoid.rb +0 -122
  191. data/lib/support/ruby_version.rb +1 -1
  192. data/spec/app/models/account.rb +2 -6
  193. data/spec/app/models/acolyte.rb +2 -1
  194. data/spec/app/models/actor.rb +0 -1
  195. data/spec/app/models/address.rb +8 -3
  196. data/spec/app/models/animal.rb +1 -1
  197. data/spec/app/models/appointment.rb +3 -3
  198. data/spec/app/models/article.rb +1 -4
  199. data/spec/app/models/audio.rb +5 -0
  200. data/spec/app/models/author.rb +0 -2
  201. data/spec/app/models/band.rb +3 -2
  202. data/spec/app/models/bar.rb +1 -0
  203. data/spec/app/models/book.rb +1 -0
  204. data/spec/app/models/building.rb +0 -2
  205. data/spec/app/models/building_address.rb +0 -2
  206. data/spec/app/models/bus.rb +1 -1
  207. data/spec/app/models/canvas.rb +1 -1
  208. data/spec/app/models/contextable_item.rb +5 -0
  209. data/spec/app/models/contractor.rb +0 -2
  210. data/spec/app/models/country_code.rb +1 -1
  211. data/spec/app/models/definition.rb +2 -2
  212. data/spec/app/models/dog.rb +1 -1
  213. data/spec/app/models/dragon.rb +4 -0
  214. data/spec/app/models/drug.rb +1 -3
  215. data/spec/app/models/dungeon.rb +4 -0
  216. data/spec/app/models/edit.rb +5 -0
  217. data/spec/app/models/even.rb +7 -0
  218. data/spec/app/models/event.rb +1 -1
  219. data/spec/app/models/filesystem.rb +1 -0
  220. data/spec/app/models/fish.rb +0 -1
  221. data/spec/app/models/fruits.rb +6 -0
  222. data/spec/app/models/game.rb +0 -2
  223. data/spec/app/models/house.rb +1 -3
  224. data/spec/app/models/id_key.rb +6 -0
  225. data/spec/app/models/item.rb +1 -5
  226. data/spec/app/models/jar.rb +1 -1
  227. data/spec/app/models/label.rb +4 -4
  228. data/spec/app/models/line_item.rb +1 -1
  229. data/spec/app/models/login.rb +1 -1
  230. data/spec/app/models/message.rb +8 -0
  231. data/spec/app/models/movie.rb +1 -0
  232. data/spec/app/models/name.rb +3 -3
  233. data/spec/app/models/note.rb +3 -1
  234. data/spec/app/models/odd.rb +7 -0
  235. data/spec/app/models/oscar.rb +1 -1
  236. data/spec/app/models/parent_doc.rb +1 -1
  237. data/spec/app/models/person.rb +16 -10
  238. data/spec/app/models/phone.rb +1 -3
  239. data/spec/app/models/player.rb +3 -3
  240. data/spec/app/models/post.rb +5 -3
  241. data/spec/app/models/preference.rb +1 -1
  242. data/spec/app/models/quiz.rb +0 -3
  243. data/spec/app/models/record.rb +10 -5
  244. data/spec/app/models/registry.rb +1 -1
  245. data/spec/app/models/server.rb +1 -1
  246. data/spec/app/models/service.rb +3 -3
  247. data/spec/app/models/sound.rb +5 -0
  248. data/spec/app/models/symptom.rb +1 -1
  249. data/spec/app/models/template.rb +1 -1
  250. data/spec/app/models/title.rb +0 -1
  251. data/spec/app/models/track.rb +5 -5
  252. data/spec/app/models/tree.rb +3 -3
  253. data/spec/app/models/video.rb +1 -5
  254. data/spec/app/models/wiki_page.rb +2 -5
  255. data/spec/app/models/word.rb +3 -0
  256. data/spec/app/models/word_origin.rb +1 -1
  257. data/spec/config/mongoid.yml +7 -8
  258. data/spec/helpers.rb +18 -0
  259. data/spec/mongoid/atomic/modifiers_spec.rb +22 -22
  260. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +8 -49
  261. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +7 -49
  262. data/spec/mongoid/atomic/paths/root_spec.rb +3 -61
  263. data/spec/mongoid/atomic/paths_spec.rb +19 -19
  264. data/spec/mongoid/atomic_spec.rb +19 -19
  265. data/spec/mongoid/{nested_attributes_spec.rb → attributes/nested_spec.rb} +474 -592
  266. data/spec/mongoid/attributes/readonly_spec.rb +58 -18
  267. data/spec/mongoid/attributes_spec.rb +334 -434
  268. data/spec/mongoid/{dirty_spec.rb → changeable_spec.rb} +203 -153
  269. data/spec/mongoid/{components_spec.rb → composable_spec.rb} +3 -3
  270. data/spec/mongoid/config/environment_spec.rb +3 -3
  271. data/spec/mongoid/config/options_spec.rb +6 -6
  272. data/spec/mongoid/config_spec.rb +24 -48
  273. data/spec/mongoid/contextual/aggregable/memory_spec.rb +12 -12
  274. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +46 -38
  275. data/spec/mongoid/contextual/atomic_spec.rb +59 -55
  276. data/spec/mongoid/contextual/find_and_modify_spec.rb +14 -14
  277. data/spec/mongoid/contextual/geo_near_spec.rb +22 -22
  278. data/spec/mongoid/contextual/map_reduce_spec.rb +27 -27
  279. data/spec/mongoid/contextual/memory_spec.rb +156 -94
  280. data/spec/mongoid/contextual/mongo_spec.rb +238 -150
  281. data/spec/mongoid/contextual/none_spec.rb +127 -0
  282. data/spec/mongoid/contextual/text_search_spec.rb +209 -0
  283. data/spec/mongoid/copyable_spec.rb +56 -68
  284. data/spec/mongoid/criteria/findable_spec.rb +991 -0
  285. data/spec/mongoid/{criterion/inspection_spec.rb → criteria/inspectable_spec.rb} +5 -5
  286. data/spec/mongoid/{criterion → criteria}/marshalable_spec.rb +2 -2
  287. data/spec/mongoid/criteria/modifiable_spec.rb +1252 -0
  288. data/spec/mongoid/{criterion/scoping_spec.rb → criteria/scopable_spec.rb} +37 -37
  289. data/spec/mongoid/criteria_spec.rb +713 -2419
  290. data/spec/mongoid/document_spec.rb +171 -121
  291. data/spec/mongoid/equality_spec.rb +22 -22
  292. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +3 -3
  293. data/spec/mongoid/errors/callback_spec.rb +3 -3
  294. data/spec/mongoid/errors/delete_restriction_spec.rb +3 -3
  295. data/spec/mongoid/errors/document_not_destroyed_spec.rb +33 -0
  296. data/spec/mongoid/errors/document_not_found_spec.rb +11 -11
  297. data/spec/mongoid/errors/eager_load_spec.rb +3 -3
  298. data/spec/mongoid/errors/invalid_collection_spec.rb +3 -3
  299. data/spec/mongoid/errors/invalid_config_option_spec.rb +3 -3
  300. data/spec/mongoid/errors/invalid_field_option_spec.rb +3 -3
  301. data/spec/mongoid/errors/invalid_field_spec.rb +3 -3
  302. data/spec/mongoid/errors/invalid_find_spec.rb +3 -3
  303. data/spec/mongoid/errors/invalid_includes_spec.rb +3 -3
  304. data/spec/mongoid/errors/invalid_index_spec.rb +3 -3
  305. data/spec/mongoid/errors/invalid_options_spec.rb +3 -3
  306. data/spec/mongoid/errors/invalid_path_spec.rb +3 -3
  307. data/spec/mongoid/errors/invalid_scope_spec.rb +5 -5
  308. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +3 -3
  309. data/spec/mongoid/errors/invalid_storage_options_spec.rb +3 -3
  310. data/spec/mongoid/errors/invalid_time_spec.rb +3 -3
  311. data/spec/mongoid/errors/inverse_not_found_spec.rb +3 -3
  312. data/spec/mongoid/errors/mixed_relations_spec.rb +3 -3
  313. data/spec/mongoid/errors/mixed_session_configuration_spec.rb +3 -3
  314. data/spec/mongoid/errors/mongoid_error_spec.rb +8 -8
  315. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +3 -3
  316. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  317. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +3 -3
  318. data/spec/mongoid/errors/no_metadata_spec.rb +3 -3
  319. data/spec/mongoid/errors/no_parent_spec.rb +3 -3
  320. data/spec/mongoid/errors/no_session_config_spec.rb +3 -3
  321. data/spec/mongoid/errors/no_session_database_spec.rb +3 -3
  322. data/spec/mongoid/errors/no_session_hosts_spec.rb +3 -3
  323. data/spec/mongoid/errors/no_sessions_config_spec.rb +3 -3
  324. data/spec/mongoid/errors/readonly_attribute_spec.rb +3 -3
  325. data/spec/mongoid/errors/readonly_document_spec.rb +29 -0
  326. data/spec/mongoid/errors/scope_overwrite_spec.rb +3 -3
  327. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +3 -3
  328. data/spec/mongoid/errors/unknown_attribute_spec.rb +5 -5
  329. data/spec/mongoid/errors/unsaved_document_spec.rb +3 -3
  330. data/spec/mongoid/errors/unsupported_javascript_spec.rb +3 -3
  331. data/spec/mongoid/errors/validations_spec.rb +7 -7
  332. data/spec/mongoid/extensions/array_spec.rb +61 -61
  333. data/spec/mongoid/extensions/big_decimal_spec.rb +11 -11
  334. data/spec/mongoid/extensions/binary_spec.rb +12 -12
  335. data/spec/mongoid/extensions/boolean_spec.rb +18 -18
  336. data/spec/mongoid/extensions/date_spec.rb +13 -13
  337. data/spec/mongoid/extensions/date_time_spec.rb +8 -8
  338. data/spec/mongoid/extensions/false_class_spec.rb +5 -5
  339. data/spec/mongoid/extensions/float_spec.rb +29 -15
  340. data/spec/mongoid/extensions/hash_spec.rb +29 -29
  341. data/spec/mongoid/extensions/integer_spec.rb +15 -15
  342. data/spec/mongoid/extensions/module_spec.rb +2 -2
  343. data/spec/mongoid/extensions/nil_class_spec.rb +1 -1
  344. data/spec/mongoid/extensions/object_id_spec.rb +134 -134
  345. data/spec/mongoid/extensions/object_spec.rb +26 -26
  346. data/spec/mongoid/extensions/range_spec.rb +61 -12
  347. data/spec/mongoid/extensions/regexp_spec.rb +4 -4
  348. data/spec/mongoid/extensions/set_spec.rb +4 -4
  349. data/spec/mongoid/extensions/string_spec.rb +35 -46
  350. data/spec/mongoid/extensions/symbol_spec.rb +9 -9
  351. data/spec/mongoid/extensions/time_spec.rb +49 -49
  352. data/spec/mongoid/extensions/time_with_zone_spec.rb +34 -34
  353. data/spec/mongoid/extensions/true_class_spec.rb +5 -5
  354. data/spec/mongoid/extensions_spec.rb +29 -0
  355. data/spec/mongoid/factory_spec.rb +15 -15
  356. data/spec/mongoid/fields/foreign_key_spec.rb +73 -66
  357. data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +15 -15
  358. data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +22 -22
  359. data/spec/mongoid/fields/localized_spec.rb +38 -23
  360. data/spec/mongoid/fields/standard_spec.rb +12 -12
  361. data/spec/mongoid/fields_spec.rb +263 -217
  362. data/spec/mongoid/findable_spec.rb +509 -0
  363. data/spec/mongoid/indexable/specification_spec.rb +102 -0
  364. data/spec/mongoid/{indexes_spec.rb → indexable_spec.rb} +171 -51
  365. data/spec/mongoid/{inspection_spec.rb → inspectable_spec.rb} +6 -14
  366. data/spec/mongoid/{callbacks_spec.rb → interceptable_spec.rb} +117 -116
  367. data/spec/mongoid/log_subscriber_spec.rb +75 -0
  368. data/spec/mongoid/loggable_spec.rb +1 -1
  369. data/spec/mongoid/{matchers → matchable}/all_spec.rb +4 -4
  370. data/spec/mongoid/{matchers → matchable}/and_spec.rb +11 -11
  371. data/spec/mongoid/{matchers → matchable}/default_spec.rb +15 -15
  372. data/spec/mongoid/{matchers → matchable}/exists_spec.rb +5 -5
  373. data/spec/mongoid/{matchers → matchable}/gt_spec.rb +9 -8
  374. data/spec/mongoid/{matchers → matchable}/gte_spec.rb +7 -7
  375. data/spec/mongoid/matchable/in_spec.rb +49 -0
  376. data/spec/mongoid/{matchers → matchable}/lt_spec.rb +7 -7
  377. data/spec/mongoid/{matchers → matchable}/lte_spec.rb +7 -7
  378. data/spec/mongoid/{matchers → matchable}/ne_spec.rb +3 -3
  379. data/spec/mongoid/matchable/nin_spec.rb +48 -0
  380. data/spec/mongoid/{matchers → matchable}/or_spec.rb +6 -6
  381. data/spec/mongoid/{matchers → matchable}/size_spec.rb +3 -3
  382. data/spec/mongoid/{matchers_spec.rb → matchable_spec.rb} +41 -41
  383. data/spec/mongoid/persistable/creatable_spec.rb +553 -0
  384. data/spec/mongoid/persistable/deletable_spec.rb +218 -0
  385. data/spec/mongoid/persistable/destroyable_spec.rb +192 -0
  386. data/spec/mongoid/persistable/incrementable_spec.rb +173 -0
  387. data/spec/mongoid/persistable/logical_spec.rb +143 -0
  388. data/spec/mongoid/persistable/poppable_spec.rb +115 -0
  389. data/spec/mongoid/persistable/pullable_spec.rb +228 -0
  390. data/spec/mongoid/persistable/pushable_spec.rb +258 -0
  391. data/spec/mongoid/persistable/renamable_spec.rb +135 -0
  392. data/spec/mongoid/persistable/savable_spec.rb +498 -0
  393. data/spec/mongoid/persistable/settable_spec.rb +162 -0
  394. data/spec/mongoid/persistable/unsettable_spec.rb +155 -0
  395. data/spec/mongoid/persistable/updatable_spec.rb +558 -0
  396. data/spec/mongoid/persistable/upsertable_spec.rb +106 -0
  397. data/spec/mongoid/persistable_spec.rb +206 -0
  398. data/spec/mongoid/{atomic/positionable_spec.rb → positional_spec.rb} +9 -9
  399. data/spec/mongoid/query_cache_spec.rb +263 -0
  400. data/spec/mongoid/railties/document_spec.rb +2 -2
  401. data/spec/mongoid/relations/accessors_spec.rb +53 -145
  402. data/spec/mongoid/relations/auto_save_spec.rb +37 -17
  403. data/spec/mongoid/relations/bindings/embedded/in_spec.rb +12 -12
  404. data/spec/mongoid/relations/bindings/embedded/many_spec.rb +3 -3
  405. data/spec/mongoid/relations/bindings/embedded/one_spec.rb +5 -5
  406. data/spec/mongoid/relations/bindings/referenced/in_spec.rb +26 -26
  407. data/spec/mongoid/relations/bindings/referenced/many_spec.rb +10 -10
  408. data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +19 -19
  409. data/spec/mongoid/relations/bindings/referenced/one_spec.rb +12 -12
  410. data/spec/mongoid/relations/builders/embedded/in_spec.rb +4 -4
  411. data/spec/mongoid/relations/builders/embedded/many_spec.rb +18 -18
  412. data/spec/mongoid/relations/builders/embedded/one_spec.rb +11 -11
  413. data/spec/mongoid/relations/builders/nested_attributes/many_spec.rb +12 -13
  414. data/spec/mongoid/relations/builders/nested_attributes/one_spec.rb +14 -14
  415. data/spec/mongoid/relations/builders/referenced/in_spec.rb +24 -35
  416. data/spec/mongoid/relations/builders/referenced/many_spec.rb +15 -15
  417. data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +18 -18
  418. data/spec/mongoid/relations/builders/referenced/one_spec.rb +12 -25
  419. data/spec/mongoid/relations/builders_spec.rb +21 -21
  420. data/spec/mongoid/relations/cascading/delete_spec.rb +9 -9
  421. data/spec/mongoid/relations/cascading/destroy_spec.rb +6 -6
  422. data/spec/mongoid/relations/cascading/nullify_spec.rb +4 -4
  423. data/spec/mongoid/relations/cascading/restrict_spec.rb +7 -7
  424. data/spec/mongoid/relations/cascading_spec.rb +16 -16
  425. data/spec/mongoid/relations/constraint_spec.rb +8 -7
  426. data/spec/mongoid/relations/conversions_spec.rb +16 -14
  427. data/spec/mongoid/relations/counter_cache_spec.rb +85 -0
  428. data/spec/mongoid/relations/cyclic_spec.rb +18 -18
  429. data/spec/mongoid/relations/eager/belongs_to_spec.rb +154 -0
  430. data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +117 -0
  431. data/spec/mongoid/relations/eager/has_many_spec.rb +207 -0
  432. data/spec/mongoid/relations/eager/has_one_spec.rb +163 -0
  433. data/spec/mongoid/relations/eager_spec.rb +228 -0
  434. data/spec/mongoid/relations/embedded/dirty_spec.rb +8 -8
  435. data/spec/mongoid/relations/embedded/in_spec.rb +56 -57
  436. data/spec/mongoid/relations/embedded/many_spec.rb +467 -372
  437. data/spec/mongoid/relations/embedded/one_spec.rb +108 -141
  438. data/spec/mongoid/relations/macros_spec.rb +108 -102
  439. data/spec/mongoid/relations/metadata_spec.rb +180 -255
  440. data/spec/mongoid/relations/options_spec.rb +1 -1
  441. data/spec/mongoid/relations/polymorphic_spec.rb +13 -17
  442. data/spec/mongoid/relations/proxy_spec.rb +2 -2
  443. data/spec/mongoid/relations/referenced/in_spec.rb +128 -303
  444. data/spec/mongoid/relations/referenced/many_spec.rb +587 -527
  445. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +401 -424
  446. data/spec/mongoid/relations/referenced/one_spec.rb +149 -264
  447. data/spec/mongoid/relations/reflections_spec.rb +6 -6
  448. data/spec/mongoid/relations/synchronization_spec.rb +46 -50
  449. data/spec/mongoid/relations/targets/enumerable_spec.rb +118 -118
  450. data/spec/mongoid/relations/touchable_spec.rb +333 -0
  451. data/spec/mongoid/relations_spec.rb +16 -15
  452. data/spec/mongoid/{reloading_spec.rb → reloadable_spec.rb} +38 -55
  453. data/spec/mongoid/{scoping_spec.rb → scopable_spec.rb} +89 -164
  454. data/spec/mongoid/selectable_spec.rb +134 -0
  455. data/spec/mongoid/{serialization_spec.rb → serializable_spec.rb} +129 -82
  456. data/spec/mongoid/sessions/factory_spec.rb +49 -28
  457. data/spec/mongoid/sessions/mongo_uri_spec.rb +7 -7
  458. data/spec/mongoid/sessions/options_spec.rb +108 -0
  459. data/spec/mongoid/sessions_spec.rb +319 -178
  460. data/spec/mongoid/{sharding_spec.rb → shardable_spec.rb} +8 -8
  461. data/spec/mongoid/{state_spec.rb → stateful_spec.rb} +36 -11
  462. data/spec/mongoid/tasks/database_rake_spec.rb +285 -0
  463. data/spec/mongoid/tasks/database_spec.rb +160 -0
  464. data/spec/mongoid/threaded_spec.rb +17 -70
  465. data/spec/mongoid/timestamps/created/short_spec.rb +6 -6
  466. data/spec/mongoid/timestamps/created_spec.rb +5 -5
  467. data/spec/mongoid/timestamps/timeless_spec.rb +6 -6
  468. data/spec/mongoid/timestamps/updated/short_spec.rb +11 -11
  469. data/spec/mongoid/timestamps/updated_spec.rb +9 -13
  470. data/spec/mongoid/timestamps_spec.rb +9 -13
  471. data/spec/mongoid/{hierarchy_spec.rb → traversable_spec.rb} +19 -19
  472. data/spec/mongoid/{validations → validatable}/associated_spec.rb +45 -22
  473. data/spec/mongoid/{validations → validatable}/format_spec.rb +6 -6
  474. data/spec/mongoid/{validations → validatable}/length_spec.rb +14 -14
  475. data/spec/mongoid/{validations → validatable}/numericality_spec.rb +1 -1
  476. data/spec/mongoid/{validations → validatable}/presence_spec.rb +37 -44
  477. data/spec/mongoid/{validations → validatable}/uniqueness_spec.rb +184 -192
  478. data/spec/mongoid/{validations_spec.rb → validatable_spec.rb} +28 -28
  479. data/spec/mongoid_spec.rb +8 -8
  480. data/spec/rails/mongoid_spec.rb +19 -350
  481. data/spec/spec_helper.rb +26 -15
  482. metadata +262 -247
  483. data/lib/mongoid/atomic/positionable.rb +0 -73
  484. data/lib/mongoid/components.rb +0 -92
  485. data/lib/mongoid/config/inflections.rb +0 -6
  486. data/lib/mongoid/contextual/eager.rb +0 -158
  487. data/lib/mongoid/errors/versioning_not_on_root.rb +0 -23
  488. data/lib/mongoid/identity_map.rb +0 -163
  489. data/lib/mongoid/json.rb +0 -16
  490. data/lib/mongoid/matchers/strategies.rb +0 -97
  491. data/lib/mongoid/matchers.rb +0 -32
  492. data/lib/mongoid/multi_parameter_attributes.rb +0 -105
  493. data/lib/mongoid/nested_attributes.rb +0 -78
  494. data/lib/mongoid/observer.rb +0 -192
  495. data/lib/mongoid/paranoia.rb +0 -136
  496. data/lib/mongoid/persistence/atomic/add_to_set.rb +0 -47
  497. data/lib/mongoid/persistence/atomic/bit.rb +0 -35
  498. data/lib/mongoid/persistence/atomic/inc.rb +0 -45
  499. data/lib/mongoid/persistence/atomic/operation.rb +0 -154
  500. data/lib/mongoid/persistence/atomic/pop.rb +0 -32
  501. data/lib/mongoid/persistence/atomic/pull.rb +0 -32
  502. data/lib/mongoid/persistence/atomic/pull_all.rb +0 -32
  503. data/lib/mongoid/persistence/atomic/push.rb +0 -25
  504. data/lib/mongoid/persistence/atomic/push_all.rb +0 -25
  505. data/lib/mongoid/persistence/atomic/rename.rb +0 -30
  506. data/lib/mongoid/persistence/atomic/sets.rb +0 -28
  507. data/lib/mongoid/persistence/atomic/unset.rb +0 -27
  508. data/lib/mongoid/persistence/atomic.rb +0 -231
  509. data/lib/mongoid/persistence/deletion.rb +0 -31
  510. data/lib/mongoid/persistence/insertion.rb +0 -38
  511. data/lib/mongoid/persistence/modification.rb +0 -35
  512. data/lib/mongoid/persistence/operations/embedded/insert.rb +0 -46
  513. data/lib/mongoid/persistence/operations/embedded/remove.rb +0 -43
  514. data/lib/mongoid/persistence/operations/insert.rb +0 -34
  515. data/lib/mongoid/persistence/operations/remove.rb +0 -33
  516. data/lib/mongoid/persistence/operations/update.rb +0 -59
  517. data/lib/mongoid/persistence/operations/upsert.rb +0 -28
  518. data/lib/mongoid/persistence/operations.rb +0 -214
  519. data/lib/mongoid/persistence/upsertion.rb +0 -31
  520. data/lib/mongoid/persistence.rb +0 -357
  521. data/lib/mongoid/unit_of_work.rb +0 -61
  522. data/lib/mongoid/versioning.rb +0 -217
  523. data/lib/rack/mongoid/middleware/identity_map.rb +0 -39
  524. data/lib/rack/mongoid.rb +0 -2
  525. data/lib/rails/generators/mongoid/observer/observer_generator.rb +0 -17
  526. data/lib/rails/generators/mongoid/observer/templates/observer.rb.tt +0 -4
  527. data/spec/app/models/actor_observer.rb +0 -15
  528. data/spec/app/models/callback_recorder.rb +0 -25
  529. data/spec/app/models/paranoid_phone.rb +0 -25
  530. data/spec/app/models/paranoid_post.rb +0 -36
  531. data/spec/app/models/phone_observer.rb +0 -6
  532. data/spec/mongoid/attributes/processing_spec.rb +0 -149
  533. data/spec/mongoid/criterion/destructive_spec.rb +0 -101
  534. data/spec/mongoid/criterion/modifiable_spec.rb +0 -409
  535. data/spec/mongoid/criterion/modification_spec.rb +0 -402
  536. data/spec/mongoid/errors/versioning_not_on_root_spec.rb +0 -29
  537. data/spec/mongoid/finders_spec.rb +0 -321
  538. data/spec/mongoid/identity_map_spec.rb +0 -564
  539. data/spec/mongoid/json_spec.rb +0 -33
  540. data/spec/mongoid/matchers/in_spec.rb +0 -25
  541. data/spec/mongoid/matchers/nin_spec.rb +0 -25
  542. data/spec/mongoid/multi_parameter_attributes_spec.rb +0 -128
  543. data/spec/mongoid/observer_spec.rb +0 -290
  544. data/spec/mongoid/paranoia_spec.rb +0 -759
  545. data/spec/mongoid/persistence/atomic/add_to_set_spec.rb +0 -262
  546. data/spec/mongoid/persistence/atomic/bit_spec.rb +0 -88
  547. data/spec/mongoid/persistence/atomic/inc_spec.rb +0 -133
  548. data/spec/mongoid/persistence/atomic/pop_spec.rb +0 -111
  549. data/spec/mongoid/persistence/atomic/pull_all_spec.rb +0 -77
  550. data/spec/mongoid/persistence/atomic/pull_spec.rb +0 -80
  551. data/spec/mongoid/persistence/atomic/push_all_spec.rb +0 -77
  552. data/spec/mongoid/persistence/atomic/push_spec.rb +0 -77
  553. data/spec/mongoid/persistence/atomic/rename_spec.rb +0 -42
  554. data/spec/mongoid/persistence/atomic/sets_spec.rb +0 -154
  555. data/spec/mongoid/persistence/atomic/unset_spec.rb +0 -65
  556. data/spec/mongoid/persistence/atomic_spec.rb +0 -216
  557. data/spec/mongoid/persistence/operations/embedded/insert_spec.rb +0 -191
  558. data/spec/mongoid/persistence/operations/embedded/remove_spec.rb +0 -8
  559. data/spec/mongoid/persistence/operations/insert_spec.rb +0 -149
  560. data/spec/mongoid/persistence/operations/remove_spec.rb +0 -113
  561. data/spec/mongoid/persistence/operations/update_spec.rb +0 -141
  562. data/spec/mongoid/persistence/operations/upsert_spec.rb +0 -59
  563. data/spec/mongoid/persistence/operations_spec.rb +0 -313
  564. data/spec/mongoid/persistence_spec.rb +0 -2279
  565. data/spec/mongoid/unit_of_work_spec.rb +0 -196
  566. data/spec/mongoid/versioning_spec.rb +0 -540
  567. data/spec/rack/mongoid/middleware/identity_map_spec.rb +0 -72
@@ -0,0 +1,152 @@
1
+ # encoding: utf-8
2
+ require "mongoid/matchable/default"
3
+ require "mongoid/matchable/all"
4
+ require "mongoid/matchable/and"
5
+ require "mongoid/matchable/exists"
6
+ require "mongoid/matchable/gt"
7
+ require "mongoid/matchable/gte"
8
+ require "mongoid/matchable/in"
9
+ require "mongoid/matchable/lt"
10
+ require "mongoid/matchable/lte"
11
+ require "mongoid/matchable/ne"
12
+ require "mongoid/matchable/nin"
13
+ require "mongoid/matchable/or"
14
+ require "mongoid/matchable/size"
15
+
16
+ module Mongoid
17
+
18
+ # This module contains all the behavior for ruby implementations of MongoDB
19
+ # selectors.
20
+ #
21
+ # @since 4.0.0
22
+ module Matchable
23
+ extend ActiveSupport::Concern
24
+
25
+ # Hash lookup for the matcher for a specific operation.
26
+ #
27
+ # @since 1.0.0
28
+ MATCHERS = {
29
+ "$all" => All,
30
+ "$and" => And,
31
+ "$exists" => Exists,
32
+ "$gt" => Gt,
33
+ "$gte" => Gte,
34
+ "$in" => In,
35
+ "$lt" => Lt,
36
+ "$lte" => Lte,
37
+ "$ne" => Ne,
38
+ "$nin" => Nin,
39
+ "$or" => Or,
40
+ "$size" => Size
41
+ }.with_indifferent_access.freeze
42
+
43
+ # Determines if this document has the attributes to match the supplied
44
+ # MongoDB selector. Used for matching on embedded associations.
45
+ #
46
+ # @example Does the document match?
47
+ # document.matches?(:title => { "$in" => [ "test" ] })
48
+ #
49
+ # @param [ Hash ] selector The MongoDB selector.
50
+ #
51
+ # @return [ true, false ] True if matches, false if not.
52
+ #
53
+ # @since 1.0.0
54
+ def matches?(selector)
55
+ selector.each_pair do |key, value|
56
+ if value.is_a?(Hash)
57
+ value.each do |item|
58
+ return false unless matcher(self, key, Hash[*item]).matches?(Hash[*item])
59
+ end
60
+ else
61
+ return false unless matcher(self, key, value).matches?(value)
62
+ end
63
+ end
64
+ true
65
+ end
66
+
67
+ private
68
+
69
+ # Get the matcher for the supplied key and value. Will determine the class
70
+ # name from the key.
71
+ #
72
+ # @api private
73
+ #
74
+ # @example Get the matcher.
75
+ # document.matcher(:title, { "$in" => [ "test" ] })
76
+ #
77
+ # @param [ Document ] document The document to check.
78
+ # @param [ Symbol, String ] key The field name.
79
+ # @param [ Object, Hash ] The value or selector.
80
+ #
81
+ # @return [ Matcher ] The matcher.
82
+ #
83
+ # @since 2.0.0.rc.7
84
+ def matcher(document, key, value)
85
+ Matchable.matcher(document, key, value)
86
+ end
87
+
88
+ class << self
89
+
90
+ # Get the matcher for the supplied key and value. Will determine the class
91
+ # name from the key.
92
+ #
93
+ # @api private
94
+ #
95
+ # @example Get the matcher.
96
+ # document.matcher(:title, { "$in" => [ "test" ] })
97
+ #
98
+ # @param [ Document ] document The document to check.
99
+ # @param [ Symbol, String ] key The field name.
100
+ # @param [ Object, Hash ] The value or selector.
101
+ #
102
+ # @return [ Matcher ] The matcher.
103
+ #
104
+ # @since 2.0.0.rc.7
105
+ def matcher(document, key, value)
106
+ if value.is_a?(Hash)
107
+ matcher = MATCHERS[value.keys.first]
108
+ if matcher
109
+ matcher.new(extract_attribute(document, key))
110
+ else
111
+ Default.new(extract_attribute(document, key))
112
+ end
113
+ else
114
+ case key.to_s
115
+ when "$or" then Or.new(value, document)
116
+ when "$and" then And.new(value, document)
117
+ else Default.new(extract_attribute(document, key))
118
+ end
119
+ end
120
+ end
121
+
122
+ private
123
+
124
+ # Extract the attribute from the key, being smarter about dot notation.
125
+ #
126
+ # @api private
127
+ #
128
+ # @example Extract the attribute.
129
+ # strategy.extract_attribute(doc, "info.field")
130
+ #
131
+ # @param [ Document ] document The document.
132
+ # @param [ String ] key The key.
133
+ #
134
+ # @return [ Object ] The value of the attribute.
135
+ #
136
+ # @since 2.2.1
137
+ def extract_attribute(document, key)
138
+ if (key_string = key.to_s) =~ /.+\..+/
139
+ key_string.split('.').inject(document.as_document) do |_attribs, _key|
140
+ if _attribs.is_a?(::Array)
141
+ _attribs.map { |doc| doc.try(:[], _key) }
142
+ else
143
+ _attribs.try(:[], _key)
144
+ end
145
+ end
146
+ else
147
+ document.attributes[key_string]
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,189 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Persistable
4
+
5
+ # Defines behaviour for persistence operations that create new documents.
6
+ #
7
+ # @since 4.0.0
8
+ module Creatable
9
+ extend ActiveSupport::Concern
10
+
11
+ # Insert a new document into the database. Will return the document
12
+ # itself whether or not the save was successful.
13
+ #
14
+ # @example Insert a document.
15
+ # document.insert
16
+ #
17
+ # @param [ Hash ] options Options to pass to insert.
18
+ #
19
+ # @return [ Document ] The persisted document.
20
+ #
21
+ # @since 1.0.0
22
+ def insert(options = {})
23
+ prepare_insert(options) do
24
+ if embedded?
25
+ insert_as_embedded
26
+ else
27
+ insert_as_root
28
+ end
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ # Get the atomic insert for embedded documents, either a push or set.
35
+ #
36
+ # @api private
37
+ #
38
+ # @example Get the inserts.
39
+ # document.inserts
40
+ #
41
+ # @return [ Hash ] The insert ops.
42
+ #
43
+ # @since 2.1.0
44
+ def atomic_inserts
45
+ { atomic_insert_modifier => { atomic_position => as_document }}
46
+ end
47
+
48
+ # Insert the embedded document.
49
+ #
50
+ # @api private
51
+ #
52
+ # @example Insert the document as embedded.
53
+ # document.insert_as_embedded
54
+ #
55
+ # @return [ Document ] The document.
56
+ #
57
+ # @since 4.0.0
58
+ def insert_as_embedded
59
+ raise Errors::NoParent.new(self.class.name) unless _parent
60
+ if _parent.new_record?
61
+ _parent.insert
62
+ else
63
+ selector = _parent.atomic_selector
64
+ _root.collection.find(selector).update(positionally(selector, atomic_inserts))
65
+ end
66
+ end
67
+
68
+ # Insert the root document.
69
+ #
70
+ # @api private
71
+ #
72
+ # @example Insert the document as root.
73
+ # document.insert_as_root
74
+ #
75
+ # @return [ Document ] The document.
76
+ #
77
+ # @since 4.0.0
78
+ def insert_as_root
79
+ collection.insert(as_document)
80
+ end
81
+
82
+ # Post process an insert, which sets the new record attribute to false
83
+ # and flags all the children as persisted.
84
+ #
85
+ # @api private
86
+ #
87
+ # @example Post process the insert.
88
+ # document.post_process_insert
89
+ #
90
+ # @return [ true ] true.
91
+ #
92
+ # @since 4.0.0
93
+ def post_process_insert
94
+ self.new_record = false
95
+ flag_children_persisted
96
+ true
97
+ end
98
+
99
+ # Prepare the insert for execution. Validates and runs callbacks, etc.
100
+ #
101
+ # @api private
102
+ #
103
+ # @example Prepare for insertion.
104
+ # document.prepare_insert do
105
+ # collection.insert(as_document)
106
+ # end
107
+ #
108
+ # @param [ Hash ] options The options.
109
+ #
110
+ # @return [ Document ] The document.
111
+ #
112
+ # @since 4.0.0
113
+ def prepare_insert(options = {})
114
+ return self if performing_validations?(options) &&
115
+ invalid?(options[:context] || :create)
116
+ result = run_callbacks(:save) do
117
+ run_callbacks(:create) do
118
+ yield(self)
119
+ post_process_insert
120
+ end
121
+ end
122
+ post_process_persist(result, options) and self
123
+ end
124
+
125
+ module ClassMethods
126
+
127
+ # Create a new document. This will instantiate a new document and
128
+ # insert it in a single call. Will always return the document
129
+ # whether save passed or not.
130
+ #
131
+ # @example Create a new document.
132
+ # Person.create(:title => "Mr")
133
+ #
134
+ # @example Create multiple new documents.
135
+ # Person.create({ title: "Mr" }, { title: "Mrs" })
136
+ #
137
+ # @param [ Hash, Array ] attributes The attributes to create with, or an
138
+ # Array of multiple attributes for multiple documents.
139
+ #
140
+ # @return [ Document, Array<Document> ] The newly created document(s).
141
+ #
142
+ # @since 1.0.0
143
+ def create(attributes = nil, &block)
144
+ _creating do
145
+ if attributes.is_a?(::Array)
146
+ attributes.map { |attrs| create(attrs, &block) }
147
+ else
148
+ doc = new(attributes, &block)
149
+ doc.save
150
+ doc
151
+ end
152
+ end
153
+ end
154
+
155
+ # Create a new document. This will instantiate a new document and
156
+ # insert it in a single call. Will always return the document
157
+ # whether save passed or not, and if validation fails an error will be
158
+ # raise.
159
+ #
160
+ # @example Create a new document.
161
+ # Person.create!(:title => "Mr")
162
+ #
163
+ # @example Create multiple new documents.
164
+ # Person.create!({ title: "Mr" }, { title: "Mrs" })
165
+ #
166
+ # @param [ Hash, Array ] attributes The attributes to create with, or an
167
+ # Array of multiple attributes for multiple documents.
168
+ # @param [ Hash ] options A mass-assignment protection options. Supports
169
+ # :as and :without_protection
170
+ #
171
+ # @return [ Document, Array<Document> ] The newly created document(s).
172
+ #
173
+ # @since 1.0.0
174
+ def create!(attributes = nil, &block)
175
+ _creating do
176
+ if attributes.is_a?(::Array)
177
+ attributes.map { |attrs| create!(attrs, &block) }
178
+ else
179
+ doc = new(attributes, &block)
180
+ doc.fail_due_to_validation! unless doc.insert.errors.empty?
181
+ doc.fail_due_to_callback!(:create!) if doc.new_record?
182
+ doc
183
+ end
184
+ end
185
+ end
186
+ end
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,149 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Persistable
4
+
5
+ # Defines behaviour for persistence operations that delete documents.
6
+ #
7
+ # @since 4.0.0
8
+ module Deletable
9
+ extend ActiveSupport::Concern
10
+
11
+ # Remove the document from the database.
12
+ #
13
+ # @example Remove the document.
14
+ # document.remove
15
+ #
16
+ # @param [ Hash ] options Options to pass to remove.
17
+ #
18
+ # @return [ TrueClass ] True.
19
+ #
20
+ # @since 1.0.0
21
+ def delete(options = {})
22
+ raise Errors::ReadonlyDocument.new(self.class) if readonly?
23
+ prepare_delete do
24
+ if embedded?
25
+ delete_as_embedded(options)
26
+ else
27
+ delete_as_root
28
+ end
29
+ end
30
+ end
31
+ alias :remove :delete
32
+
33
+ private
34
+
35
+ # Get the atomic deletes for the operation.
36
+ #
37
+ # @api private
38
+ #
39
+ # @example Get the atomic deletes.
40
+ # document.atomic_deletes
41
+ #
42
+ # @return [ Hash ] The atomic deletes.
43
+ #
44
+ # @since 4.0.0
45
+ def atomic_deletes
46
+ { atomic_delete_modifier => { atomic_path => _index ? { "_id" => id } : true }}
47
+ end
48
+
49
+ # Delete the embedded document.
50
+ #
51
+ # @api private
52
+ #
53
+ # @example Delete the embedded document.
54
+ # document.delete_as_embedded
55
+ #
56
+ # @param [ Hash ] options The deletion options.
57
+ #
58
+ # @return [ true ] If the operation succeeded.
59
+ #
60
+ # @since 4.0.0
61
+ def delete_as_embedded(options = {})
62
+ _parent.remove_child(self) if notifying_parent?(options)
63
+ if _parent.persisted?
64
+ selector = _parent.atomic_selector
65
+ _root.collection.find(selector).update(positionally(selector, atomic_deletes))
66
+ end
67
+ true
68
+ end
69
+
70
+ # Delete the root document.
71
+ #
72
+ # @api private
73
+ #
74
+ # @example Delete the root document.
75
+ # document.delete_as_root
76
+ #
77
+ # @return [ true ] If the document was removed.
78
+ #
79
+ # @since 4.0.0
80
+ def delete_as_root
81
+ collection.find(atomic_selector).remove
82
+ true
83
+ end
84
+
85
+ # Are we needing to notify the parent document of the deletion.
86
+ #
87
+ # @api private
88
+ #
89
+ # @example Are we notifying the parent.
90
+ # document.notifying_parent?(suppress: true)
91
+ #
92
+ # @param [ Hash ] options The delete options.
93
+ #
94
+ # @return [ true, false ] If the parent should be notified.
95
+ #
96
+ # @since 4.0.0
97
+ def notifying_parent?(options = {})
98
+ !options.delete(:suppress)
99
+ end
100
+
101
+ # Prepare the delete operation.
102
+ #
103
+ # @api private
104
+ #
105
+ # @example Prepare the delete operation.
106
+ # document.prepare_delete do
107
+ # collection.find(atomic_selector).remove
108
+ # end
109
+ #
110
+ # @return [ Object ] The result of the block.
111
+ #
112
+ # @since 4.0.0
113
+ def prepare_delete
114
+ cascade!
115
+ yield(self)
116
+ freeze
117
+ self.destroyed = true
118
+ true
119
+ end
120
+
121
+ module ClassMethods
122
+
123
+ # Delete all documents given the supplied conditions. If no conditions
124
+ # are passed, the entire collection will be dropped for performance
125
+ # benefits. Does not fire any callbacks.
126
+ #
127
+ # @example Delete matching documents from the collection.
128
+ # Person.delete_all({ :title => "Sir" })
129
+ #
130
+ # @example Delete all documents from the collection.
131
+ # Person.delete_all
132
+ #
133
+ # @param [ Hash ] conditions Optional conditions to delete by.
134
+ #
135
+ # @return [ Integer ] The number of documents deleted.
136
+ #
137
+ # @since 1.0.0
138
+ def delete_all(conditions = nil)
139
+ selector = conditions || {}
140
+ selector.merge!(_type: name) if hereditary?
141
+ coll = collection
142
+ deleted = coll.find(selector).count
143
+ coll.find(selector).remove_all
144
+ deleted
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,60 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Persistable
4
+
5
+ # Defines behaviour for persistence operations that destroy documents.
6
+ #
7
+ # @since 4.0.0
8
+ module Destroyable
9
+ extend ActiveSupport::Concern
10
+
11
+ # Remove the document from the database with callbacks.
12
+ #
13
+ # @example Destroy a document.
14
+ # document.destroy
15
+ #
16
+ # @param [ Hash ] options Options to pass to destroy.
17
+ #
18
+ # @return [ true, false ] True if successful, false if not.
19
+ #
20
+ # @since 1.0.0
21
+ def destroy(options = nil)
22
+ raise Errors::ReadonlyDocument.new(self.class) if readonly?
23
+ self.flagged_for_destroy = true
24
+ result = run_callbacks(:destroy) { delete(options || {}) }
25
+ self.flagged_for_destroy = false
26
+ result
27
+ end
28
+
29
+ def destroy!(options = {})
30
+ destroy || raise(Errors::DocumentNotDestroyed.new(id, self.class))
31
+ end
32
+
33
+ module ClassMethods
34
+
35
+ # Delete all documents given the supplied conditions. If no conditions
36
+ # are passed, the entire collection will be dropped for performance
37
+ # benefits. Fires the destroy callbacks if conditions were passed.
38
+ #
39
+ # @example Destroy matching documents from the collection.
40
+ # Person.destroy_all({ :title => "Sir" })
41
+ #
42
+ # @example Destroy all documents from the collection.
43
+ # Person.destroy_all
44
+ #
45
+ # @param [ Hash ] conditions Optional conditions to destroy by.
46
+ #
47
+ # @return [ Integer ] The number of documents destroyed.
48
+ #
49
+ # @since 1.0.0
50
+ def destroy_all(conditions = nil)
51
+ selector = conditions || {}
52
+ documents = where(selector)
53
+ destroyed = documents.count
54
+ documents.each { |doc| doc.destroy }
55
+ destroyed
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Persistable
4
+
5
+ # Defines behaviour for $inc operations.
6
+ #
7
+ # @since 4.0.0
8
+ module Incrementable
9
+ extend ActiveSupport::Concern
10
+
11
+ # Increment the provided fields by the corresponding values. Values can
12
+ # be positive or negative, and if no value exists for the field it will
13
+ # be set with the provided value.
14
+ #
15
+ # @example Increment the fields.
16
+ # document.inc(score: 10, place: 1, lives: -10)
17
+ #
18
+ # @param [ Hash ] increments The field/inc increment pairs.
19
+ #
20
+ # @return [ true, false ] If the increment succeeded.
21
+ #
22
+ # @since 4.0.0
23
+ def inc(increments)
24
+ prepare_atomic_operation do |ops|
25
+ process_atomic_operations(increments) do |field, value|
26
+ increment = value.__to_inc__
27
+ current = attributes[field]
28
+ attributes[field] = (current || 0) + increment
29
+ ops[atomic_attribute_name(field)] = increment
30
+ end
31
+ { "$inc" => ops }
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Persistable
4
+
5
+ # Defines behaviour for logical bitwise operations.
6
+ #
7
+ # @since 4.0.0
8
+ module Logical
9
+ extend ActiveSupport::Concern
10
+
11
+ # Performs an atomic $bit operation on the field with the provided hash
12
+ # of bitwise ops to execute in order.
13
+ #
14
+ # @example Execute the bitwise operations.
15
+ # person.bit(age: { :and => 12 }, val: { and: 10, or: 12 })
16
+ #
17
+ # @param [ Hash ] operations The bitwise operations.
18
+ #
19
+ # @return [ true, false ] If the operation succeeded.
20
+ #
21
+ # @since 4.0.0
22
+ def bit(operations)
23
+ prepare_atomic_operation do |ops|
24
+ process_atomic_operations(operations) do |field, values|
25
+ value = attributes[field]
26
+ values.each do |op, val|
27
+ value = value & val if op.to_s == "and"
28
+ value = value | val if op.to_s == "or"
29
+ end
30
+ attributes[field] = value
31
+ ops[atomic_attribute_name(field)] = values
32
+ end
33
+ { "$bit" => ops }
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Persistable
4
+
5
+ # Defines behaviour for $pop operations.
6
+ #
7
+ # @since 4.0.0
8
+ module Poppable
9
+ extend ActiveSupport::Concern
10
+
11
+ # Pop or shift items from arrays using the $pop operator.
12
+ #
13
+ # @example Pop items from an array.
14
+ # document.pop(aliases: 1)
15
+ #
16
+ # @example Shift items in the array.
17
+ # document.pop(aliases: -1)
18
+ #
19
+ # @example Multiple pops in one call.
20
+ # document.pop(names: 1, aliases: 1)
21
+ #
22
+ # @param [ Hash ] pops The field/value pop operations.
23
+ #
24
+ # @return [ true, false ] If the operation succeeded.
25
+ #
26
+ # @since 4.0.0
27
+ def pop(pops)
28
+ prepare_atomic_operation do |ops|
29
+ process_atomic_operations(pops) do |field, value|
30
+ values = send(field)
31
+ value > 0 ? values.pop : values.shift
32
+ ops[atomic_attribute_name(field)] = value
33
+ end
34
+ { "$pop" => ops }
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end