mongoid 7.5.0 → 8.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (358) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +3 -3
  4. data/lib/config/locales/en.yml +47 -30
  5. data/lib/mongoid/association/accessors.rb +38 -9
  6. data/lib/mongoid/association/bindable.rb +50 -2
  7. data/lib/mongoid/association/builders.rb +4 -2
  8. data/lib/mongoid/association/constrainable.rb +0 -1
  9. data/lib/mongoid/association/eager_loadable.rb +29 -7
  10. data/lib/mongoid/association/embedded/batchable.rb +53 -13
  11. data/lib/mongoid/association/embedded/cyclic.rb +1 -1
  12. data/lib/mongoid/association/embedded/embedded_in/binding.rb +24 -2
  13. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +2 -2
  14. data/lib/mongoid/association/embedded/embedded_in.rb +3 -2
  15. data/lib/mongoid/association/embedded/embeds_many/binding.rb +1 -0
  16. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +1 -1
  17. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +50 -28
  18. data/lib/mongoid/association/embedded/embeds_many.rb +2 -2
  19. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +18 -4
  20. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +23 -4
  21. data/lib/mongoid/association/embedded/embeds_one.rb +3 -3
  22. data/lib/mongoid/association/macros.rb +2 -1
  23. data/lib/mongoid/association/many.rb +11 -7
  24. data/lib/mongoid/association/nested/many.rb +5 -4
  25. data/lib/mongoid/association/nested/nested_buildable.rb +4 -4
  26. data/lib/mongoid/association/nested/one.rb +5 -5
  27. data/lib/mongoid/association/one.rb +2 -2
  28. data/lib/mongoid/association/options.rb +9 -9
  29. data/lib/mongoid/association/proxy.rb +14 -3
  30. data/lib/mongoid/association/referenced/auto_save.rb +4 -3
  31. data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
  32. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
  33. data/lib/mongoid/association/referenced/belongs_to/proxy.rb +5 -6
  34. data/lib/mongoid/association/referenced/belongs_to.rb +2 -2
  35. data/lib/mongoid/association/referenced/counter_cache.rb +10 -10
  36. data/lib/mongoid/association/referenced/eager.rb +2 -2
  37. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +66 -13
  38. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +6 -3
  39. data/lib/mongoid/association/referenced/has_many/enumerable.rb +20 -28
  40. data/lib/mongoid/association/referenced/has_many/proxy.rb +24 -18
  41. data/lib/mongoid/association/referenced/has_many.rb +3 -3
  42. data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -1
  43. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +5 -5
  44. data/lib/mongoid/association/referenced/has_one/proxy.rb +9 -12
  45. data/lib/mongoid/association/referenced/has_one.rb +3 -3
  46. data/lib/mongoid/association/referenced/syncable.rb +4 -4
  47. data/lib/mongoid/association/reflections.rb +2 -2
  48. data/lib/mongoid/association/relatable.rb +44 -10
  49. data/lib/mongoid/association.rb +5 -5
  50. data/lib/mongoid/atomic/modifiers.rb +2 -2
  51. data/lib/mongoid/atomic/paths/embedded/many.rb +19 -0
  52. data/lib/mongoid/attributes/dynamic.rb +3 -3
  53. data/lib/mongoid/attributes/nested.rb +5 -5
  54. data/lib/mongoid/attributes/processing.rb +10 -3
  55. data/lib/mongoid/attributes/projector.rb +1 -1
  56. data/lib/mongoid/attributes/readonly.rb +2 -2
  57. data/lib/mongoid/attributes.rb +43 -40
  58. data/lib/mongoid/changeable.rb +42 -7
  59. data/lib/mongoid/clients/options.rb +5 -1
  60. data/lib/mongoid/clients/sessions.rb +2 -14
  61. data/lib/mongoid/clients/validators/storage.rb +3 -3
  62. data/lib/mongoid/config/validators/client.rb +6 -6
  63. data/lib/mongoid/config.rb +27 -17
  64. data/lib/mongoid/contextual/aggregable/memory.rb +24 -16
  65. data/lib/mongoid/contextual/aggregable/mongo.rb +5 -5
  66. data/lib/mongoid/contextual/aggregable/none.rb +1 -1
  67. data/lib/mongoid/contextual/atomic.rb +1 -1
  68. data/lib/mongoid/contextual/geo_near.rb +7 -7
  69. data/lib/mongoid/contextual/map_reduce.rb +2 -2
  70. data/lib/mongoid/contextual/memory.rb +59 -32
  71. data/lib/mongoid/contextual/mongo.rb +184 -256
  72. data/lib/mongoid/contextual/none.rb +34 -16
  73. data/lib/mongoid/contextual/queryable.rb +1 -1
  74. data/lib/mongoid/contextual.rb +2 -2
  75. data/lib/mongoid/copyable.rb +32 -8
  76. data/lib/mongoid/criteria/findable.rb +7 -4
  77. data/lib/mongoid/criteria/includable.rb +24 -20
  78. data/lib/mongoid/criteria/marshalable.rb +10 -2
  79. data/lib/mongoid/criteria/permission.rb +1 -1
  80. data/lib/mongoid/criteria/queryable/aggregable.rb +2 -2
  81. data/lib/mongoid/criteria/queryable/extensions/array.rb +2 -15
  82. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -4
  83. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +2 -2
  84. data/lib/mongoid/criteria/queryable/extensions/date.rb +6 -1
  85. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +6 -1
  86. data/lib/mongoid/criteria/queryable/extensions/hash.rb +0 -16
  87. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -1
  88. data/lib/mongoid/criteria/queryable/extensions/object.rb +2 -1
  89. data/lib/mongoid/criteria/queryable/extensions/range.rb +13 -5
  90. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
  91. data/lib/mongoid/criteria/queryable/extensions/set.rb +1 -1
  92. data/lib/mongoid/criteria/queryable/extensions/string.rb +3 -3
  93. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +4 -2
  94. data/lib/mongoid/criteria/queryable/extensions/time.rb +6 -1
  95. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +6 -1
  96. data/lib/mongoid/criteria/queryable/key.rb +3 -3
  97. data/lib/mongoid/criteria/queryable/optional.rb +5 -11
  98. data/lib/mongoid/criteria/queryable/options.rb +2 -2
  99. data/lib/mongoid/criteria/queryable/pipeline.rb +1 -1
  100. data/lib/mongoid/criteria/queryable/selectable.rb +5 -27
  101. data/lib/mongoid/criteria/queryable/selector.rb +92 -7
  102. data/lib/mongoid/criteria/queryable/smash.rb +40 -7
  103. data/lib/mongoid/criteria/queryable.rb +12 -7
  104. data/lib/mongoid/criteria/scopable.rb +2 -2
  105. data/lib/mongoid/criteria.rb +15 -37
  106. data/lib/mongoid/deprecable.rb +36 -0
  107. data/lib/mongoid/deprecation.rb +25 -0
  108. data/lib/mongoid/document.rb +98 -36
  109. data/lib/mongoid/equality.rb +12 -12
  110. data/lib/mongoid/errors/document_not_found.rb +10 -6
  111. data/lib/mongoid/errors/invalid_config_option.rb +1 -1
  112. data/lib/mongoid/errors/invalid_dependent_strategy.rb +1 -1
  113. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
  114. data/lib/mongoid/errors/invalid_field.rb +6 -2
  115. data/lib/mongoid/errors/invalid_field_type.rb +26 -0
  116. data/lib/mongoid/errors/invalid_relation.rb +1 -1
  117. data/lib/mongoid/errors/invalid_relation_option.rb +1 -1
  118. data/lib/mongoid/errors/invalid_session_use.rb +1 -1
  119. data/lib/mongoid/errors/invalid_storage_options.rb +1 -1
  120. data/lib/mongoid/errors/mongoid_error.rb +3 -3
  121. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +1 -1
  122. data/lib/mongoid/errors/no_client_database.rb +1 -1
  123. data/lib/mongoid/errors/no_client_hosts.rb +1 -1
  124. data/lib/mongoid/errors/readonly_attribute.rb +1 -1
  125. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
  126. data/lib/mongoid/errors/unknown_attribute.rb +1 -1
  127. data/lib/mongoid/errors.rb +2 -2
  128. data/lib/mongoid/extensions/array.rb +9 -7
  129. data/lib/mongoid/extensions/big_decimal.rb +29 -10
  130. data/lib/mongoid/extensions/binary.rb +42 -0
  131. data/lib/mongoid/extensions/boolean.rb +8 -2
  132. data/lib/mongoid/extensions/date.rb +26 -20
  133. data/lib/mongoid/extensions/date_time.rb +1 -1
  134. data/lib/mongoid/extensions/false_class.rb +1 -1
  135. data/lib/mongoid/extensions/float.rb +4 -5
  136. data/lib/mongoid/extensions/hash.rb +13 -6
  137. data/lib/mongoid/extensions/integer.rb +4 -5
  138. data/lib/mongoid/extensions/module.rb +1 -1
  139. data/lib/mongoid/extensions/object.rb +8 -6
  140. data/lib/mongoid/extensions/range.rb +41 -10
  141. data/lib/mongoid/extensions/regexp.rb +11 -4
  142. data/lib/mongoid/extensions/set.rb +11 -4
  143. data/lib/mongoid/extensions/string.rb +11 -22
  144. data/lib/mongoid/extensions/symbol.rb +4 -15
  145. data/lib/mongoid/extensions/time.rb +27 -16
  146. data/lib/mongoid/extensions/time_with_zone.rb +1 -2
  147. data/lib/mongoid/extensions/true_class.rb +1 -1
  148. data/lib/mongoid/extensions.rb +1 -0
  149. data/lib/mongoid/factory.rb +42 -7
  150. data/lib/mongoid/fields/foreign_key.rb +11 -4
  151. data/lib/mongoid/fields/localized.rb +2 -2
  152. data/lib/mongoid/fields/standard.rb +7 -7
  153. data/lib/mongoid/fields/validators/macro.rb +3 -9
  154. data/lib/mongoid/fields.rb +57 -15
  155. data/lib/mongoid/findable.rb +28 -22
  156. data/lib/mongoid/indexable/specification.rb +2 -2
  157. data/lib/mongoid/indexable/validators/options.rb +6 -2
  158. data/lib/mongoid/interceptable.rb +73 -13
  159. data/lib/mongoid/matchable.rb +1 -1
  160. data/lib/mongoid/matcher.rb +12 -7
  161. data/lib/mongoid/persistable/creatable.rb +18 -9
  162. data/lib/mongoid/persistable/deletable.rb +1 -1
  163. data/lib/mongoid/persistable/destroyable.rb +1 -1
  164. data/lib/mongoid/persistable/savable.rb +2 -2
  165. data/lib/mongoid/persistable/unsettable.rb +1 -1
  166. data/lib/mongoid/persistable/updatable.rb +19 -12
  167. data/lib/mongoid/persistable/upsertable.rb +1 -1
  168. data/lib/mongoid/persistable.rb +3 -3
  169. data/lib/mongoid/persistence_context.rb +22 -5
  170. data/lib/mongoid/query_cache.rb +8 -260
  171. data/lib/mongoid/railties/controller_runtime.rb +1 -1
  172. data/lib/mongoid/reloadable.rb +7 -3
  173. data/lib/mongoid/scopable.rb +17 -15
  174. data/lib/mongoid/selectable.rb +1 -2
  175. data/lib/mongoid/serializable.rb +10 -6
  176. data/lib/mongoid/stateful.rb +35 -9
  177. data/lib/mongoid/tasks/database.rb +0 -2
  178. data/lib/mongoid/threaded/lifecycle.rb +5 -5
  179. data/lib/mongoid/threaded.rb +9 -9
  180. data/lib/mongoid/timestamps/created.rb +1 -1
  181. data/lib/mongoid/timestamps/updated.rb +2 -2
  182. data/lib/mongoid/touchable.rb +2 -3
  183. data/lib/mongoid/traversable.rb +4 -3
  184. data/lib/mongoid/validatable/localizable.rb +1 -1
  185. data/lib/mongoid/validatable/macros.rb +0 -2
  186. data/lib/mongoid/validatable/presence.rb +2 -2
  187. data/lib/mongoid/validatable/uniqueness.rb +9 -8
  188. data/lib/mongoid/validatable.rb +6 -6
  189. data/lib/mongoid/version.rb +1 -1
  190. data/lib/mongoid/warnings.rb +3 -4
  191. data/lib/mongoid.rb +1 -0
  192. data/spec/config/mongoid.yml +16 -0
  193. data/spec/integration/app_spec.rb +8 -12
  194. data/spec/integration/associations/belongs_to_spec.rb +18 -0
  195. data/spec/integration/associations/embedded_spec.rb +15 -0
  196. data/spec/integration/associations/embeds_many_spec.rb +15 -2
  197. data/spec/integration/associations/embeds_one_spec.rb +18 -0
  198. data/spec/integration/associations/foreign_key_spec.rb +9 -0
  199. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
  200. data/spec/integration/associations/has_one_spec.rb +97 -1
  201. data/spec/integration/associations/scope_option_spec.rb +1 -1
  202. data/spec/integration/callbacks_models.rb +95 -1
  203. data/spec/integration/callbacks_spec.rb +226 -4
  204. data/spec/integration/criteria/range_spec.rb +95 -1
  205. data/spec/integration/discriminator_key_spec.rb +115 -76
  206. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  207. data/spec/integration/i18n_fallbacks_spec.rb +1 -15
  208. data/spec/integration/matcher_examples_spec.rb +20 -13
  209. data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
  210. data/spec/integration/matcher_operator_spec.rb +3 -5
  211. data/spec/integration/persistence/range_field_spec.rb +350 -0
  212. data/spec/mongoid/association/counter_cache_spec.rb +1 -1
  213. data/spec/mongoid/association/depending_spec.rb +9 -9
  214. data/spec/mongoid/association/eager_spec.rb +2 -1
  215. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
  216. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
  217. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +69 -9
  218. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
  219. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +219 -8
  220. data/spec/mongoid/association/embedded/embeds_many_models.rb +157 -0
  221. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +12 -0
  222. data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
  223. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
  224. data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
  225. data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
  226. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
  227. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
  228. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +15 -0
  229. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  230. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -2
  231. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +67 -4
  232. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
  233. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
  234. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
  235. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +2 -56
  236. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +82 -13
  237. data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
  238. data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
  239. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
  240. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
  241. data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
  242. data/spec/mongoid/association/syncable_spec.rb +14 -0
  243. data/spec/mongoid/atomic/paths_spec.rb +0 -14
  244. data/spec/mongoid/attributes/nested_spec.rb +80 -11
  245. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  246. data/spec/mongoid/attributes/projector_spec.rb +1 -5
  247. data/spec/mongoid/attributes_spec.rb +524 -27
  248. data/spec/mongoid/changeable_spec.rb +130 -13
  249. data/spec/mongoid/clients/factory_spec.rb +23 -30
  250. data/spec/mongoid/clients/sessions_spec.rb +0 -38
  251. data/spec/mongoid/clients_spec.rb +32 -2
  252. data/spec/mongoid/config_spec.rb +58 -13
  253. data/spec/mongoid/contextual/aggregable/memory_spec.rb +396 -158
  254. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  255. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  256. data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
  257. data/spec/mongoid/contextual/memory_spec.rb +521 -14
  258. data/spec/mongoid/contextual/mongo_spec.rb +564 -394
  259. data/spec/mongoid/contextual/none_spec.rb +11 -19
  260. data/spec/mongoid/copyable_spec.rb +451 -1
  261. data/spec/mongoid/criteria/findable_spec.rb +86 -210
  262. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  263. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  264. data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
  265. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
  266. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
  267. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
  268. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
  269. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
  270. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
  271. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
  272. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
  273. data/spec/mongoid/criteria/queryable/optional_spec.rb +0 -484
  274. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +50 -0
  275. data/spec/mongoid/criteria/queryable/selectable_spec.rb +77 -85
  276. data/spec/mongoid/criteria/queryable/selector_spec.rb +14 -2
  277. data/spec/mongoid/criteria_spec.rb +469 -1201
  278. data/spec/mongoid/document_fields_spec.rb +173 -24
  279. data/spec/mongoid/document_spec.rb +32 -41
  280. data/spec/mongoid/equality_spec.rb +12 -12
  281. data/spec/mongoid/errors/document_not_found_spec.rb +29 -2
  282. data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
  283. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  284. data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
  285. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  286. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
  287. data/spec/mongoid/extensions/array_spec.rb +16 -2
  288. data/spec/mongoid/extensions/big_decimal_spec.rb +697 -212
  289. data/spec/mongoid/extensions/binary_spec.rb +44 -9
  290. data/spec/mongoid/extensions/boolean_spec.rb +68 -82
  291. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
  292. data/spec/mongoid/extensions/date_spec.rb +71 -1
  293. data/spec/mongoid/extensions/date_time_spec.rb +15 -9
  294. data/spec/mongoid/extensions/float_spec.rb +48 -76
  295. data/spec/mongoid/extensions/hash_spec.rb +30 -0
  296. data/spec/mongoid/extensions/integer_spec.rb +45 -66
  297. data/spec/mongoid/extensions/range_spec.rb +255 -54
  298. data/spec/mongoid/extensions/regexp_spec.rb +58 -33
  299. data/spec/mongoid/extensions/set_spec.rb +106 -0
  300. data/spec/mongoid/extensions/string_spec.rb +53 -25
  301. data/spec/mongoid/extensions/symbol_spec.rb +18 -25
  302. data/spec/mongoid/extensions/time_spec.rb +634 -66
  303. data/spec/mongoid/extensions/time_with_zone_spec.rb +17 -31
  304. data/spec/mongoid/factory_spec.rb +61 -1
  305. data/spec/mongoid/fields_spec.rb +321 -50
  306. data/spec/mongoid/findable_spec.rb +64 -29
  307. data/spec/mongoid/indexable/specification_spec.rb +2 -2
  308. data/spec/mongoid/indexable_spec.rb +39 -20
  309. data/spec/mongoid/interceptable_spec.rb +584 -5
  310. data/spec/mongoid/interceptable_spec_models.rb +235 -4
  311. data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
  312. data/spec/mongoid/mongoizable_spec.rb +285 -0
  313. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  314. data/spec/mongoid/persistable/deletable_spec.rb +2 -2
  315. data/spec/mongoid/persistable/destroyable_spec.rb +2 -2
  316. data/spec/mongoid/persistable/upsertable_spec.rb +14 -0
  317. data/spec/mongoid/persistence_context_spec.rb +50 -1
  318. data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
  319. data/spec/mongoid/query_cache_spec.rb +0 -154
  320. data/spec/mongoid/reloadable_spec.rb +35 -2
  321. data/spec/mongoid/scopable_spec.rb +54 -16
  322. data/spec/mongoid/shardable_spec.rb +14 -0
  323. data/spec/mongoid/stateful_spec.rb +28 -0
  324. data/spec/mongoid/timestamps_spec.rb +390 -0
  325. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  326. data/spec/mongoid/touchable_spec.rb +116 -0
  327. data/spec/mongoid/touchable_spec_models.rb +12 -8
  328. data/spec/mongoid/traversable_spec.rb +4 -11
  329. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  330. data/spec/mongoid/validatable/uniqueness_spec.rb +60 -31
  331. data/spec/mongoid/warnings_spec.rb +35 -0
  332. data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
  333. data/spec/rails/mongoid_spec.rb +4 -16
  334. data/spec/shared/lib/mrss/event_subscriber.rb +5 -15
  335. data/spec/support/constraints.rb +24 -0
  336. data/spec/support/macros.rb +30 -0
  337. data/spec/support/models/augmentation.rb +12 -0
  338. data/spec/support/models/band.rb +3 -0
  339. data/spec/support/models/catalog.rb +24 -0
  340. data/spec/support/models/circus.rb +3 -0
  341. data/spec/support/models/fanatic.rb +8 -0
  342. data/spec/support/models/implant.rb +9 -0
  343. data/spec/support/models/label.rb +2 -0
  344. data/spec/support/models/passport.rb +9 -0
  345. data/spec/support/models/person.rb +1 -0
  346. data/spec/support/models/player.rb +2 -0
  347. data/spec/support/models/powerup.rb +12 -0
  348. data/spec/support/models/registry.rb +1 -0
  349. data/spec/support/models/school.rb +14 -0
  350. data/spec/support/models/shield.rb +18 -0
  351. data/spec/support/models/student.rb +14 -0
  352. data/spec/support/models/weapon.rb +12 -0
  353. data.tar.gz.sig +0 -0
  354. metadata +49 -13
  355. metadata.gz.sig +0 -0
  356. data/lib/mongoid/errors/eager_load.rb +0 -23
  357. data/lib/mongoid/errors/invalid_value.rb +0 -17
  358. data/spec/mongoid/errors/eager_load_spec.rb +0 -31
