mongoid 7.5.4 → 8.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (414) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +3 -3
  4. data/README.md +6 -6
  5. data/lib/config/locales/en.yml +92 -43
  6. data/lib/mongoid/association/accessors.rb +40 -11
  7. data/lib/mongoid/association/bindable.rb +50 -2
  8. data/lib/mongoid/association/builders.rb +5 -3
  9. data/lib/mongoid/association/constrainable.rb +0 -1
  10. data/lib/mongoid/association/eager_loadable.rb +29 -7
  11. data/lib/mongoid/association/embedded/batchable.rb +34 -11
  12. data/lib/mongoid/association/embedded/cyclic.rb +1 -1
  13. data/lib/mongoid/association/embedded/embedded_in/binding.rb +24 -2
  14. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +2 -2
  15. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +4 -3
  16. data/lib/mongoid/association/embedded/embedded_in.rb +3 -2
  17. data/lib/mongoid/association/embedded/embeds_many/binding.rb +1 -0
  18. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +4 -3
  19. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +69 -45
  20. data/lib/mongoid/association/embedded/embeds_many.rb +2 -2
  21. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +19 -5
  22. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +24 -5
  23. data/lib/mongoid/association/embedded/embeds_one.rb +3 -3
  24. data/lib/mongoid/association/macros.rb +8 -1
  25. data/lib/mongoid/association/many.rb +11 -7
  26. data/lib/mongoid/association/nested/many.rb +5 -4
  27. data/lib/mongoid/association/nested/nested_buildable.rb +4 -4
  28. data/lib/mongoid/association/nested/one.rb +45 -7
  29. data/lib/mongoid/association/one.rb +2 -2
  30. data/lib/mongoid/association/options.rb +9 -9
  31. data/lib/mongoid/association/proxy.rb +15 -4
  32. data/lib/mongoid/association/referenced/auto_save.rb +4 -3
  33. data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
  34. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
  35. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +5 -6
  36. data/lib/mongoid/association/referenced/belongs_to.rb +2 -2
  37. data/lib/mongoid/association/referenced/counter_cache.rb +10 -10
  38. data/lib/mongoid/association/referenced/eager.rb +2 -2
  39. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +70 -13
  40. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +6 -3
  41. data/lib/mongoid/association/referenced/has_many/enumerable.rb +22 -30
  42. data/lib/mongoid/association/referenced/has_many/proxy.rb +29 -19
  43. data/lib/mongoid/association/referenced/has_many.rb +3 -3
  44. data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -1
  45. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +5 -5
  46. data/lib/mongoid/association/referenced/has_one/proxy.rb +9 -12
  47. data/lib/mongoid/association/referenced/has_one.rb +3 -3
  48. data/lib/mongoid/association/referenced/syncable.rb +4 -4
  49. data/lib/mongoid/association/reflections.rb +4 -4
  50. data/lib/mongoid/association/relatable.rb +44 -10
  51. data/lib/mongoid/association.rb +5 -5
  52. data/lib/mongoid/atomic/modifiers.rb +2 -2
  53. data/lib/mongoid/atomic.rb +7 -0
  54. data/lib/mongoid/attributes/dynamic.rb +4 -4
  55. data/lib/mongoid/attributes/nested.rb +6 -6
  56. data/lib/mongoid/attributes/processing.rb +37 -6
  57. data/lib/mongoid/attributes/projector.rb +2 -2
  58. data/lib/mongoid/attributes/readonly.rb +3 -3
  59. data/lib/mongoid/attributes.rb +51 -42
  60. data/lib/mongoid/changeable.rb +147 -14
  61. data/lib/mongoid/clients/options.rb +5 -1
  62. data/lib/mongoid/clients/sessions.rb +2 -14
  63. data/lib/mongoid/clients/storage_options.rb +2 -5
  64. data/lib/mongoid/clients/validators/storage.rb +3 -15
  65. data/lib/mongoid/collection_configurable.rb +58 -0
  66. data/lib/mongoid/composable.rb +2 -0
  67. data/lib/mongoid/config/defaults.rb +60 -0
  68. data/lib/mongoid/config/options.rb +3 -0
  69. data/lib/mongoid/config/validators/async_query_executor.rb +24 -0
  70. data/lib/mongoid/config/validators/client.rb +6 -6
  71. data/lib/mongoid/config/validators.rb +1 -0
  72. data/lib/mongoid/config.rb +140 -18
  73. data/lib/mongoid/contextual/aggregable/memory.rb +24 -16
  74. data/lib/mongoid/contextual/aggregable/mongo.rb +5 -5
  75. data/lib/mongoid/contextual/aggregable/none.rb +1 -1
  76. data/lib/mongoid/contextual/atomic.rb +1 -1
  77. data/lib/mongoid/contextual/geo_near.rb +7 -7
  78. data/lib/mongoid/contextual/map_reduce.rb +2 -2
  79. data/lib/mongoid/contextual/memory.rb +285 -58
  80. data/lib/mongoid/contextual/mongo/documents_loader.rb +177 -0
  81. data/lib/mongoid/contextual/mongo.rb +517 -346
  82. data/lib/mongoid/contextual/none.rb +193 -20
  83. data/lib/mongoid/contextual/queryable.rb +1 -1
  84. data/lib/mongoid/contextual.rb +14 -2
  85. data/lib/mongoid/copyable.rb +32 -8
  86. data/lib/mongoid/criteria/findable.rb +8 -5
  87. data/lib/mongoid/criteria/includable.rb +27 -22
  88. data/lib/mongoid/criteria/marshalable.rb +10 -2
  89. data/lib/mongoid/criteria/permission.rb +1 -1
  90. data/lib/mongoid/criteria/queryable/aggregable.rb +2 -2
  91. data/lib/mongoid/criteria/queryable/extensions/array.rb +3 -16
  92. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -4
  93. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +2 -2
  94. data/lib/mongoid/criteria/queryable/extensions/date.rb +6 -1
  95. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +6 -1
  96. data/lib/mongoid/criteria/queryable/extensions/hash.rb +1 -17
  97. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -9
  98. data/lib/mongoid/criteria/queryable/extensions/object.rb +2 -1
  99. data/lib/mongoid/criteria/queryable/extensions/range.rb +13 -5
  100. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
  101. data/lib/mongoid/criteria/queryable/extensions/set.rb +1 -1
  102. data/lib/mongoid/criteria/queryable/extensions/string.rb +4 -14
  103. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +4 -12
  104. data/lib/mongoid/criteria/queryable/extensions/time.rb +6 -1
  105. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +6 -1
  106. data/lib/mongoid/criteria/queryable/key.rb +4 -4
  107. data/lib/mongoid/criteria/queryable/mergeable.rb +1 -1
  108. data/lib/mongoid/criteria/queryable/optional.rb +11 -17
  109. data/lib/mongoid/criteria/queryable/options.rb +2 -2
  110. data/lib/mongoid/criteria/queryable/pipeline.rb +1 -1
  111. data/lib/mongoid/criteria/queryable/selectable.rb +47 -38
  112. data/lib/mongoid/criteria/queryable/selector.rb +92 -7
  113. data/lib/mongoid/criteria/queryable/smash.rb +40 -7
  114. data/lib/mongoid/criteria/queryable.rb +12 -7
  115. data/lib/mongoid/criteria/scopable.rb +2 -2
  116. data/lib/mongoid/criteria/translator.rb +45 -0
  117. data/lib/mongoid/criteria.rb +20 -40
  118. data/lib/mongoid/deprecable.rb +36 -0
  119. data/lib/mongoid/deprecation.rb +25 -0
  120. data/lib/mongoid/document.rb +127 -35
  121. data/lib/mongoid/equality.rb +8 -8
  122. data/lib/mongoid/errors/create_collection_failure.rb +33 -0
  123. data/lib/mongoid/errors/document_not_found.rb +10 -6
  124. data/lib/mongoid/errors/drop_collection_failure.rb +27 -0
  125. data/lib/mongoid/errors/immutable_attribute.rb +26 -0
  126. data/lib/mongoid/errors/invalid_async_query_executor.rb +25 -0
  127. data/lib/mongoid/errors/invalid_config_option.rb +1 -1
  128. data/lib/mongoid/errors/invalid_dependent_strategy.rb +1 -1
  129. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
  130. data/lib/mongoid/errors/invalid_field.rb +6 -2
  131. data/lib/mongoid/errors/invalid_field_type.rb +26 -0
  132. data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +22 -0
  133. data/lib/mongoid/errors/invalid_relation.rb +1 -1
  134. data/lib/mongoid/errors/invalid_relation_option.rb +1 -1
  135. data/lib/mongoid/errors/invalid_session_use.rb +1 -1
  136. data/lib/mongoid/errors/invalid_storage_options.rb +1 -1
  137. data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
  138. data/lib/mongoid/errors/mongoid_error.rb +3 -3
  139. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +1 -1
  140. data/lib/mongoid/errors/no_client_database.rb +1 -1
  141. data/lib/mongoid/errors/no_client_hosts.rb +1 -1
  142. data/lib/mongoid/errors/readonly_attribute.rb +1 -1
  143. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
  144. data/lib/mongoid/errors/unknown_attribute.rb +1 -1
  145. data/lib/mongoid/errors.rb +6 -3
  146. data/lib/mongoid/extensions/array.rb +9 -7
  147. data/lib/mongoid/extensions/big_decimal.rb +33 -10
  148. data/lib/mongoid/extensions/binary.rb +42 -0
  149. data/lib/mongoid/extensions/boolean.rb +8 -2
  150. data/lib/mongoid/extensions/date.rb +26 -20
  151. data/lib/mongoid/extensions/date_time.rb +1 -1
  152. data/lib/mongoid/extensions/false_class.rb +1 -1
  153. data/lib/mongoid/extensions/float.rb +7 -4
  154. data/lib/mongoid/extensions/hash.rb +19 -8
  155. data/lib/mongoid/extensions/integer.rb +7 -4
  156. data/lib/mongoid/extensions/module.rb +1 -1
  157. data/lib/mongoid/extensions/object.rb +10 -8
  158. data/lib/mongoid/extensions/range.rb +41 -10
  159. data/lib/mongoid/extensions/regexp.rb +11 -4
  160. data/lib/mongoid/extensions/set.rb +11 -4
  161. data/lib/mongoid/extensions/string.rb +11 -22
  162. data/lib/mongoid/extensions/symbol.rb +4 -15
  163. data/lib/mongoid/extensions/time.rb +29 -16
  164. data/lib/mongoid/extensions/time_with_zone.rb +1 -2
  165. data/lib/mongoid/extensions/true_class.rb +1 -1
  166. data/lib/mongoid/extensions.rb +1 -0
  167. data/lib/mongoid/factory.rb +55 -7
  168. data/lib/mongoid/fields/foreign_key.rb +11 -4
  169. data/lib/mongoid/fields/localized.rb +19 -4
  170. data/lib/mongoid/fields/standard.rb +17 -7
  171. data/lib/mongoid/fields/validators/macro.rb +3 -9
  172. data/lib/mongoid/fields.rb +129 -20
  173. data/lib/mongoid/findable.rb +54 -24
  174. data/lib/mongoid/indexable/specification.rb +2 -2
  175. data/lib/mongoid/indexable/validators/options.rb +6 -2
  176. data/lib/mongoid/interceptable.rb +76 -15
  177. data/lib/mongoid/matchable.rb +1 -1
  178. data/lib/mongoid/matcher/eq_impl.rb +1 -1
  179. data/lib/mongoid/matcher/type.rb +1 -1
  180. data/lib/mongoid/matcher.rb +33 -13
  181. data/lib/mongoid/persistable/creatable.rb +19 -9
  182. data/lib/mongoid/persistable/deletable.rb +2 -2
  183. data/lib/mongoid/persistable/destroyable.rb +1 -1
  184. data/lib/mongoid/persistable/savable.rb +14 -2
  185. data/lib/mongoid/persistable/unsettable.rb +2 -2
  186. data/lib/mongoid/persistable/updatable.rb +69 -12
  187. data/lib/mongoid/persistable/upsertable.rb +21 -2
  188. data/lib/mongoid/persistable.rb +6 -3
  189. data/lib/mongoid/persistence_context.rb +6 -4
  190. data/lib/mongoid/query_cache.rb +13 -261
  191. data/lib/mongoid/railties/controller_runtime.rb +1 -1
  192. data/lib/mongoid/railties/database.rake +7 -2
  193. data/lib/mongoid/reloadable.rb +10 -8
  194. data/lib/mongoid/scopable.rb +15 -13
  195. data/lib/mongoid/selectable.rb +1 -2
  196. data/lib/mongoid/serializable.rb +10 -6
  197. data/lib/mongoid/stateful.rb +57 -10
  198. data/lib/mongoid/tasks/database.rake +12 -0
  199. data/lib/mongoid/tasks/database.rb +20 -2
  200. data/lib/mongoid/threaded/lifecycle.rb +5 -5
  201. data/lib/mongoid/threaded.rb +42 -12
  202. data/lib/mongoid/timestamps/created.rb +1 -1
  203. data/lib/mongoid/timestamps/updated.rb +2 -2
  204. data/lib/mongoid/touchable.rb +2 -3
  205. data/lib/mongoid/traversable.rb +5 -4
  206. data/lib/mongoid/utils.rb +22 -0
  207. data/lib/mongoid/validatable/localizable.rb +1 -1
  208. data/lib/mongoid/validatable/macros.rb +5 -7
  209. data/lib/mongoid/validatable/presence.rb +2 -2
  210. data/lib/mongoid/validatable/uniqueness.rb +9 -8
  211. data/lib/mongoid/validatable.rb +9 -6
  212. data/lib/mongoid/version.rb +1 -1
  213. data/lib/mongoid/warnings.rb +19 -4
  214. data/lib/mongoid.rb +17 -3
  215. data/spec/config/mongoid.yml +16 -0
  216. data/spec/integration/app_spec.rb +10 -14
  217. data/spec/integration/associations/belongs_to_spec.rb +18 -0
  218. data/spec/integration/associations/embedded_spec.rb +15 -0
  219. data/spec/integration/associations/embeds_many_spec.rb +15 -2
  220. data/spec/integration/associations/embeds_one_spec.rb +18 -0
  221. data/spec/integration/associations/foreign_key_spec.rb +9 -0
  222. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
  223. data/spec/integration/associations/has_one_spec.rb +97 -1
  224. data/spec/integration/associations/scope_option_spec.rb +1 -1
  225. data/spec/integration/callbacks_models.rb +132 -1
  226. data/spec/integration/callbacks_spec.rb +360 -4
  227. data/spec/integration/criteria/range_spec.rb +95 -1
  228. data/spec/integration/discriminator_key_spec.rb +118 -80
  229. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  230. data/spec/integration/i18n_fallbacks_spec.rb +3 -32
  231. data/spec/integration/matcher_examples_spec.rb +20 -13
  232. data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
  233. data/spec/integration/matcher_operator_spec.rb +3 -5
  234. data/spec/integration/persistence/range_field_spec.rb +350 -0
  235. data/spec/mongoid/association/counter_cache_spec.rb +1 -1
  236. data/spec/mongoid/association/depending_spec.rb +9 -9
  237. data/spec/mongoid/association/eager_spec.rb +2 -1
  238. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
  239. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
  240. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +96 -9
  241. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
  242. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +255 -65
  243. data/spec/mongoid/association/embedded/embeds_many_models.rb +37 -0
  244. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +12 -0
  245. data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
  246. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
  247. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +15 -2
  248. data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
  249. data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
  250. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
  251. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
  252. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +15 -0
  253. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  254. data/spec/mongoid/association/referenced/belongs_to_spec.rb +4 -20
  255. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +186 -229
  256. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
  257. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
  258. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
  259. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +2 -56
  260. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +173 -177
  261. data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
  262. data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
  263. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
  264. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
  265. data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
  266. data/spec/mongoid/association/syncable_spec.rb +15 -1
  267. data/spec/mongoid/atomic/paths_spec.rb +0 -14
  268. data/spec/mongoid/attributes/nested_spec.rb +80 -11
  269. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  270. data/spec/mongoid/attributes/projector_spec.rb +1 -5
  271. data/spec/mongoid/attributes_spec.rb +510 -33
  272. data/spec/mongoid/changeable_spec.rb +429 -37
  273. data/spec/mongoid/clients/factory_spec.rb +23 -30
  274. data/spec/mongoid/clients/sessions_spec.rb +0 -38
  275. data/spec/mongoid/clients_spec.rb +149 -15
  276. data/spec/mongoid/collection_configurable_spec.rb +158 -0
  277. data/spec/mongoid/config/defaults_spec.rb +160 -0
  278. data/spec/mongoid/config_spec.rb +214 -31
  279. data/spec/mongoid/contextual/aggregable/memory_spec.rb +396 -158
  280. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  281. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  282. data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
  283. data/spec/mongoid/contextual/memory_spec.rb +850 -88
  284. data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +187 -0
  285. data/spec/mongoid/contextual/mongo_spec.rb +1572 -435
  286. data/spec/mongoid/contextual/none_spec.rb +60 -21
  287. data/spec/mongoid/copyable_spec.rb +453 -11
  288. data/spec/mongoid/criteria/findable_spec.rb +86 -210
  289. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  290. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  291. data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
  292. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
  293. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
  294. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
  295. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
  296. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
  297. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
  298. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +4 -69
  299. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +0 -59
  300. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
  301. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
  302. data/spec/mongoid/criteria/queryable/optional_spec.rb +15 -484
  303. data/spec/mongoid/criteria/queryable/options_spec.rb +1 -1
  304. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +469 -0
  305. data/spec/mongoid/criteria/queryable/selectable_spec.rb +78 -86
  306. data/spec/mongoid/criteria/queryable/selector_spec.rb +15 -3
  307. data/spec/mongoid/criteria/translator_spec.rb +132 -0
  308. data/spec/mongoid/criteria_projection_spec.rb +1 -5
  309. data/spec/mongoid/criteria_spec.rb +469 -1205
  310. data/spec/mongoid/document_fields_spec.rb +173 -24
  311. data/spec/mongoid/document_spec.rb +32 -41
  312. data/spec/mongoid/errors/document_not_found_spec.rb +29 -2
  313. data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
  314. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  315. data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
  316. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  317. data/spec/mongoid/errors/readonly_document_spec.rb +2 -2
  318. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
  319. data/spec/mongoid/extensions/array_spec.rb +16 -2
  320. data/spec/mongoid/extensions/big_decimal_spec.rb +712 -212
  321. data/spec/mongoid/extensions/binary_spec.rb +44 -9
  322. data/spec/mongoid/extensions/boolean_spec.rb +68 -82
  323. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
  324. data/spec/mongoid/extensions/date_spec.rb +71 -1
  325. data/spec/mongoid/extensions/date_time_spec.rb +15 -9
  326. data/spec/mongoid/extensions/float_spec.rb +53 -74
  327. data/spec/mongoid/extensions/hash_spec.rb +33 -3
  328. data/spec/mongoid/extensions/integer_spec.rb +50 -64
  329. data/spec/mongoid/extensions/range_spec.rb +255 -54
  330. data/spec/mongoid/extensions/regexp_spec.rb +58 -33
  331. data/spec/mongoid/extensions/set_spec.rb +106 -0
  332. data/spec/mongoid/extensions/string_spec.rb +53 -25
  333. data/spec/mongoid/extensions/symbol_spec.rb +18 -25
  334. data/spec/mongoid/extensions/time_spec.rb +639 -106
  335. data/spec/mongoid/extensions/time_with_zone_spec.rb +24 -83
  336. data/spec/mongoid/factory_spec.rb +61 -1
  337. data/spec/mongoid/fields/localized_spec.rb +80 -37
  338. data/spec/mongoid/fields_spec.rb +500 -84
  339. data/spec/mongoid/findable_spec.rb +450 -58
  340. data/spec/mongoid/indexable/specification_spec.rb +2 -2
  341. data/spec/mongoid/indexable_spec.rb +55 -30
  342. data/spec/mongoid/interceptable_spec.rb +599 -8
  343. data/spec/mongoid/interceptable_spec_models.rb +235 -4
  344. data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
  345. data/spec/mongoid/mongoizable_spec.rb +285 -0
  346. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  347. data/spec/mongoid/persistable/deletable_spec.rb +28 -8
  348. data/spec/mongoid/persistable/destroyable_spec.rb +28 -8
  349. data/spec/mongoid/persistable/incrementable_spec.rb +37 -0
  350. data/spec/mongoid/persistable/logical_spec.rb +37 -0
  351. data/spec/mongoid/persistable/poppable_spec.rb +36 -0
  352. data/spec/mongoid/persistable/pullable_spec.rb +72 -0
  353. data/spec/mongoid/persistable/pushable_spec.rb +72 -0
  354. data/spec/mongoid/persistable/renamable_spec.rb +36 -0
  355. data/spec/mongoid/persistable/savable_spec.rb +96 -0
  356. data/spec/mongoid/persistable/settable_spec.rb +37 -0
  357. data/spec/mongoid/persistable/unsettable_spec.rb +36 -0
  358. data/spec/mongoid/persistable/updatable_spec.rb +20 -28
  359. data/spec/mongoid/persistable/upsertable_spec.rb +89 -1
  360. data/spec/mongoid/persistence_context_spec.rb +31 -57
  361. data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
  362. data/spec/mongoid/query_cache_spec.rb +56 -215
  363. data/spec/mongoid/reloadable_spec.rb +83 -6
  364. data/spec/mongoid/scopable_spec.rb +91 -1
  365. data/spec/mongoid/serializable_spec.rb +9 -30
  366. data/spec/mongoid/shardable_spec.rb +4 -4
  367. data/spec/mongoid/stateful_spec.rb +150 -8
  368. data/spec/mongoid/tasks/database_rake_spec.rb +74 -0
  369. data/spec/mongoid/tasks/database_spec.rb +127 -0
  370. data/spec/mongoid/timestamps_spec.rb +392 -4
  371. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  372. data/spec/mongoid/touchable_spec.rb +390 -2
  373. data/spec/mongoid/touchable_spec_models.rb +14 -8
  374. data/spec/mongoid/traversable_spec.rb +13 -35
  375. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  376. data/spec/mongoid/validatable/uniqueness_spec.rb +58 -31
  377. data/spec/mongoid/warnings_spec.rb +35 -0
  378. data/spec/mongoid_spec.rb +34 -16
  379. data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
  380. data/spec/rails/mongoid_spec.rb +4 -16
  381. data/spec/spec_helper.rb +5 -0
  382. data/spec/support/constraints.rb +24 -0
  383. data/spec/support/immutable_ids.rb +118 -0
  384. data/spec/support/macros.rb +78 -0
  385. data/spec/support/models/artist.rb +0 -1
  386. data/spec/support/models/augmentation.rb +12 -0
  387. data/spec/support/models/band.rb +4 -0
  388. data/spec/support/models/book.rb +1 -0
  389. data/spec/support/models/building.rb +2 -0
  390. data/spec/support/models/catalog.rb +24 -0
  391. data/spec/support/models/circus.rb +3 -0
  392. data/spec/support/models/cover.rb +10 -0
  393. data/spec/support/models/fanatic.rb +8 -0
  394. data/spec/support/models/implant.rb +9 -0
  395. data/spec/support/models/label.rb +2 -0
  396. data/spec/support/models/passport.rb +9 -0
  397. data/spec/support/models/person.rb +2 -0
  398. data/spec/support/models/player.rb +2 -0
  399. data/spec/support/models/powerup.rb +12 -0
  400. data/spec/support/models/product.rb +1 -0
  401. data/spec/support/models/purse.rb +9 -0
  402. data/spec/support/models/registry.rb +1 -0
  403. data/spec/support/models/school.rb +14 -0
  404. data/spec/support/models/shield.rb +18 -0
  405. data/spec/support/models/student.rb +14 -0
  406. data/spec/support/models/weapon.rb +12 -0
  407. data.tar.gz.sig +0 -0
  408. metadata +93 -15
  409. metadata.gz.sig +0 -0
  410. data/lib/mongoid/errors/eager_load.rb +0 -23
  411. data/lib/mongoid/errors/invalid_value.rb +0 -17
  412. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -60
  413. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -60
  414. data/spec/mongoid/errors/eager_load_spec.rb +0 -31
