mongoid 3.1.6 → 4.0.0

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