@@ -25,9 +25,9 @@ module Mongoid
25
25
  # @example Is the attribute present?
26
26
  # person.attribute_present?("title")
27
27
  #
28
- # @param [ String, Symbol ] name The name of the attribute.
28
+ # @param [ String | Symbol ] name The name of the attribute.
29
29
  #
30
- # @return [ true, false ] True if present, false if not.
30
+ # @return [ true | false ] True if present, false if not.
31
31
  def attribute_present?(name)
32
32
  attribute = read_raw_attribute(name)
33
33
  !attribute.blank? || attribute == false
@@ -50,9 +50,9 @@ module Mongoid
50
50
  # @example Does the document have the attribute?
51
51
  # model.has_attribute?(:name)
52
52
  #
53
- # @param [ String, Symbol ] name The name of the attribute.
53
+ # @param [ String | Symbol ] name The name of the attribute.
54
54
  #
55
- # @return [ true, false ] If the key is present in the attributes.
55
+ # @return [ true | false ] If the key is present in the attributes.
56
56
  def has_attribute?(name)
57
57
  attributes.key?(name.to_s)
58
58
  end
@@ -63,9 +63,9 @@ module Mongoid
63
63
  # @example Does the document have the attribute before it was assigned?
64
64
  # model.has_attribute_before_type_cast?(:name)