@@ -57,7 +57,9 @@ module Mongoid
57
57
  # @return [ Mongo::Collection ] The collection for this persistence
58
58
  # context.
59
59
  def collection(parent = nil)
60
- parent ? parent.collection.with(client_options) : client[collection_name.to_sym]
60
+ parent ?
61
+ parent.collection.with(client_options.except(:database, "database")) :
62
+ client[collection_name.to_sym]
61
63
  end
62
64
 
63
65
  # Get the collection name for this persistence context.
@@ -116,7 +118,7 @@ module Mongoid
116
118
  #
117
119
  # @param [ Object ] other The object to be compared with this one.
118
120
  #
119
- # @return [ true, false ] Whether the two persistence contexts are equal.
121
+ # @return [ true | false ] Whether the two persistence contexts are equal.
120
122
  def ==(other)
121
123
  return false unless other.is_a?(PersistenceContext)
122
124
  options == other.options
@@ -182,7 +184,7 @@ module Mongoid
182
184
  # PersistenceContext.set(model)
183
185
  #
184
186
  # @param [ Object ] object The class or model instance.
185
- # @param [ Hash, Mongoid::PersistenceContext ] options_or_context The persistence
187
+ # @param [ Hash | Mongoid::PersistenceContext ] options_or_context The persistence
186
188
  # options or a persistence context object.
