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
@@ -1,4 +1,7 @@
1
1
  # encoding: utf-8
2
+ require "active_model/attribute_methods"
3
+ require "mongoid/attributes/dynamic"
4
+ require "mongoid/attributes/nested"
2
5
  require "mongoid/attributes/processing"
3
6
  require "mongoid/attributes/readonly"
4
7
 
@@ -8,6 +11,7 @@ module Mongoid
8
11
  # and how to get and set values.
9
12
  module Attributes
10
13
  extend ActiveSupport::Concern
14
+ include Nested
11
15
  include Processing
12
16
  include Readonly
13
17
 
@@ -27,6 +31,8 @@ module Mongoid
27
31
  def attribute_present?(name)
28
32
  attribute = read_attribute(name)
29
33
  !attribute.blank? || attribute == false
34
+ rescue ActiveModel::MissingAttributeError
35
+ false
30
36
  end
31
37
 
32
38
  # Get the attributes that have not been cast.
@@ -87,6 +93,9 @@ module Mongoid
87
93
  # @since 1.0.0
88
94
  def read_attribute(name)
89
95
  normalized = database_field_name(name.to_s)
96
+ if attribute_missing?(normalized)
97
+ raise ActiveModel::MissingAttributeError, "Missing attribute: '#{name}'."
98
+ end
90
99
  if hash_dot_syntax?(normalized)
91
100
  attributes.__nested__(normalized)
92
101
  else
@@ -141,25 +150,6 @@ module Mongoid
141
150
  end
142
151
  end
143
152
 
144
- # Override respond_to? so it responds properly for dynamic attributes.
145
- #
146
- # @example Does this object respond to the method?
147
- # person.respond_to?(:title)
148
- #
149
- # @param [ Array ] *args The name of the method.
150
- #
151
- # @return [ true, false ] True if it does, false if not.
152
- #
153
- # @since 1.0.0
154
- def respond_to?(name, include_private = false)
155
- super || (
156
- Mongoid.allow_dynamic_fields &&
157
- attributes &&
158
- attributes.has_key?(name.to_s.reader) &&
159
- name.to_s.valid_method_name?
160
- )
161
- end
162
-
163
153
  # Write a single attribute to the document attribute hash. This will
164
154
  # also fire the before and after update callbacks, and perform any
165
155
  # necessary typecasting.
@@ -178,6 +168,7 @@ module Mongoid
178
168
  access = database_field_name(name.to_s)
179
169
  if attribute_writable?(access)
180
170
  _assigning do
171
+ validate_attribute_value(access, value)
181
172
  localized = fields[access].try(:localized?)
182
173
  attributes_before_type_cast[name.to_s] = value
183
174
  typed_value = typed_value_for(access, value)
@@ -207,12 +198,11 @@ module Mongoid
207
198
  # person.assign_attributes({ :title => "Mr." }, :as => :admin)
208
199
  #
209
200
  # @param [ Hash ] attrs The new attributes to set.
210
- # @param [ Hash ] options Supported options: :without_protection, :as
211
201
  #
212
202
  # @since 2.2.1
213
- def assign_attributes(attrs = nil, options = {})
203
+ def assign_attributes(attrs = nil)
214
204
  _assigning do
215
- process_attributes(attrs, options[:as] || :default, !options[:without_protection])
205
+ process_attributes(attrs)
216
206
  end
217
207
  end
218
208
 
@@ -230,71 +220,46 @@ module Mongoid
230
220
  # @param [ Boolean ] guard_protected_attributes False to skip mass assignment protection.
231
221
  #
232
222
  # @since 1.0.0
233
- def write_attributes(attrs = nil, guard_protected_attributes = true)
234
- assign_attributes(attrs, without_protection: !guard_protected_attributes)
223
+ def write_attributes(attrs = nil)
224
+ assign_attributes(attrs)
235
225
  end
236
226
  alias :attributes= :write_attributes
237
227
 