65
65
  #
66
- # @param [ String, Symbol ] name The name of the attribute.
66
+ # @param [ String | Symbol ] name The name of the attribute.
67
67
  #
68
- # @return [ true, false ] If the key is present in the
68
+ # @return [ true | false ] If the key is present in the
69
69
  # attributes_before_type_cast.
70
70
  def has_attribute_before_type_cast?(name)
71
71
  attributes_before_type_cast.key?(name.to_s)
@@ -80,16 +80,32 @@ module Mongoid
80
80
  # @example Read an attribute (alternate syntax.)
81
81
  # person[:title]
82
82
  #
83
- # @param [ String, Symbol ] name The name of the attribute to get.
83
+ # @param [ String | Symbol ] name The name of the attribute to get.
84
84
  #
85
85
  # @return [ Object ] The value of the attribute.
86
86
  def read_attribute(name)
87
87
  field = fields[name.to_s]
88
88
  raw = read_raw_attribute(name)
89
- field ? field.demongoize(raw) : raw
89
+ process_raw_attribute(name.to_s, raw, field)
90
90
  end
91
91
  alias :[] :read_attribute
92
92
 
93
+
94
+ # Process the raw attribute values just read from the documents attributes.
95
+ #
96
+ # @param [ String ] name The name of the attribute to get.
97
+ # @param [ Object ] raw The raw attribute value.
98
+ # @param [ Field | nil ] field The field to use for demongoization or nil.
99
+ #
100
+ # @return [ Object ] The value of the attribute.
101
+ #
102
+ # @api private
103
+ def process_raw_attribute(name, raw, field)
104
+ value = field ? field.demongoize(raw) : raw
105
+ attribute_will_change!(name) if value.resizable?
106
+ value
107
+ end
108
+
93
109
  # Read a value from the attributes before type cast. If the value has not