187
189
  #
188
190
  # @return [ Mongoid::PersistenceContext ] The persistence context for the object.
@@ -218,7 +220,7 @@ module Mongoid
218
220
  # @example Clear the persistence context for a class or model instance.
219
221
  # PersistenceContext.clear(model)
220
222
  #
221
- # @param [ Class, Object ] object The class or model instance.
223
+ # @param [ Class | Object ] object The class or model instance.
222
224
  # @param [ Mongo::Cluster ] cluster The original cluster before this context was used.
223
225
  # @param [ Mongoid::PersistenceContext ] original_context The original persistence
224
226
  # context that was set before this context was used.
@@ -4,28 +4,8 @@ module Mongoid
4
4
 
5
5
  # A cache of database queries on a per-request basis.
6
6
  module QueryCache
7
- # @api private
8
- LEGACY_WARNING = <<~DOC
9
- You are using the legacy Mongoid query cache which has known issues.
10
- Please upgrade the `mongo' gem to at least 2.14.0 to use the improved driver query cache.
11
- Refer to: https://docs.mongodb.com/mongoid/current/tutorials/mongoid-queries/#the-improved-driver-query-cache
12
- DOC
13
7
 
14
8
  class << self
15
- # Get the cached queries.
16
- #
17
- # @example Get the cached queries from the current thread.
18
- # QueryCache.cache_table
19
- #
20
- # @return [ Hash ] The hash of cached queries.
21
- # @api private
22
- def cache_table
23
- if defined?(Mongo::QueryCache)
24
- raise NotImplementedError, "Mongoid does not expose driver's query cache table"
25
- else
26
- Thread.current["[mongoid]:query_cache"] ||= {}
27
- end
28
- end
29
9
 
30
10
  # Clear the query cache.
31
11
  #
@@ -34,11 +14,8 @@ module Mongoid
34
14
  #
35
15
  # @return [ nil ] Always nil.
36
16
  def clear_cache
37
- if defined?(Mongo::QueryCache)
38
- Mongo::QueryCache.clear
39
- else
40
- Thread.current["[mongoid]:query_cache"] = nil
41
- end
17
+ Mongoid::Warnings.warn_mongoid_query_cache_clear
18
+ Mongo::QueryCache.clear
42
19
  end
43
20
 
44
21
  # Set whether the cache is enabled.
@@ -46,13 +23,10 @@ module Mongoid
46
23
  # @example Set if the cache is enabled.
47
24
  # QueryCache.enabled = true
48
25
  #
49
- # @param [ true, false ] value The enabled value.
26
+ # @param [ true | false ] value The enabled value.
50
27
  def enabled=(value)
51
- if defined?(Mongo::QueryCache)
52
- Mongo::QueryCache.enabled = value
53
- else
54
- Thread.current["[mongoid]:query_cache:enabled"] = value
55
- end
28
+ Mongoid::Warnings.warn_mongoid_query_cache
29
+ Mongo::QueryCache.enabled = value
56
30
  end
57
31
 
58
32
  # Is the query cache enabled on the current thread?
@@ -60,13 +34,10 @@ module Mongoid
60
34
  # @example Is the query cache enabled?
61
35
  # QueryCache.enabled?
62
36
  #
63
- # @return [ true, false ] If the cache is enabled.
37
+ # @return [ true | false ] If the cache is enabled.
64
38
  def enabled?
65
- if defined?(Mongo::QueryCache)
66
- Mongo::QueryCache.enabled?
67
- else
68
- !!Thread.current["[mongoid]:query_cache:enabled"]
69
- end
39
+ Mongoid::Warnings.warn_mongoid_query_cache
40
+ Mongo::QueryCache.enabled?
70
41
  end
71
42
 
72
43
  # Execute the block while using the query cache.
@@ -76,21 +47,8 @@ module Mongoid
76
47
  #
77
48
  # @return [ Object ] The result of the block.
78
49
  def cache(&block)
79
- if defined?(Mongo::QueryCache)
80
- Mongo::QueryCache.cache(&block)
81
- else
82
- @legacy_query_cache_warned ||= begin
83
- Mongoid.logger.warn(LEGACY_WARNING)
84
- true
85
- end
86
- enabled = QueryCache.enabled?
87
- QueryCache.enabled = true
88
- begin
89
- yield
90
- ensure
91
- QueryCache.enabled = enabled
92
- end
93
- end
50
+ Mongoid::Warnings.warn_mongoid_query_cache
51
+ Mongo::QueryCache.cache(&block)
94
52
  end
95
53
 
96
54
  # Execute the block with the query cache disabled.
@@ -100,217 +58,11 @@ module Mongoid
100
58
  #
101
59
  # @return [ Object ] The result of the block.
102
60
  def uncached(&block)
103
- if defined?(Mongo::QueryCache)
104
- Mongo::QueryCache.uncached(&block)
105
- else
106
- enabled = QueryCache.enabled?
107
- QueryCache.enabled = false
108
- begin
109
- yield
110
- ensure
111
- QueryCache.enabled = enabled
112
- end
113
- end
114
- end
115
- end
116
-
117
- if defined?(Mongo::QueryCache::Middleware)
118
- Middleware = Mongo::QueryCache::Middleware
119
- else
120
- # The middleware to be added to a rack application in order to activate the
121
- # query cache.
122
- class Middleware
123
-
124
- # Instantiate the middleware.
125
- #
126
- # @example Create the new middleware.
127
- # Middleware.new(app)
128
- #
129
- # @param [ Object ] app The rack application stack.
130
- def initialize(app)
131
- @app = app
132
- end
133
-
134
- # Execute the request, wrapping in a query cache.
135
- #
136
- # @example Execute the request.
137
- # middleware.call(env)
138
- #
139
- # @param [ Object ] env The environment.
140
- #
141
- # @return [ Object ] The result of the call.
142
- def call(env)
143
- QueryCache.cache do
144
- @app.call(env)
145
- end
146
- ensure
147
- QueryCache.clear_cache
148
- end
149
- end
150
- end
151
-
152
- # A Cursor that attempts to load documents from memory first before hitting
153
- # the database if the same query has already been executed.
154
- # @deprecated This class is only used with driver versions 2.13 and lower.
155
- class CachedCursor < Mongo::Cursor
156
-
157
- # We iterate over the cached documents if they exist already in the
158
- # cursor otherwise proceed as normal.
159
- #
160
- # @example Iterate over the documents.
161
- # cursor.each do |doc|
162
- # # ...
163
- # end
164
- def each
165
- if @cached_documents
166
- @cached_documents.each do |doc|
167
- yield doc
168
- end
169
- else
170
- super
171
- end
172
- end
173
-
174
- # Get a human-readable string representation of +Cursor+.
175
- #
176
- # @example Inspect the cursor.
177
- # cursor.inspect
178
- #
179
- # @return [ String ] A string representation of a +Cursor+ instance.
180
- def inspect
181
- "#<Mongoid::QueryCache::CachedCursor:0x#{object_id} @view=#{@view.inspect}>"
182
- end
183
-
184
- private
185
-
186
- def process(result)
187
- documents = super
188
- if @cursor_id.zero? && !@after_first_batch
189
- @cached_documents ||= []
190
- @cached_documents.concat(documents)
191
- end
192
- @after_first_batch = true
193
- documents
61
+ Mongoid::Warnings.warn_mongoid_query_cache
62
+ Mongo::QueryCache.uncached(&block)
194
63
  end
195
64
  end
196
65
 
197
- # Included to add behavior for clearing out the query cache on certain
198
- # operations.
199
- # @deprecated This module is only used with driver versions 2.13 and lower.
200
- module Base
201
-
202
- def alias_query_cache_clear(*method_names)
203
- method_names.each do |method_name|
204
- define_method("#{method_name}_with_clear_cache") do |*args|
205
- QueryCache.clear_cache
206
- send("#{method_name}_without_clear_cache", *args)
207
- end
208
-
209
- alias_method "#{method_name}_without_clear_cache", method_name
210
- alias_method method_name, "#{method_name}_with_clear_cache"
211
- end
212
- end
213
- end
214
-
215
- # Contains enhancements to the Mongo::Collection::View in order to get a
216
- # cached cursor or a regular cursor on iteration.
217
- # @deprecated This module is only used with driver versions 2.13 and lower.
218
- module View
219
- extend ActiveSupport::Concern
220
-
221
- included do
222
- extend QueryCache::Base
223
- alias_query_cache_clear :delete_one,
224
- :delete_many,
225
- :update_one,
226
- :update_many,
227
- :replace_one,
228
- :find_one_and_delete,
229
- :find_one_and_replace,
230
- :find_one_and_update
231
- end
232
-
233
- # Override the default enumeration to handle if the cursor can be cached
234
- # or not.
235
- #
236
- # @example Iterate over the view.
237
- # view.each do |doc|
238
- # # ...
239
- # end
240
- def each
241
- if system_collection? || !QueryCache.enabled? || (respond_to?(:write?, true) && write?)
242
- super
243
- else
244
- @cursor = nil
245
- unless @cursor = cached_cursor
246
- session = client.send(:get_session, @options)
247
- read_with_retry(session, server_selector) do |server|
248
- result = send_initial_query(server, session)
249
- if result.cursor_id == 0 || result.cursor_id.nil?
250
- @cursor = CachedCursor.new(view, result, server, session: session)
251
- QueryCache.cache_table[cache_key] = @cursor
252
- else
253
- @cursor = Mongo::Cursor.new(view, result, server, session: session)
254
- end
255
- end
256
- end
257
- if block_given?
258
- if limit
259
- @cursor.to_a[0...limit].each do |doc|
260
- yield doc
261
- end
262
- else
263
- @cursor.each do |doc|
264
- yield doc
265
- end
266
- end
267
- else
268
- @cursor.to_enum
269
- end
270
- end
271
- end
272
-
273
- private
274
-
275
- def cached_cursor
276
- if limit
277
- key = [ collection.namespace, selector, nil, skip, sort, projection, collation ]
278
- cursor = QueryCache.cache_table[key]
279
- end
280
- cursor || QueryCache.cache_table[cache_key]
281
- end
282
-
283
- def cache_key
284
- [ collection.namespace, selector, limit, skip, sort, projection, collation ]
285
- end
286
-
287
- def system_collection?
288
- collection.name.start_with?('system.')
289
- end
290
- end
291
-
292
- # Adds behavior to the query cache for collections.
293
- # @deprecated This module is only used with driver versions 2.13 and lower.
294
- module Collection
295
- extend ActiveSupport::Concern
296
-
297
- included do
298
- extend QueryCache::Base
299
- alias_query_cache_clear :insert_one, :insert_many
300
- end
301
- end
302
-
303
- # Bypass the query cache when reloading a document.
304
- module Document
305
- def reload
306
- QueryCache.uncached { super }
307
- end
308
- end
66
+ Middleware = Mongo::QueryCache::Middleware
309
67
  end
310
68
  end
311
-
312
- unless defined?(Mongo::QueryCache)
313
- Mongo::Collection.__send__(:include, Mongoid::QueryCache::Collection)
314
- Mongo::Collection::View.__send__(:include, Mongoid::QueryCache::View)
315
- Mongoid::Document.__send__(:include, Mongoid::QueryCache::Document)
316
- end
@@ -62,7 +62,7 @@ module Mongoid
62
62
  def started _; end
63
63
 
64
64
  def _completed e
65
- Collector.runtime += e.duration
65
+ Collector.runtime += e.duration * 1000
66
66
  end
67
67
  alias :succeeded :_completed
68
68
  alias :failed :_completed
@@ -25,7 +25,7 @@ namespace :db do
25
25
 
26
26
  unless Rake::Task.task_defined?("db:setup")
27
27
  desc "Create the database, and initialize with the seed data"
28
- task :setup => [ "db:create", "mongoid:create_indexes", "db:seed" ]
28
+ task :setup => [ "db:create", "mongoid:create_collections", "mongoid:create_indexes", "db:seed" ]
29
29
  end
30
30
 
31
31
  unless Rake::Task.task_defined?("db:reset")
@@ -55,10 +55,15 @@ namespace :db do
55
55
 
56
56
  unless Rake::Task.task_defined?("db:test:prepare")
57
57
  namespace :test do
58
- task :prepare => "mongoid:create_indexes"
58
+ task :prepare => ["mongoid:create_collections", "mongoid:create_indexes"]
59
59
  end
60
60
  end
61
61
 
62
+ unless Rake::Task.task_defined?("db:create_collections")
63
+ desc "Create collections specified in Mongoid models"
64
+ task :create_collections => "mongoid:create_collections"
65
+ end
66
+
62
67
  unless Rake::Task.task_defined?("db:create_indexes")
63
68
  desc "Create indexes specified in Mongoid models"
64
69
  task :create_indexes => "mongoid:create_indexes"
@@ -16,18 +16,20 @@ module Mongoid
16
16
  #
17
17
  # @return [ Document ] The document, reloaded.
18
18
  def reload
19
- if @atomic_selector
20
- # Clear atomic_selector cache for sharded clusters. MONGOID-5076
21
- remove_instance_variable('@atomic_selector')
22
- end
23
-
24
19
  reloaded = _reload
25
20
  if Mongoid.raise_not_found_error && (reloaded.nil? || reloaded.empty?)
26
- raise Errors::DocumentNotFound.new(self.class, _id, _id)
21
+ shard_keys = atomic_selector.with_indifferent_access.slice(*shard_key_fields, :_id)
22
+ raise Errors::DocumentNotFound.new(self.class, _id, shard_keys)
27
23
  end
24
+
25
+ reset_atomic_updates!
26
+
28
27
  @attributes = reloaded
29
- @attributes_before_type_cast = {}
30
- changed_attributes.clear
28
+ @attributes_before_type_cast = @attributes.dup
29
+ @changed_attributes = {}
30
+ @previous_changes = {}
31
+ @previous_attributes = {}
32
+ @previously_new_record = false
31
33
  reset_readonly
32
34
  apply_defaults
33
35
  reload_relations
@@ -23,7 +23,7 @@ module Mongoid
23
23
  # @example Apply the default scoping.
24
24
  # document.apply_default_scoping
25
25
  #
26
- # @return [ true, false ] If default scoping was applied.
26
+ # @return [ true | false ] If default scoping was applied.
27
27
  def apply_default_scoping
28
28
  if default_scoping
29
29
  default_scoping.call.selector.each do |field, value|
@@ -74,7 +74,7 @@ module Mongoid
74
74
  # default_scope ->{ where(active: true) }
75
75
  # end
76
76
  #
77
- # @param [ Proc, Criteria ] value The default scope.
77
+ # @param [ Proc | Criteria ] value The default scope.
78
78
  #
79
79
  # @raise [ Errors::InvalidScope ] If the scope is not a proc or criteria.
80
80
  #
@@ -90,7 +90,7 @@ module Mongoid
90
90
  # @example Can the default scope be applied?
91
91
  # Band.default_scopable?
92
92
  #
93
- # @return [ true, false ] If the default scope can be applied.
93
+ # @return [ true | false ] If the default scope can be applied.
94
94
  def default_scopable?
95
95
  default_scoping? && !Threaded.without_default_scope?(self)
96
96
  end
@@ -168,9 +168,11 @@ module Mongoid
168
168
  # Band.where(name: "Depeche Mode")
169
169
  # end
170
170
  #
171
- # @note This will force the default scope to be removed.
171
+ # @note This will force the default scope to be removed, but will not
172
+ # remove scopes declared with ``.with_scope``. This will be changed
173
+ # in Mongoid 9.
172
174
  #
173
- # @return [ Criteria, Object ] The unscoped criteria or result of the
175
+ # @return [ Criteria | Object ] The unscoped criteria or result of the
174
176
  # block.
175
177
  def unscoped
176
178
  if block_given?
@@ -240,7 +242,7 @@ module Mongoid
240
242
  # @example Warn or raise error if name exists.
241
243
  # Model.valid_scope_name?("test")
242
244
  #
243
- # @param [ String, Symbol ] name The name of the scope.
245
+ # @param [ String | Symbol ] name The name of the scope.
244
246
  #
245
247
  # @raise [ Errors::ScopeOverwrite ] If the name exists and configured to
246
248
  # raise the error.
@@ -249,12 +251,12 @@ module Mongoid
249
251
  if Mongoid.scope_overwrite_exception
250
252
  raise Errors::ScopeOverwrite.new(self.name, name)
251
253
  else
252
- if Mongoid.logger
253
- Mongoid.logger.warn(
254
- "Creating scope :#{name}. " +
255
- "Overwriting existing method #{self.name}.#{name}."
256
- )
257
- end
254
+ Mongoid.logger.warn(
255
+ "Creating scope :#{name} which conflicts with #{self.name}.#{name}. " +
256
+ "Calls to `Mongoid::Criteria##{name}` will delegate to " +
257
+ "`Mongoid::Criteria##{name}` for criteria with klass #{self.name} " +
258
+ "and will ignore the declared scope."
259
+ )
258
260
  end