238
- private
239
-
240
- # Define a reader method for a dynamic attribute.
228
+ # Determine if the attribute is missing from the document, due to loading
229
+ # it from the database with missing fields.
241
230
  #
242
- # @api private
231
+ # @example Is the attribute missing?
232
+ # document.attribute_missing?("test")
243
233
  #
244
- # @example Define a reader method.
245
- # model.define_dynamic_reader(:field)
234
+ # @param [ String ] name The name of the attribute.
246
235
  #
247
- # @param [ String ] name The name of the field.
236
+ # @return [ true, false ] If the attribute is missing.
248
237
  #
249
- # @since 3.0.0
250
- def define_dynamic_reader(name)
251
- return unless name.valid_method_name?
252
-
253
- class_eval <<-READER
254
- def #{name}
255
- attribute_will_change!(#{name.inspect})
256
- read_attribute(#{name.inspect})
257
- end
258
- READER
238
+ # @since 4.0.0
239
+ def attribute_missing?(name)
240
+ selection = __selected_fields
241
+ return false unless selection
242
+ field = fields[name]
243
+ (selection.values.first == 0 && selection_excluded?(name, selection, field)) ||
244
+ (selection.values.first == 1 && !selection_included?(name, selection, field))
259
245
  end
260
246
 
261
- # Define a reader method for a dynamic attribute before type cast.
262
- #
263
- # @api private
264
- #
265
- # @example Define a reader method for an attribute.
266
- # model.define_dynamic_before_type_cast_reader(:field)
267
- #
268
- # @param [ String ] name The name of the field.
269
- #
270
- # @since 3.1.0
271
- def define_dynamic_before_type_cast_reader(name)
272
- class_eval <<-READER
273
- def #{name}_before_type_cast
274
- attribute_will_change!(#{name.inspect})
275
- read_attribute_before_type_cast(#{name.inspect})
276
- end
277
- READER
278
- end
247
+ private
279
248
 
280
- # Define a writer method for a dynamic attribute.
281
- #
282
- # @api private
283
- #
284
- # @example Define a writer method.
285
- # model.define_dynamic_writer(:field)
286
- #
287
- # @param [ String ] name The name of the field.
288
- #
289
- # @since 3.0.0
290
- def define_dynamic_writer(name)
291
- return unless name.valid_method_name?
249
+ def selection_excluded?(name, selection, field)
250
+ if field && field.localized?
251
+ selection["#{name}.#{::I18n.locale}"] == 0
252
+ else
253
+ selection[name] == 0
254
+ end
255
+ end
292
256
 
293
- class_eval <<-WRITER
294
- def #{name}=(value)
295
- write_attribute(#{name.inspect}, value)
296
- end
297
- WRITER
257
+ def selection_included?(name, selection, field)
258
+ if field && field.localized?
259
+ selection.has_key?("#{name}.#{::I18n.locale}")
260
+ else
261
+ selection.has_key?(name)
262
+ end
298
263
  end
299
264
 
300
265
  # Does the string contain dot syntax for accessing hashes?
@@ -311,29 +276,6 @@ module Mongoid
311
276
  string.include?(".")
312
277
  end
313
278
 
314
- # Used for allowing accessor methods for dynamic attributes.
315
- #
316
- # @param [ String, Symbol ] name The name of the method.
317
- # @param [ Array ] *args The arguments to the method.
318
- def method_missing(name, *args)
319
- attr = name.to_s
320
- return super unless attributes.has_key?(attr.reader)
321
- if attr.writer?
322
- getter = attr.reader
323
- define_dynamic_writer(getter)
324
- write_attribute(getter, args.first)
325
- elsif attr.before_type_cast?
326
- define_dynamic_before_type_cast_reader(attr.reader)
327
- attribute_will_change!(attr.reader)
328
- read_attribute_before_type_cast(attr.reader)
329
- else
330
- getter = attr.reader
331
- define_dynamic_reader(getter)
332
- attribute_will_change!(attr.reader)
333
- read_attribute(getter)
334
- end
335
- end
336
-
337
279
  # Return the typecasted value for a field.
338
280
  #
339
281
  # @example Get the value typecasted.
@@ -367,6 +309,7 @@ module Mongoid
367
309
  #
368
310
  # @since 2.3.0
369
311
  def alias_attribute(name, original)
312
+ aliased_fields[name.to_s] = original.to_s
370
313
  class_eval <<-RUBY
371
314
  alias #{name} #{original}
372
315
  alias #{name}= #{original}=
@@ -374,11 +317,32 @@ module Mongoid
374
317
  alias #{name}_change #{original}_change
375
318
  alias #{name}_changed? #{original}_changed?
376
319
  alias reset_#{name}! reset_#{original}!
320
+ alias reset_#{name}_to_default! reset_#{original}_to_default!
377
321
  alias #{name}_was #{original}_was
378
322
  alias #{name}_will_change! #{original}_will_change!
379
323
  alias #{name}_before_type_cast #{original}_before_type_cast
380
324
  RUBY
381
325
  end
382
326
  end
327
+
328
+ private
329
+
330
+ # Validates an attribute value. This provides validation checking if
331
+ # the value is valid for given a field.
332
+ # For now, only Hash and Array fields are validated.
333
+ #
334
+ # @param [ String, Symbol ] name The name of the attribute to validate.
335
+ # @param [ Object ] value The to be validated.
336
+ #
337
+ # @since 3.0.10
338
+ def validate_attribute_value(access, value)
339
+ return unless fields[access] && value
340
+ validatable_types = [ Hash, Array ]
341
+ if validatable_types.include? fields[access].type
342
+ unless value.is_a? fields[access].type
343
+ raise Mongoid::Errors::InvalidValue.new(fields[access].type, value.class)
344
+ end
345
+ end
346
+ end
383
347
  end
384
348
  end
@@ -1,6 +1,10 @@
1
1
  # encoding: utf-8
2
2
  module Mongoid
3
- module Dirty
3
+
4
+ # Defines behaviour for dirty tracking.
5
+ #
6
+ # @since 4.0.0
7
+ module Changeable
4
8
  extend ActiveSupport::Concern
5
9
 
6
10
  # Get the changed attributes for the document.
@@ -80,7 +84,6 @@ module Mongoid
80
84
  #
81
85
  # @since 2.1.0
82
86
  def move_changes
83
- @_children = nil
84
87
  @previous_changes = changes
85
88
  Atomic::UPDATES.each do |update|
86
89
  send(update).clear
@@ -245,6 +248,15 @@ module Mongoid
245
248
  attributes[attr] = changed_attributes.delete(attr) if attribute_changed?(attr)
246
249
  end
247
250
 
251
+ def reset_attribute_to_default!(attr)
252
+ attr = database_field_name(attr)
253
+ if field = fields[attr]
254
+ __send__("#{attr}=", field.eval_default(self))
255
+ else
256
+ __send__("#{attr}=", nil)
257
+ end
258
+ end
259
+
248
260
  module ClassMethods
249
261
 
250
262
  private
@@ -267,6 +279,7 @@ module Mongoid
267
279
  create_dirty_default_change_check(name, meth)
268
280
  create_dirty_previous_value_accessor(name, meth)
269
281
  create_dirty_reset(name, meth)
282
+ create_dirty_reset_to_default(name, meth)
270
283
  end
271
284
 
272
285
  # Creates the dirty change accessor.
@@ -370,6 +383,23 @@ module Mongoid
370
383
  end
371
384
  end
372
385
  end
386
+
387
+ # Creates the dirty change reset to default.
388
+ #
389
+ # @example Create the reset.
390
+ # Model.create_dirty_reset_to_default("name", "alias")
391
+ #
392
+ # @param [ String ] name The attribute name.
393
+ # @param [ String ] meth The name of the accessor.
394
+ #
395
+ # @since 3.0.0
396
+ def create_dirty_reset_to_default(name, meth)
397
+ generated_methods.module_eval do
398
+ re_define_method("reset_#{meth}_to_default!") do
399
+ reset_attribute_to_default!(name)
400
+ end
401
+ end
402
+ end
373
403
  end
374
404
  end
375
405
  end
@@ -0,0 +1,105 @@
1
+ # encoding: utf-8
2
+ require "mongoid/changeable"
3
+ require "mongoid/findable"
4
+ require "mongoid/indexable"
5
+ require "mongoid/inspectable"
6
+ require "mongoid/interceptable"
7
+ require "mongoid/matchable"
8
+ require "mongoid/persistable"
9
+ require "mongoid/reloadable"
10
+ require "mongoid/selectable"
11
+ require "mongoid/scopable"
12
+ require "mongoid/serializable"
13
+ require "mongoid/shardable"
14
+ require "mongoid/stateful"
15
+ require "mongoid/traversable"
16
+ require "mongoid/validatable"
17
+
18
+ module Mongoid
19
+
20
+ # This module provides inclusions of all behaviour in a Mongoid document.
21
+ #
22
+ # @since 4.0.0
23
+ module Composable
24
+ extend ActiveSupport::Concern
25
+
26
+ # All modules that a +Document+ is composed of are defined in this
27
+ # module, to keep the document class from getting too cluttered.
28
+ included do
29
+ extend Findable
30
+ end
31
+
32
+ include ActiveModel::Model
33
+ include ActiveModel::ForbiddenAttributesProtection
34
+ include ActiveModel::Serializers::JSON
35
+ include ActiveModel::Serializers::Xml
36
+ include Atomic
37
+ include Changeable
38
+ include Attributes
39
+ include Evolvable
40
+ include Fields
41
+ include Indexable
42
+ include Inspectable
43
+ include Matchable
44
+ include Persistable
45
+ include Relations
46
+ include Reloadable
47
+ include Scopable
48
+ include Selectable
49
+ include Serializable
50
+ include Sessions
51
+ include Shardable
52
+ include Stateful
53
+ include Threaded::Lifecycle
54
+ include Traversable
55
+ include Validatable
56
+ include Interceptable
57
+ include Copyable
58
+ include Equality
59
+
60
+ MODULES = [
61
+ Atomic,
62
+ Attributes,
63
+ Copyable,
64
+ Changeable,
65
+ Evolvable,
66
+ Fields,
67
+ Indexable,
68
+ Inspectable,
69
+ Interceptable,
70
+ Matchable,
71
+ Persistable,
72
+ Relations,
73
+ Reloadable,
74
+ Scopable,
75
+ Serializable,
76
+ Sessions,
77
+ Shardable,
78
+ Stateful,
79
+ Threaded::Lifecycle,
80
+ Traversable,
81
+ Validatable,
82
+ Equality,
83
+ ActiveModel::Model,
84
+ ActiveModel::Validations
85
+ ]
86
+
87
+ class << self
88
+
89
+ # Get a list of methods that would be a bad idea to define as field names
90
+ # or override when including Mongoid::Document.
91
+ #
92
+ # @example Bad thing!
93
+ # Mongoid::Components.prohibited_methods
94
+ #
95
+ # @return [ Array<Symbol> ]
96
+ #
97
+ # @since 2.1.8
98
+ def prohibited_methods
99
+ @prohibited_methods ||= MODULES.flat_map do |mod|
100
+ mod.instance_methods.map{ |m| m.to_sym }
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -20,7 +20,7 @@ module Mongoid
20
20
  # Define a configuration option with a default.
21
21
  #
22
22
  # @example Define the option.
23
- # Options.option(:persist_in_safe_mode, :default => false)
23
+ # Options.option(:persist_in_safe_mode, :default => true)
24
24
  #
25
25
  # @param [ Symbol ] name The name of the configuration option.
26
26
  # @param [ Hash ] options Extras for the option.
@@ -1,6 +1,5 @@
1
1
  # encoding: utf-8
2
2
  require "mongoid/config/environment"
3
- require "mongoid/config/inflections"
4
3
  require "mongoid/config/options"
5
4
  require "mongoid/config/validators"
6
5
 
@@ -11,23 +10,18 @@ module Mongoid
11
10
  module Config
12
11
  extend self
13
12
  extend Options
14
- include ActiveModel::Observing
15
13
 
16
14
  delegate :logger=, to: ::Mongoid
17
15
  delegate :logger, to: ::Mongoid
18
16
 
19
17
  LOCK = Mutex.new
20
18
 
21
- option :allow_dynamic_fields, default: true
22
- option :identity_map_enabled, default: false
23
19
  option :include_root_in_json, default: false
24
20
  option :include_type_for_serialization, default: false
25
21
  option :preload_models, default: false
26
- option :protect_sensitive_fields, default: true
27
22
  option :raise_not_found_error, default: true
28
23
  option :scope_overwrite_exception, default: false
29
- # @todo: Remove at 4.0
30
- option :skip_version_check, default: false
24
+ option :duplicate_fields_exception, default: false
31
25
  option :use_activesupport_time_zone, default: true
32
26
  option :use_utc, default: false
33
27
 
@@ -54,7 +48,7 @@ module Mongoid
54
48
  # @param [ String ] name The database name.
55
49
  #
56
50
  # @since 3.0.0
57
- def connect_to(name, options = { consistency: :eventual })
51
+ def connect_to(name, options = { read: :primary })
58
52
  self.sessions = {
59
53
  default: {
60
54
  database: name,
@@ -72,7 +66,7 @@ module Mongoid
72
66
  #
73
67
  # @return [ Array<String> ] An array of bad field names.
74
68
  def destructive_fields
75
- Components.prohibited_methods
69
+ Composable.prohibited_methods
76
70
  end
77
71
 
78
72
  # Load the settings from a compliant mongoid.yml file. This can be used for
@@ -81,7 +81,7 @@ module Mongoid
81
81
  if block_given?
82
82
  super()
83
83
  else
84
- count > 0 ? super(0) { |doc| doc.send(field) } : 0
84
+ count > 0 ? super(0) { |doc| doc.public_send(field) } : 0
85
85
  end
86
86
  end
87
87
 
@@ -101,7 +101,7 @@ module Mongoid
101
101
  #
102
102
  # @since 3.0.0
103
103
  def aggregate_by(field, method)
104
- count > 0 ? send(method) { |doc| doc.send(field) }.send(field) : nil
104
+ count > 0 ? send(method) { |doc| doc.public_send(field) }.public_send(field) : nil
105
105
  end
106
106
  end
107
107
  end
@@ -12,7 +12,7 @@ module Mongoid
12
12
  #
13
13
  # @param [ String, Symbol ] field The field name.
14
14
  #
15
- # @return [ Hash ] The aggregate values in the form:
15
+ # @return [ Hash ] count is a number of documents with the provided field. If there're none, then count is 0 and max, min, sum, avg are nil.
16
16
  # {
17
17
  # "count" => 2.0,
18
18
  # "max" => 1000.0,
@@ -23,15 +23,11 @@ module Mongoid
23
23
  #
24
24
  # @since 3.0.0
25
25
  def aggregates(field)
26
- if query.count > 0
27
- result = collection.aggregate(pipeline(field)).to_a
28
- if result.empty?
29
- { "count" => query.count, "avg" => 0, "sum" => 0 }
30
- else
31
- result.first
32
- end
26
+ result = collection.aggregate(pipeline(field)).to_a
27
+ if result.empty?
28
+ { "count" => 0, "sum" => nil, "avg" => nil, "min" => nil, "max" => nil }
33
29
  else
34
- { "count" => 0 }
30
+ result.first
35
31
  end
36
32
  end
37
33