94
110
  # yet been assigned then this will return the attribute's existing value
95
111
  # using read_raw_attribute.
@@ -97,7 +113,7 @@ module Mongoid
97
113
  # @example Read an attribute before type cast.
98
114
  # person.read_attribute_before_type_cast(:price)
99
115
  #
100
- # @param [ String, Symbol ] name The name of the attribute to get.
116
+ # @param [ String | Symbol ] name The name of the attribute to get.
101
117
  #
102
118
  # @return [ Object ] The value of the attribute before type cast, if
103
119
  # available. Otherwise, the value of the attribute.
@@ -116,11 +132,12 @@ module Mongoid
116
132
  # @example Remove the attribute.
117
133
  # person.remove_attribute(:title)
118
134
  #
119
- # @param [ String, Symbol ] name The name of the attribute to remove.
135
+ # @param [ String | Symbol ] name The name of the attribute to remove.
120
136
  #
121
137
  # @raise [ Errors::ReadonlyAttribute ] If the field cannot be removed due
122
138
  # to being flagged as reaodnly.
123
139
  def remove_attribute(name)
140
+ validate_writable_field_name!(name.to_s)
124
141
  as_writable_attribute!(name) do |access|
125
142
  _assigning do
126
143
  attribute_will_change!(access)
@@ -140,9 +157,11 @@ module Mongoid
140
157
  # @example Write the attribute (alternate syntax.)