259
261
  end
260
262
  end
@@ -311,7 +313,7 @@ module Mongoid
311
313
  # @example Process the default scope.
312
314
  # Model.process_default_scope(value)
313
315
  #
314
- # @param [ Criteria, Proc ] value The default scope value.
316
+ # @param [ Criteria | Proc ] value The default scope value.
315
317
  def process_default_scope(value)
316
318
  if existing = default_scoping
317
319
  ->{ existing.call.merge(value.to_proc.call) }
@@ -15,8 +15,7 @@ module Mongoid
15
15
  #
16
16
  # @return [ Hash ] The document's selector.
17
17
  def atomic_selector
18
- @atomic_selector ||=
19
- (embedded? ? embedded_atomic_selector : root_atomic_selector_in_db)
18
+ embedded? ? embedded_atomic_selector : root_atomic_selector_in_db
20
19
  end
21
20
 
22
21
  private
@@ -33,10 +33,14 @@ module Mongoid
33
33
  #
34
34
  # @param [ Hash ] options The options to pass.
35
35
  #
36
- # @option options [ Symbol ] :include What associations to include.
37
- # @option options [ Symbol ] :only Limit the fields to only these.
38
- # @option options [ Symbol ] :except Dont include these fields.
39
- # @option options [ Symbol ] :methods What methods to include.
36
+ # @option options [ Symbol | String | Array<Symbol | String> ] :except
37
+ # Do not include these field(s).
38
+ # @option options [ Symbol | String | Array<Symbol | String> ] :include
39
+ # Which association(s) to include.
40
+ # @option options [ Symbol | String | Array<Symbol | String> ] :only
41
+ # Limit the field(s) to only these.
42
+ # @option options [ Symbol | String | Array<Symbol | String> ] :methods
43
+ # What methods to include.
40
44
  #