141
158
  # person[:title] = "Mr."
142
159
  #
143
- # @param [ String, Symbol ] name The name of the attribute to update.
160
+ # @param [ String | Symbol ] name The name of the attribute to update.
144
161
  # @param [ Object ] value The value to set for the attribute.
145
162
  def write_attribute(name, value)
163
+ validate_writable_field_name!(name.to_s)
164
+
146
165
  field_name = database_field_name(name)
147
166
 
148
167
  if attribute_missing?(field_name)
@@ -151,7 +170,6 @@ module Mongoid
151
170
 
152
171
  if attribute_writable?(field_name)
153
172
  _assigning do
154
- validate_attribute_value(field_name, value)
155
173
  localized = fields[field_name].try(:localized?)
156
174
  attributes_before_type_cast[name.to_s] = value
157
175
  typed_value = typed_value_for(field_name, value)
@@ -164,6 +182,11 @@ module Mongoid
164
182
  else
165
183
  attributes[field_name] = typed_value
166
184
  end
185
+
186
+ # when writing an attribute, also remove it from the unsets,
187
+ # so that removing then writing doesn't result in a removal.
188
+ delayed_atomic_unsets.delete(field_name)
189
+
167
190
  typed_value
168
191
  end
169
192
  else
@@ -214,7 +237,7 @@ module Mongoid
214
237
  #
215
238
  # @param [ String ] name The name of the attribute.
216
239
  #
217
- # @return [ true, false ] If the attribute is missing.
240
+ # @return [ true | false ] If the attribute is missing.
218
241
  def attribute_missing?(name)
219
242
  !Projector.new(__selected_fields).attribute_or_path_allowed?(name)
220
243
  end
@@ -238,7 +261,7 @@ module Mongoid
238
261
  # @example Is the string in dot syntax.
239
262
  # model.hash_dot_syntax?
240
263
  #
241
- # @return [ true, false ] If the string contains a "."
264
+ # @return [ true | false ] If the string contains a "."
242
265
  def hash_dot_syntax?(string)
243
266
  string.include?(".")
244
267
  end
@@ -248,7 +271,7 @@ module Mongoid
248
271
  # @example Get the value typecasted.
249
272
  # person.typed_value_for(:title, :sir)
250
273
  #
251
- # @param [ String, Symbol ] key The field name.
274
+ # @param [ String | Symbol ] key The field name.
252
275
  # @param [ Object ] value The uncast value.
253
276
  #
254
277
  # @return [ Object ] The cast value.
@@ -266,7 +289,11 @@ module Mongoid
266
289
  end
267
290
 
268
291
  if hash_dot_syntax?(normalized)
269
- attributes.__nested__(normalized)
292
+ if fields.key?(normalized)
293
+ attributes[normalized]
294
+ else
295
+ attributes.__nested__(normalized)
296
+ end
270
297
  else
271
298
  attributes[normalized]
272
299
  end
@@ -325,30 +352,6 @@ module Mongoid
325
352
 
326
353
  private
327
354
 
328
- # Validates an attribute value as being assignable to the specified field.
329
- #
330
- # For now, only Hash and Array fields are validated, and the value is
331
- # being checked to be of an appropriate type (i.e. either Hash or Array,
332
- # respectively, or nil).
333
- #
334
- # This method takes the name of the field as stored in the document
335
- # in the database, not (necessarily) the Ruby method name used to read/write
336
- # the said field.
337
- #
338
- # @param [ String, Symbol ] field_name The name of the field.
339
- # @param [ Object ] value The value to be validated.
340
- def validate_attribute_value(field_name, value)
341
- return if value.nil?
342
- field = fields[field_name]
343
- return unless field
344
- validatable_types = [ Hash, Array ]
345
- if validatable_types.include?(field.type)
346
- unless value.is_a?(field.type)
347
- raise Mongoid::Errors::InvalidValue.new(field.type, value.class)
348
- end
349
- end
350
- end
351
-
352
355
  def lookup_attribute_presence(name, value)
353
356
  if localized_fields.has_key?(name) && value
354
357
  value = localized_fields[name].send(:lookup, value)
@@ -21,7 +21,7 @@ module Mongoid
21
21
  # @example Has the document changed?
22
22
  # model.changed?
23
23
  #
24
- # @return [ true, false ] If the document is changed.
24
+ # @return [ true | false ] If the document is changed.
25
25
  def changed?
26
26
  changes.values.any? { |val| val } || children_changed?
27
27
  end
@@ -30,7 +30,7 @@ module Mongoid
30
30
  #
31
31
  # @note This intentionally only considers children and not descendants.
32
32
  #
33
- # @return [ true, false ] If any children have changed.
33
+ # @return [ true | false ] If any children have changed.
34
34
  def children_changed?
35
35
  _children.any?(&:changed?)
36
36
  end
@@ -62,13 +62,14 @@ module Mongoid
62
62
 
63
63
  # Call this method after save, so the changes can be properly switched.
64
64
  #
65
- # This will unset the memoized children array, set new record to
65
+ # This will unset the memoized children array, set new record flag to
66
66
  # false, set the document as validated, and move the dirty changes.
67
67
  #
68
68
  # @example Move the changes to previous.
69
69
  # person.move_changes
70
70
  def move_changes
71
71
  @previous_changes = changes
72
+ @previous_attributes = attributes.dup
72
73
  Atomic::UPDATES.each do |update|
73
74
  send(update).clear
74
75
  end
@@ -81,6 +82,7 @@ module Mongoid
81
82
  # document.post_persist
82
83
  def post_persist
83
84
  reset_persisted_descendants
85
+ reset_attributes_before_type_cast
84
86
  move_changes
85
87
  end
86
88
 
@@ -100,7 +102,7 @@ module Mongoid
100
102
  # @example Remove a flagged change.
101
103
  # model.remove_change(:field)
102
104
  #
103
- # @param [ Symbol, String ] name The name of the field.
105
+ # @param [ Symbol | String ] name The name of the field.
104
106
  def remove_change(name)
105
107
  changed_attributes.delete(name.to_s)
106
108
  end
@@ -133,6 +135,13 @@ module Mongoid
133
135
 
134
136
  private
135
137
 
138
+ # Get attributes of the document before the document was saved.
139
+ #
140
+ # @return [ Hash ] Previous attributes
141
+ def previous_attributes
142
+ @previous_attributes ||= {}
143
+ end
144
+
136
145
  # Get the old and new value for the provided attribute.
137
146
  #
138
147
  # @example Get the attribute change.
@@ -153,7 +162,7 @@ module Mongoid
153
162
  #
154
163
  # @param [ String ] attr The name of the attribute.
155
164
  #
156
- # @return [ true, false ] Whether the attribute has changed.
165
+ # @return [ true | false ] Whether the attribute has changed.
157
166
  def attribute_changed?(attr)
158
167
  attr = database_field_name(attr)
159
168
  return false unless changed_attributes.key?(attr)
@@ -167,7 +176,7 @@ module Mongoid
167
176
  #
168
177
  # @param [ String ] attr The name of the attribute.
169
178
  #
170
- # @return [ true, false ] If the attribute differs.
179
+ # @return [ true | false ] If the attribute differs.
171
180
  def attribute_changed_from_default?(attr)
172
181
  field = fields[attr]
173
182
  return false unless field
@@ -185,6 +194,25 @@ module Mongoid
185
194
  attribute_changed?(attr) ? changed_attributes[attr] : attributes[attr]
186
195
  end
187
196
 
197
+ # Get the previous attribute value that was changed
198
+ # before the document was saved.
199
+ #
200
+ # It the document has not been saved yet, or was just loaded from database,
201
+ # this method returns nil for all attributes.
202
+ #
203
+ # @param [ String ] attr The attribute name.
204
+ #
205
+ # @return [ Object | nil ] Attribute value before the document was saved,
206
+ # or nil if the document has not been saved yet.
207
+ def attribute_previously_was(attr)
208
+ attr = database_field_name(attr)
209
+ if previous_changes.key?(attr)
210
+ previous_changes[attr].first
211
+ else
212
+ previous_attributes[attr]
213
+ end
214
+ end
215
+
188
216
  # Flag an attribute as going to change.
189
217
  #
190
218
  # @example Flag the attribute.
@@ -221,6 +249,10 @@ module Mongoid
221
249
  end
222
250
  end
223
251
 
252
+ def reset_attributes_before_type_cast
253
+ @attributes_before_type_cast = @attributes.dup
254
+ end
255
+
224
256
  module ClassMethods
225
257
 
226
258
  private
@@ -291,7 +323,7 @@ module Mongoid
291
323
  end
292
324
  end
293
325
 
294
- # Creates the dirty change previous value accessor.
326
+ # Creates the dirty change previous value accessors.
295
327
  #
296
328
  # @example Create the accessor.
297
329
  # Model.create_dirty_previous_value_accessor("name", "alias")
@@ -303,6 +335,9 @@ module Mongoid
303
335
  re_define_method("#{meth}_was") do
304
336
  attribute_was(name)
305
337
  end
338
+ re_define_method("#{meth}_previously_was") do
339
+ attribute_previously_was(name)
340
+ end
306
341
  end
307
342
  end
308
343
 
@@ -12,7 +12,7 @@ module Mongoid
12
12
  # m.save
13
13
  # end
14
14
  #
15
- # @param [ Hash, Mongoid::PersistenceContext ] options_or_context
15
+ # @param [ Hash | Mongoid::PersistenceContext ] options_or_context
16
16
  # The storage options or a persistence context.
17
17
  #
18
18
  # @option options [ String | Symbol ] :collection The collection name.
@@ -45,6 +45,10 @@ module Mongoid
45
45
  PersistenceContext.new(self.class)
46
46
  end
47
47
 
48
+ def persistence_context?
49
+ !!(PersistenceContext.get(self) || PersistenceContext.get(self.class))
50
+ end
51
+
48
52
  private
49
53
 
50
54
  def set_persistence_context(options_or_context)
@@ -43,13 +43,7 @@ module Mongoid
43
43
  Threaded.set_session(session)
44
44
  yield(session)
45
45
  rescue Mongo::Error::InvalidSession => ex
46
- if
47
- # Driver 2.13.0+
48
- defined?(Mongo::Error::SessionsNotSupported) &&
49
- Mongo::Error::SessionsNotSupported === ex ||
50
- # Legacy drivers
51
- ex.message == Mongo::Session::SESSIONS_NOT_SUPPORTED
52
- then
46
+ if Mongo::Error::SessionsNotSupported === ex
53
47
  raise Mongoid::Errors::InvalidSessionUse.new(:sessions_not_supported)
54
48
  end
55
49
  raise Mongoid::Errors::InvalidSessionUse.new(:invalid_session_use)
@@ -100,13 +94,7 @@ module Mongoid
100
94
  Threaded.set_session(session)
101
95
  yield(session)
102
96
  rescue Mongo::Error::InvalidSession => ex
103
- if
104
- # Driver 2.13.0+
105
- defined?(Mongo::Error::SessionsNotSupported) &&
106
- Mongo::Error::SessionsNotSupported === ex ||
107
- # Legacy drivers
108
- ex.message == Mongo::Session::SESSIONS_NOT_SUPPORTED
109
- then
97
+ if Mongo::Error::SessionsNotSupported === ex
110
98
  raise Mongoid::Errors::InvalidSessionUse.new(:sessions_not_supported)
111
99
  end
112
100
  raise Mongoid::Errors::InvalidSessionUse.new(:invalid_session_use)
@@ -17,7 +17,7 @@ module Mongoid
17
17
  # Storage.validate(:collection_name)
18
18
  #
19
19
  # @param [ Class ] klass The model class.
20
- # @param [ Hash, String, Symbol ] options The provided options.
20
+ # @param [ Hash | String | Symbol ] options The provided options.
21
21
  def validate(klass, options)
22
22
  valid_keys?(options) or raise Errors::InvalidStorageOptions.new(klass, options)
23
23
  valid_parent?(klass) or raise Errors::InvalidStorageParent.new(klass)
@@ -31,7 +31,7 @@ module Mongoid
31
31
  #