41
45
  # @return [ Hash ] The document, ready to be serialized.
42
46
  def serializable_hash(options = nil)
@@ -137,7 +141,7 @@ module Mongoid
137
141
  # @example Get the association names.
138
142
  # document.relation_names(:include => [ :addresses ])
139
143
  #
140
- # @param [ Hash, Symbol, Array<Symbol> ] inclusions The inclusions.
144
+ # @param [ Hash | Symbol | Array<Symbol> ] inclusions The inclusions.
141
145
  #
142
146
  # @return [ Array<Symbol> ] The names of the included associations.
143
147
  def relation_names(inclusions)
@@ -150,7 +154,7 @@ module Mongoid
150
154
  # @example Get the association options.
151
155
  # document.relation_names(:include => [ :addresses ])
152
156
  #
153
- # @param [ Hash, Symbol, Array<Symbol> ] inclusions The inclusions.
157
+ # @param [ Hash | Symbol | Array<Symbol> ] inclusions The inclusions.
154
158
  # @param [ Hash ] options The options.
155
159
  # @param [ Symbol ] name The name of the association.
156
160
  #
@@ -6,7 +6,15 @@ module Mongoid
6
6
  # document can transition through.
7
7
  module Stateful
8
8
 
9
- attr_writer :destroyed, :flagged_for_destroy, :new_record
9
+ attr_writer :destroyed, :flagged_for_destroy, :previously_new_record
10
+
11
+ def new_record=(new_value)
12
+ @new_record ||= false
13
+ if @new_record && !new_value
14
+ @previously_new_record = true
15
+ end
16
+ @new_record = new_value
17
+ end
10
18
 