32
32
  # @param [ Class ] klass
33
33
  #
34
- # @return [ true, false ] If the class is valid
34
+ # @return [ true | false ] If the class is valid.
35
35
  def valid_parent?(klass)
36
36
  !klass.superclass.include?(Mongoid::Document)
37
37
  end
@@ -45,7 +45,7 @@ module Mongoid
45
45
  #
46
46
  # @param [ Hash ] options The options hash.
47
47
  #
48
- # @return [ true, false ] If all keys are valid.
48
+ # @return [ true | false ] If all keys are valid.
49
49
  def valid_keys?(options)
50
50
  return false unless options.is_a?(::Hash)
51
51
  options.keys.all? do |key|
@@ -37,7 +37,7 @@ module Mongoid
37
37
  # @example Validate the client has database.
38
38
  # validator.validate_client_database(:default, {})
39
39
  #
40
- # @param [ String, Symbol ] name The config key.
40
+ # @param [ String | Symbol ] name The config key.
41
41
  # @param [ Hash ] config The configuration.
42
42
  def validate_client_database(name, config)
43
43
  if no_database_or_uri?(config)
@@ -52,7 +52,7 @@ module Mongoid
52
52
  # @example Validate the client has hosts.
53
53
  # validator.validate_client_hosts(:default, {})
54
54
  #
55
- # @param [ String, Symbol ] name The config key.
55
+ # @param [ String | Symbol ] name The config key.
56
56
  # @param [ Hash ] config The configuration.
57
57
  def validate_client_hosts(name, config)
58
58
  if no_hosts_or_uri?(config)
@@ -68,7 +68,7 @@ module Mongoid
68
68
  # @example Validate the uri and options.
69
69
  # validator.validate_client_uri(:default, {})
70
70
  #
71
- # @param [ String, Symbol ] name The config key.
71
+ # @param [ String | Symbol ] name The config key.
72
72
  # @param [ Hash ] config The configuration.
73
73
  def validate_client_uri(name, config)
74
74
  if both_uri_and_standard?(config)
@@ -86,7 +86,7 @@ module Mongoid
86
86
  #
87
87
  # @param [ Hash ] config The configuration options.
88
88
  #
89
- # @return [ true, false ] If no database or uri is defined.
89
+ # @return [ true | false ] If no database or uri is defined.
90
90
  def no_database_or_uri?(config)
91
91
  !config.has_key?(:database) && !config.has_key?(:uri)
92
92
  end
@@ -101,7 +101,7 @@ module Mongoid
101
101
  #
102
102
  # @param [ Hash ] config The configuration options.
103
103
  #
104
- # @return [ true, false ] If no hosts or uri is defined.
104
+ # @return [ true | false ] If no hosts or uri is defined.
105
105
  def no_hosts_or_uri?(config)
106
106
  !config.has_key?(:hosts) && !config.has_key?(:uri)
107
107
  end
@@ -116,7 +116,7 @@ module Mongoid
116
116
  #
117
117
  # @param [ Hash ] config The configuration options.
118
118
  #
119
- # @return [ true, false ] If both standard and uri are defined.
119
+ # @return [ true | false ] If both standard and uri are defined.
120
120
  def both_uri_and_standard?(config)
121
121
  config.has_key?(:uri) && config.keys.any? do |key|
122
122
  STANDARD.include?(key.to_sym)
@@ -75,46 +75,55 @@ module Mongoid
75
75
  # Return stored times as UTC.
76
76
  option :use_utc, default: false
77
77
 
78
+ # Store BigDecimals as Decimal128s instead of strings in the db.
79
+ option :map_big_decimal_to_decimal128, default: true
80
+
78
81
  # Update embedded documents correctly when setting it, unsetting it
79
82
  # and resetting it. See MONGOID-5206 and MONGOID-5240 for more details.
80
- option :broken_updates, default: true
83
+ option :broken_updates, default: false
81
84
 
82
85
  # Maintain legacy behavior of === on Mongoid documents, which returns
83
86
  # true in a number of cases where Ruby's === implementation would
84
87
  # return false.
85
- option :legacy_triple_equals, default: true
88
+ option :legacy_triple_equals, default: false
86
89
 
87
90
  # When exiting a nested `with_scope' block, set the current scope to
88
91
  # nil instead of the parent scope for backwards compatibility.
89
- option :broken_scoping, default: true
92
+ option :broken_scoping, default: false
90
93
 
91
94
  # Maintain broken behavior of sum over empty result sets for backwards
92
95
  # compatibility.
93
- option :broken_aggregables, default: true
96
+ option :broken_aggregables, default: false
94
97
 
95
98
  # Ignore aliased fields in embedded documents when performing pluck and
96
99
  # distinct operations, for backwards compatibility.
97
- option :broken_alias_handling, default: true
100
+ option :broken_alias_handling, default: false
98
101
 
99
102
  # Maintain broken `and' behavior when using the same operator on the same
100
103
  # field multiple times for backwards compatibility.
101
- option :broken_and, default: true
104
+ option :broken_and, default: false
102
105
 
103
106
  # Use millisecond precision when comparing Time objects with the _matches?
104
107
  # function.
105
- option :compare_time_by_ms, default: false
108
+ option :compare_time_by_ms, default: true
106
109
 
107
110
  # Use bson-ruby's implementation of as_json for BSON::ObjectId instead of
108
111
  # the one monkey-patched into Mongoid.
109
- option :object_id_as_json_oid, default: true
112
+ option :object_id_as_json_oid, default: false
110
113
 
111
114
  # Maintain legacy behavior of pluck and distinct, which does not
112
115
  # demongoize the values on returning them.
113
- option :legacy_pluck_distinct, default: true
116
+ option :legacy_pluck_distinct, default: false
114
117
 
115
118
  # Combine chained operators, which use the same field and operator,
116
119
  # using and's instead of overwriting them.
117
- option :overwrite_chained_operators, default: true
120
+ option :overwrite_chained_operators, default: false
121
+
122
+ # When this flag is true, the attributes method on a document will return
123
+ # a BSON::Document when that document is retrieved from the database, and
124
+ # a Hash otherwise. When this flag is false, the attributes method will
125
+ # always return a Hash.
126
+ option :legacy_attributes, default: false
118
127
 
119
128
  # Has Mongoid been configured? This is checking that at least a valid