11
19
  # Returns true if the +Document+ has not been persisted to the database,
12
20
  # false if it has. This is determined by the variable @new_record
@@ -15,29 +23,47 @@ module Mongoid
15
23
  # @example Is the document new?
16
24
  # person.new_record?
17
25
  #
18
- # @return [ true, false ] True if new, false if not.
26
+ # @return [ true | false ] True if new, false if not.
19
27
  def new_record?
20
28
  @new_record ||= false
21
29
  end
22
30
 
31
+ # Returns true if this document was just created -- that is, prior to the last
32
+ # save, the object didn't exist in the database and new_record? would have
33
+ # returned true.
34
+ #
35
+ # @return [ true | false ] True if was just created, false if not.
36
+ def previously_new_record?
37
+ @previously_new_record ||= false
38
+ end
39
+
23
40
  # Checks if the document has been saved to the database. Returns false
24
41
  # if the document has been destroyed.
25
42
  #
26
43
  # @example Is the document persisted?
27
44
  # person.persisted?
28
45
  #
29
- # @return [ true, false ] True if persisted, false if not.
46
+ # @return [ true | false ] True if persisted, false if not.
30
47
  def persisted?
31
48
  !new_record? && !destroyed?
32
49
  end
33
50
 
51
+ # Checks if the document was previously saved to the database
52
+ # but now it has been deleted.
53
+ #
54
+ # @return [ true | false ] True if was persisted but now destroyed,
55
+ # otherwise false.
56
+ def previously_persisted?
57
+ !new_record? && destroyed?
58
+ end
59
+
34
60
  # Returns whether or not the document has been flagged for deletion, but