120
129
  # client config exists.
@@ -122,7 +131,7 @@ module Mongoid
122
131
  # @example Is Mongoid configured?
123
132
  # config.configured?
124
133
  #
125
- # @return [ true, false ] If Mongoid is configured.
134
+ # @return [ true | false ] If Mongoid is configured.
126
135
  def configured?
127
136
  clients.key?(:default)
128
137
  end
@@ -163,7 +172,7 @@ module Mongoid
163
172
  # Mongoid.load!("/path/to/mongoid.yml")
164
173
  #
165
174
  # @param [ String ] path The path to the file.
166
- # @param [ String, Symbol ] environment The environment to load.
175
+ # @param [ String | Symbol ] environment The environment to load.
167
176
  def load!(path, environment = nil)
168
177
  settings = Environment.load_yaml(path, environment)
169
178
  if settings.present?
@@ -207,6 +216,7 @@ module Mongoid
207
216
  configuration = settings.with_indifferent_access
208
217
  self.options = configuration[:options]
209
218
  self.clients = configuration[:clients]
219
+ Mongo.options = configuration[:driver_options] || {}
210
220
  set_log_levels
211
221
  end
212
222
 
@@ -215,9 +225,9 @@ module Mongoid
215
225
  # @example Override the database globally.
216
226
  # config.override_database(:optional)
217
227
  #
218
- # @param [ String, Symbol ] name The name of the database.
228
+ # @param [ String | Symbol ] name The name of the database.
219
229
  #
220
- # @return [ String, Symbol ] The global override.
230
+ # @return [ String | Symbol ] The global override.
221
231
  def override_database(name)
222
232
  Threaded.database_override = name
223
233
  end
@@ -227,9 +237,9 @@ module Mongoid
227
237
  # @example Override the client globally.
228
238
  # config.override_client(:optional)
229
239
  #
230
- # @param [ String, Symbol ] name The name of the client.
240
+ # @param [ String | Symbol ] name The name of the client.
231
241
  #
232
- # @return [ String, Symbol ] The global override.
242
+ # @return [ String | Symbol ] The global override.
233
243
  def override_client(name)
234
244
  Threaded.client_override = name ? name.to_s : nil
235
245
  end
@@ -300,7 +310,7 @@ module Mongoid
300
310
  # @example Is the application using passenger?
301
311
  # config.running_with_passenger?
302
312
  #
303
- # @return [ true, false ] If the app is deployed on Passenger.
313
+ # @return [ true | false ] If the app is deployed on Passenger.
304
314
  def running_with_passenger?
305
315
  @running_with_passenger ||= defined?(PhusionPassenger)
306
316
  end
@@ -9,7 +9,7 @@ module Mongoid
9
9
  # Get all the aggregate values for the provided field.
10
10
  # Provided for interface consistency with Aggregable::Mongo.
11
11
  #
12
- # @param [ String, Symbol ] field The field name.
12
+ # @param [ String | Symbol ] field The field name.
13
13
  #
14
14
  # @return [ Hash ] A Hash containing the aggregate values.
15
15
  # If no documents are present, then returned Hash will have
@@ -27,9 +27,13 @@ module Mongoid
27
27
  #
28
28
  # @param [ Symbol ] field The field to average.
29
29
  #
30
- # @return [ Float ] The average.
30
+ # @return [ Numeric ] The average.
31
31
  def avg(field)
32
- count > 0 ? sum(field).to_f / count.to_f : nil
32
+ total = count { |doc| !doc.send(field).nil? }
33
+ return nil unless total > 0
34
+
35
+ total = total.to_f if total.is_a?(Integer)
36
+ sum(field) / total
33
37
  end
34
38
 
35
39
  # Get the max value of the provided field. If provided a block, will
@@ -46,10 +50,12 @@ module Mongoid
46
50
  #
47
51
  # @param [ Symbol ] field The field to max.
48
52
  #
49
- # @return [ Float, Document ] The max value or document with the max
53
+ # @return [ Numeric | Document ] The max value or document with the max
50
54
  # value.
51
55
  def max(field = nil)
52
- block_given? ? super() : aggregate_by(field, :max_by)
56
+ return super() if block_given?
57
+
58
+ aggregate_by(field, :max)
53
59
  end
54
60
 
55
61
  # Get the min value of the provided field. If provided a block, will
@@ -66,10 +72,12 @@ module Mongoid
66
72
  #
67
73
  # @param [ Symbol ] field The field to min.
68
74
  #
69
- # @return [ Float, Document ] The min value or document with the min
75
+ # @return [ Numeric | Document ] The min value or document with the min
70
76
  # value.
71
77
  def min(field = nil)
72
- block_given? ? super() : aggregate_by(field, :min_by)
78
+ return super() if block_given?
79
+
80
+ aggregate_by(field, :min)
73
81
  end
74
82
 
75
83
  # Get the sum value of the provided field. If provided a block, will
@@ -83,13 +91,11 @@ module Mongoid
83
91
  #
84
92
  # @param [ Symbol ] field The field to sum.
85
93
  #
86
- # @return [ Float ] The sum value.
94
+ # @return [ Numeric ] The sum value.
87
95
  def sum(field = nil)
88
- if block_given?
89
- super()
90
- else
91
- count > 0 ? super(0) { |doc| doc.public_send(field) } : 0
92
- end
96
+ return super() if block_given?
97
+
98
+ aggregate_by(field, :sum) || 0
93
99
  end
94
100
 
95
101
  private
@@ -99,14 +105,16 @@ module Mongoid
99
105
  # @api private
100
106
  #
101
107
  # @example Aggregate by the field and method.
102
- # aggregable.aggregate_by(:name, :min_by)
108
+ # aggregable.aggregate_by(:likes, :min_by)
103
109
  #
104
110
  # @param [ Symbol ] field The field to aggregate on.
105
111
  # @param [ Symbol ] method The method (min_by or max_by).
106
112
  #
107
- # @return [ Integer ] The aggregate.
113
+ # @return [ Numeric | nil ] The aggregate.
108
114
  def aggregate_by(field, method)
109
- count > 0 ? send(method) { |doc| doc.public_send(field) }.public_send(field) : nil
115
+ return nil unless any?
116
+
117
+ map { |doc| doc.public_send(field) }.compact.public_send(method)
110
118
  end
111
119
  end
112
120
  end