35
61
  # not destroyed yet. Used for atomic pulls of child documents.
36
62
  #
37
63
  # @example Is the document flagged?
38
64
  # document.flagged_for_destroy?
39
65
  #
40
- # @return [ true, false ] If the document is flagged.
66
+ # @return [ true | false ] If the document is flagged.
41
67
  def flagged_for_destroy?
42
68
  @flagged_for_destroy ||= false
43
69
  end
@@ -51,7 +77,7 @@ module Mongoid
51
77
  # @example Is the document destroyed?
52
78
  # person.destroyed?
53
79
  #
54
- # @return [ true, false ] True if destroyed, false if not.
80
+ # @return [ true | false ] True if destroyed, false if not.
55
81
  def destroyed?
56
82
  @destroyed ||= false
57
83
  end
@@ -61,7 +87,7 @@ module Mongoid
61
87
  # @example Is this pushable?
62
88
  # person.pushable?
63
89
  #
64
- # @return [ true, false ] Is the document new and embedded?
90
+ # @return [ true | false ] Is the document new and embedded?
65
91
  def pushable?
66
92
  new_record? &&
67
93
  embedded_many? &&
@@ -69,14 +95,35 @@ module Mongoid
69
95
  !_parent.delayed_atomic_sets[atomic_path]
70
96
  end
71
97
 
98
+ # Flags the document as readonly. Will cause a ReadonlyDocument error to be
99
+ # raised if the document is attempted to be saved, updated or destroyed.
100
+ #
101
+ # @example Flag the document as readonly.
102
+ # document.readonly!
103
+ #
104
+ # @return [ true | false ] true if the document was successfully marked
105
+ # readonly, false otherwise.
106
+ def readonly!
107
+ if Mongoid.legacy_readonly
108
+ Mongoid::Warnings.warn_legacy_readonly
109
+ false
110
+ else
111
+ @readonly = true
112
+ end
113
+ end
114
+
72
115
  # Is the document readonly?
73
116
  #
74
117
  # @example Is the document readonly?
75
118
  # document.readonly?
76
119
  #
77
- # @return [ true, false ] If the document is readonly.
120
+ # @return [ true | false ] If the document is readonly.
78
121
  def readonly?
79
- __selected_fields != nil
122
+ if Mongoid.legacy_readonly
123
+ __selected_fields != nil
124
+ else
125
+ @readonly ||= false
126
+ end
80
127
  end
81
128
 
82
129
  # Determine if the document can be set.
@@ -84,7 +131,7 @@ module Mongoid
84
131
  # @example Is this settable?
85
132
  # person.settable?
86
133
  #
87
- # @return [ true, false ] Is this document a new embeds one?
134
+ # @return [ true | false ] Is this document a new embeds one?
88
135
  def settable?
89
136
  new_record? && embedded_one? && _parent.persisted?
90
137
  end
@@ -94,7 +141,7 @@ module Mongoid
94
141
  # @example Is the document updateable?
95
142
  # person.updateable?
96
143
  #
97
- # @return [ true, false ] If the document is changed and persisted.
144
+ # @return [ true | false ] If the document is changed and persisted.
98
145
  def updateable?
99
146
  persisted? && changed?
100
147
  end