mongoid 7.4.0 → 8.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (315) 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 +51 -28
  5. data/lib/mongoid/association/accessors.rb +32 -3
  6. data/lib/mongoid/association/bindable.rb +48 -0
  7. data/lib/mongoid/association/builders.rb +4 -2
  8. data/lib/mongoid/association/eager_loadable.rb +29 -7
  9. data/lib/mongoid/association/embedded/batchable.rb +48 -8
  10. data/lib/mongoid/association/embedded/embedded_in/binding.rb +24 -2
  11. data/lib/mongoid/association/embedded/embedded_in.rb +2 -1
  12. data/lib/mongoid/association/embedded/embeds_many/binding.rb +1 -0
  13. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +1 -1
  14. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +40 -18
  15. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +18 -4
  16. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +21 -2
  17. data/lib/mongoid/association/macros.rb +22 -1
  18. data/lib/mongoid/association/many.rb +5 -0
  19. data/lib/mongoid/association/nested/many.rb +2 -1
  20. data/lib/mongoid/association/proxy.rb +12 -0
  21. data/lib/mongoid/association/referenced/auto_save.rb +3 -2
  22. data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
  23. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
  24. data/lib/mongoid/association/referenced/belongs_to.rb +1 -1
  25. data/lib/mongoid/association/referenced/counter_cache.rb +8 -8
  26. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +64 -11
  27. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +4 -1
  28. data/lib/mongoid/association/referenced/has_many/enumerable.rb +10 -14
  29. data/lib/mongoid/association/referenced/has_many/proxy.rb +12 -9
  30. data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -1
  31. data/lib/mongoid/association/referenced/has_one/proxy.rb +8 -11
  32. data/lib/mongoid/association/referenced/syncable.rb +2 -2
  33. data/lib/mongoid/association/relatable.rb +38 -4
  34. data/lib/mongoid/atomic/paths/embedded/many.rb +19 -0
  35. data/lib/mongoid/attributes/processing.rb +9 -2
  36. data/lib/mongoid/attributes.rb +30 -27
  37. data/lib/mongoid/changeable.rb +37 -2
  38. data/lib/mongoid/clients/options.rb +4 -0
  39. data/lib/mongoid/clients/sessions.rb +2 -14
  40. data/lib/mongoid/config/environment.rb +20 -4
  41. data/lib/mongoid/config.rb +25 -10
  42. data/lib/mongoid/contextual/aggregable/memory.rb +23 -15
  43. data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
  44. data/lib/mongoid/contextual/map_reduce.rb +2 -2
  45. data/lib/mongoid/contextual/memory.rb +176 -17
  46. data/lib/mongoid/contextual/mongo.rb +226 -206
  47. data/lib/mongoid/contextual/none.rb +66 -4
  48. data/lib/mongoid/copyable.rb +32 -8
  49. data/lib/mongoid/criteria/includable.rb +24 -20
  50. data/lib/mongoid/criteria/marshalable.rb +10 -2
  51. data/lib/mongoid/criteria/queryable/extensions/array.rb +2 -13
  52. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -4
  53. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
  54. data/lib/mongoid/criteria/queryable/extensions/date.rb +6 -1
  55. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +6 -1
  56. data/lib/mongoid/criteria/queryable/extensions/hash.rb +0 -14
  57. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -1
  58. data/lib/mongoid/criteria/queryable/extensions/object.rb +2 -1
  59. data/lib/mongoid/criteria/queryable/extensions/range.rb +13 -5
  60. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +1 -1
  61. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +3 -1
  62. data/lib/mongoid/criteria/queryable/extensions/time.rb +6 -1
  63. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +6 -1
  64. data/lib/mongoid/criteria/queryable/mergeable.rb +21 -0
  65. data/lib/mongoid/criteria/queryable/optional.rb +3 -9
  66. data/lib/mongoid/criteria/queryable/options.rb +1 -1
  67. data/lib/mongoid/criteria/queryable/selectable.rb +28 -34
  68. data/lib/mongoid/criteria/queryable/selector.rb +89 -4
  69. data/lib/mongoid/criteria/queryable/smash.rb +39 -6
  70. data/lib/mongoid/criteria/queryable.rb +11 -6
  71. data/lib/mongoid/criteria.rb +1 -26
  72. data/lib/mongoid/deprecable.rb +36 -0
  73. data/lib/mongoid/deprecation.rb +25 -0
  74. data/lib/mongoid/document.rb +96 -32
  75. data/lib/mongoid/errors/document_not_found.rb +29 -8
  76. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
  77. data/lib/mongoid/errors/invalid_field.rb +5 -1
  78. data/lib/mongoid/errors/invalid_field_type.rb +26 -0
  79. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
  80. data/lib/mongoid/errors.rb +2 -2
  81. data/lib/mongoid/extensions/array.rb +8 -6
  82. data/lib/mongoid/extensions/big_decimal.rb +29 -10
  83. data/lib/mongoid/extensions/binary.rb +42 -0
  84. data/lib/mongoid/extensions/boolean.rb +8 -2
  85. data/lib/mongoid/extensions/date.rb +26 -20
  86. data/lib/mongoid/extensions/date_time.rb +1 -1
  87. data/lib/mongoid/extensions/float.rb +4 -5
  88. data/lib/mongoid/extensions/hash.rb +12 -5
  89. data/lib/mongoid/extensions/integer.rb +4 -5
  90. data/lib/mongoid/extensions/object.rb +2 -0
  91. data/lib/mongoid/extensions/range.rb +41 -10
  92. data/lib/mongoid/extensions/regexp.rb +11 -4
  93. data/lib/mongoid/extensions/set.rb +11 -4
  94. data/lib/mongoid/extensions/string.rb +2 -13
  95. data/lib/mongoid/extensions/symbol.rb +3 -14
  96. data/lib/mongoid/extensions/time.rb +27 -16
  97. data/lib/mongoid/extensions/time_with_zone.rb +1 -2
  98. data/lib/mongoid/extensions.rb +1 -0
  99. data/lib/mongoid/factory.rb +42 -7
  100. data/lib/mongoid/fields/foreign_key.rb +7 -0
  101. data/lib/mongoid/fields/validators/macro.rb +3 -9
  102. data/lib/mongoid/fields.rb +194 -28
  103. data/lib/mongoid/findable.rb +27 -7
  104. data/lib/mongoid/indexable/specification.rb +1 -1
  105. data/lib/mongoid/indexable/validators/options.rb +4 -1
  106. data/lib/mongoid/interceptable.rb +69 -9
  107. data/lib/mongoid/persistable/creatable.rb +14 -5
  108. data/lib/mongoid/persistable/updatable.rb +12 -5
  109. data/lib/mongoid/persistable/upsertable.rb +1 -1
  110. data/lib/mongoid/persistence_context.rb +19 -2
  111. data/lib/mongoid/query_cache.rb +6 -258
  112. data/lib/mongoid/railties/controller_runtime.rb +1 -1
  113. data/lib/mongoid/reloadable.rb +7 -3
  114. data/lib/mongoid/selectable.rb +1 -2
  115. data/lib/mongoid/stateful.rb +27 -1
  116. data/lib/mongoid/timestamps/created.rb +1 -1
  117. data/lib/mongoid/timestamps/updated.rb +1 -1
  118. data/lib/mongoid/touchable.rb +2 -3
  119. data/lib/mongoid/traversable.rb +5 -1
  120. data/lib/mongoid/validatable/uniqueness.rb +2 -1
  121. data/lib/mongoid/version.rb +1 -1
  122. data/lib/mongoid/warnings.rb +28 -0
  123. data/lib/mongoid.rb +2 -0
  124. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +11 -5
  125. data/spec/config/mongoid.yml +16 -0
  126. data/spec/config/mongoid_with_schema_map_uuid.yml +27 -0
  127. data/spec/integration/app_spec.rb +28 -26
  128. data/spec/integration/associations/belongs_to_spec.rb +18 -0
  129. data/spec/integration/associations/embedded_dirty_spec.rb +28 -0
  130. data/spec/integration/associations/embedded_spec.rb +15 -0
  131. data/spec/integration/associations/embeds_many_spec.rb +15 -2
  132. data/spec/integration/associations/embeds_one_spec.rb +18 -0
  133. data/spec/integration/associations/foreign_key_spec.rb +9 -0
  134. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
  135. data/spec/integration/associations/has_one_spec.rb +97 -1
  136. data/spec/integration/associations/scope_option_spec.rb +1 -1
  137. data/spec/integration/callbacks_models.rb +95 -1
  138. data/spec/integration/callbacks_spec.rb +226 -4
  139. data/spec/integration/criteria/range_spec.rb +95 -1
  140. data/spec/integration/discriminator_key_spec.rb +115 -76
  141. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  142. data/spec/integration/matcher_examples_spec.rb +20 -13
  143. data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
  144. data/spec/integration/matcher_operator_spec.rb +3 -5
  145. data/spec/integration/persistence/range_field_spec.rb +350 -0
  146. data/spec/lite_spec_helper.rb +1 -1
  147. data/spec/mongoid/association/counter_cache_spec.rb +1 -1
  148. data/spec/mongoid/association/depending_spec.rb +9 -9
  149. data/spec/mongoid/association/eager_spec.rb +2 -1
  150. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
  151. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
  152. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +69 -9
  153. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
  154. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +219 -8
  155. data/spec/mongoid/association/embedded/embeds_many_models.rb +157 -0
  156. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +12 -0
  157. data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
  158. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
  159. data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
  160. data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
  161. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
  162. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
  163. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +15 -0
  164. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  165. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -2
  166. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +67 -4
  167. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
  168. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
  169. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
  170. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +8 -8
  171. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +82 -13
  172. data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
  173. data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
  174. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
  175. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
  176. data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
  177. data/spec/mongoid/association/syncable_spec.rb +14 -0
  178. data/spec/mongoid/atomic/paths_spec.rb +0 -14
  179. data/spec/mongoid/atomic_spec.rb +22 -0
  180. data/spec/mongoid/attributes/nested_spec.rb +80 -11
  181. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  182. data/spec/mongoid/attributes/projector_spec.rb +1 -5
  183. data/spec/mongoid/attributes_spec.rb +524 -27
  184. data/spec/mongoid/changeable_spec.rb +130 -13
  185. data/spec/mongoid/clients/factory_spec.rb +34 -42
  186. data/spec/mongoid/clients/options_spec.rb +1 -0
  187. data/spec/mongoid/clients/sessions_spec.rb +0 -38
  188. data/spec/mongoid/clients_spec.rb +32 -2
  189. data/spec/mongoid/config/environment_spec.rb +39 -1
  190. data/spec/mongoid/config_spec.rb +104 -13
  191. data/spec/mongoid/contextual/aggregable/memory_spec.rb +396 -158
  192. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  193. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  194. data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
  195. data/spec/mongoid/contextual/memory_spec.rb +1337 -69
  196. data/spec/mongoid/contextual/mongo_spec.rb +1105 -172
  197. data/spec/mongoid/contextual/none_spec.rb +38 -0
  198. data/spec/mongoid/copyable_spec.rb +451 -1
  199. data/spec/mongoid/criteria/findable_spec.rb +86 -210
  200. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  201. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  202. data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
  203. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
  204. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
  205. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
  206. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
  207. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
  208. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
  209. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
  210. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
  211. data/spec/mongoid/criteria/queryable/optional_spec.rb +0 -484
  212. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +50 -0
  213. data/spec/mongoid/criteria/queryable/selectable_spec.rb +289 -124
  214. data/spec/mongoid/criteria/queryable/selector_spec.rb +14 -2
  215. data/spec/mongoid/criteria_spec.rb +474 -1198
  216. data/spec/mongoid/document_fields_spec.rb +173 -24
  217. data/spec/mongoid/document_spec.rb +32 -41
  218. data/spec/mongoid/errors/document_not_found_spec.rb +76 -0
  219. data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
  220. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  221. data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
  222. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  223. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
  224. data/spec/mongoid/extensions/array_spec.rb +16 -2
  225. data/spec/mongoid/extensions/big_decimal_spec.rb +697 -212
  226. data/spec/mongoid/extensions/binary_spec.rb +44 -9
  227. data/spec/mongoid/extensions/boolean_spec.rb +68 -82
  228. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
  229. data/spec/mongoid/extensions/date_spec.rb +71 -1
  230. data/spec/mongoid/extensions/date_time_spec.rb +15 -9
  231. data/spec/mongoid/extensions/float_spec.rb +48 -76
  232. data/spec/mongoid/extensions/hash_spec.rb +30 -0
  233. data/spec/mongoid/extensions/integer_spec.rb +45 -66
  234. data/spec/mongoid/extensions/range_spec.rb +255 -54
  235. data/spec/mongoid/extensions/regexp_spec.rb +58 -33
  236. data/spec/mongoid/extensions/set_spec.rb +106 -0
  237. data/spec/mongoid/extensions/string_spec.rb +53 -25
  238. data/spec/mongoid/extensions/symbol_spec.rb +18 -25
  239. data/spec/mongoid/extensions/time_spec.rb +634 -66
  240. data/spec/mongoid/extensions/time_with_zone_spec.rb +17 -31
  241. data/spec/mongoid/factory_spec.rb +61 -1
  242. data/spec/mongoid/fields_spec.rb +321 -50
  243. data/spec/mongoid/findable_spec.rb +80 -15
  244. data/spec/mongoid/indexable/specification_spec.rb +2 -2
  245. data/spec/mongoid/indexable_spec.rb +16 -19
  246. data/spec/mongoid/interceptable_spec.rb +584 -5
  247. data/spec/mongoid/interceptable_spec_models.rb +235 -4
  248. data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
  249. data/spec/mongoid/mongoizable_spec.rb +285 -0
  250. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  251. data/spec/mongoid/persistable/deletable_spec.rb +2 -2
  252. data/spec/mongoid/persistable/destroyable_spec.rb +2 -2
  253. data/spec/mongoid/persistable/upsertable_spec.rb +14 -0
  254. data/spec/mongoid/persistence_context_spec.rb +50 -1
  255. data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
  256. data/spec/mongoid/query_cache_spec.rb +0 -154
  257. data/spec/mongoid/reloadable_spec.rb +35 -2
  258. data/spec/mongoid/scopable_spec.rb +21 -1
  259. data/spec/mongoid/shardable_spec.rb +14 -0
  260. data/spec/mongoid/stateful_spec.rb +28 -0
  261. data/spec/mongoid/timestamps_spec.rb +390 -0
  262. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  263. data/spec/mongoid/touchable_spec.rb +116 -0
  264. data/spec/mongoid/touchable_spec_models.rb +12 -8
  265. data/spec/mongoid/traversable_spec.rb +4 -11
  266. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  267. data/spec/mongoid/validatable/uniqueness_spec.rb +60 -31
  268. data/spec/mongoid/warnings_spec.rb +35 -0
  269. data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
  270. data/spec/rails/mongoid_spec.rb +4 -16
  271. data/spec/shared/lib/mrss/constraints.rb +8 -16
  272. data/spec/shared/lib/mrss/docker_runner.rb +23 -3
  273. data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
  274. data/spec/shared/lib/mrss/lite_constraints.rb +32 -1
  275. data/spec/shared/share/Dockerfile.erb +34 -48
  276. data/spec/shared/shlib/config.sh +27 -0
  277. data/spec/shared/shlib/server.sh +32 -19
  278. data/spec/shared/shlib/set_env.sh +37 -0
  279. data/spec/support/constraints.rb +24 -0
  280. data/spec/support/macros.rb +39 -0
  281. data/spec/support/models/augmentation.rb +12 -0
  282. data/spec/support/models/band.rb +3 -0
  283. data/spec/support/models/catalog.rb +24 -0
  284. data/spec/support/models/circus.rb +3 -0
  285. data/spec/support/models/code.rb +2 -0
  286. data/spec/support/models/fanatic.rb +8 -0
  287. data/spec/support/models/implant.rb +9 -0
  288. data/spec/support/models/label.rb +2 -0
  289. data/spec/support/models/membership.rb +1 -0
  290. data/spec/support/models/passport.rb +9 -0
  291. data/spec/support/models/person.rb +1 -0
  292. data/spec/support/models/player.rb +2 -0
  293. data/spec/support/models/powerup.rb +12 -0
  294. data/spec/support/models/registry.rb +1 -0
  295. data/spec/support/models/school.rb +14 -0
  296. data/spec/support/models/shield.rb +18 -0
  297. data/spec/support/models/student.rb +14 -0
  298. data/spec/support/models/weapon.rb +12 -0
  299. data/spec/support/schema_maps/schema_map_aws.json +17 -0
  300. data/spec/support/schema_maps/schema_map_aws_key_alt_names.json +12 -0
  301. data/spec/support/schema_maps/schema_map_azure.json +17 -0
  302. data/spec/support/schema_maps/schema_map_azure_key_alt_names.json +12 -0
  303. data/spec/support/schema_maps/schema_map_gcp.json +17 -0
  304. data/spec/support/schema_maps/schema_map_gcp_key_alt_names.json +12 -0
  305. data/spec/support/schema_maps/schema_map_kmip.json +17 -0
  306. data/spec/support/schema_maps/schema_map_kmip_key_alt_names.json +12 -0
  307. data/spec/support/schema_maps/schema_map_local.json +18 -0
  308. data/spec/support/schema_maps/schema_map_local_key_alt_names.json +12 -0
  309. data/spec/support/spec_config.rb +4 -0
  310. data.tar.gz.sig +0 -0
  311. metadata +76 -13
  312. metadata.gz.sig +0 -0
  313. data/lib/mongoid/errors/eager_load.rb +0 -23
  314. data/lib/mongoid/errors/invalid_value.rb +0 -17
  315. data/spec/mongoid/errors/eager_load_spec.rb +0 -31
@@ -38,12 +38,16 @@ module Mongoid
38
38
  :max,
39
39
  :min,
40
40
  :none,
41
+ :pick,
41
42
  :pluck,
42
43
  :read,
43
44
  :sum,
45
+ :take,
46
+ :take!,
47
+ :tally,
44
48
  :text_search,
45
49
  :update,
46
- :update_all
50
+ :update_all,
47
51
 
48
52
  # Returns a count of records in the database.
49
53
  # If you want to specify conditions use where.
@@ -118,6 +122,13 @@ module Mongoid
118
122
  # strings will be transparently converted to +BSON::ObjectId+ instances
119
123
  # during query construction.
120
124
  #
125
+ # If this method is given a block, it delegates to +Enumerable#find+ and
126
+ # returns the first document of those found by the current Crieria object
127
+ # for which the block returns a truthy value. If both a block and ids are
128
+ # given, the block is ignored and the documents for the given ids are
129
+ # returned. If a block and a Proc are given, the method delegates to
130
+ # +Enumerable#find+ and uses the proc as the default.
131
+ #
121
132
  # The +find+ method takes into account the default scope defined on the
122
133
  # model class, if any.
123
134
  #
@@ -128,8 +139,13 @@ module Mongoid
128
139
  #
129
140
  # @raise Errors::DocumentNotFound If not all documents are found and
130
141
  # the +raise_not_found_error+ Mongoid configuration option is truthy.
131
- def find(*args)
132
- with_default_scope.find(*args)
142
+ def find(*args, &block)
143
+ empty_or_proc = args.empty? || (args.length == 1 && args.first.is_a?(Proc))
144
+ if block_given? && empty_or_proc
145
+ with_default_scope.find(*args, &block)
146
+ else
147
+ with_default_scope.find(*args)
148
+ end
133
149
  end
134
150
 
135
151
  # Find the first +Document+ given the conditions.
@@ -179,9 +195,11 @@ module Mongoid
179
195
  # @example Find the first document.
180
196
  # Person.first
181
197
  #
198
+ # @param [ Integer ] limit The number of documents to return.
199
+ #
182
200
  # @return [ Document ] The first matching document.
183
- def first
184
- with_default_scope.first
201
+ def first(limit = nil)
202
+ with_default_scope.first(limit)
185
203
  end
186
204
  alias :one :first
187
205
 
@@ -190,9 +208,11 @@ module Mongoid
190
208
  # @example Find the last document.
191
209
  # Person.last
192
210
  #
211
+ # @param [ Integer ] limit The number of documents to return.
212
+ #
193
213
  # @return [ Document ] The last matching document.
194
- def last
195
- with_default_scope.last
214
+ def last(limit = nil)
215
+ with_default_scope.last(limit)
196
216
  end
197
217
  end
198
218
  end
@@ -86,7 +86,7 @@ module Mongoid
86
86
  # @api private
87
87
  #
88
88
  # @example Normalize the index options.
89
- # specification.normalize_options(drop_dups: true)
89
+ # specification.normalize_options(unique: true)
90
90
  #
91
91
  # @param [ Hash ] opts The index options.
92
92
  #
@@ -13,7 +13,6 @@ module Mongoid
13
13
  :database,
14
14
  :default_language,
15
15
  :language_override,
16
- :drop_dups,
17
16
  :name,
18
17
  :sparse,
19
18
  :unique,
@@ -98,6 +97,10 @@ module Mongoid
98
97
  unless VALID_TYPES.include?(value)
99
98
  raise Errors::InvalidIndex.new(klass, spec, options)
100
99
  end
100
+
101
+ if value == "geoHaystack"
102
+ Mongoid::Warnings.warn_geo_haystack_deprecated
103
+ end
101
104
  end
102
105
  end
103
106
  end
@@ -27,7 +27,7 @@ module Mongoid
27
27
  :before_save,
28
28
  :before_update,
29
29
  :before_upsert,
30
- :before_validation
30
+ :before_validation,
31
31
  ].freeze
32
32
 
33
33
  included do
@@ -37,6 +37,12 @@ module Mongoid
37
37
  define_model_callbacks :build, :find, :initialize, :touch, only: :after
38
38
  define_model_callbacks :create, :destroy, :save, :update, :upsert
39
39
 
40
+ # This callback is used internally by Mongoid to save association
41
+ # targets for referenced associations after the parent model is persisted.
42
+ #
43
+ # @api private
44
+ define_model_callbacks :persist_parent
45
+
40
46
  attr_accessor :before_callback_halted
41
47
  end
42
48
 
@@ -109,22 +115,76 @@ module Mongoid
109
115
  # end
110
116
  #
111
117
  # @param [ Symbol ] kind The type of callback to execute.
112
- # @param [ Array ] args Any options.
113
- #
114
- # @return [ Document ] The document
115
- ruby2_keywords def run_callbacks(kind, *args, &block)
116
- cascadable_children(kind).each do |child|
117
- if child.run_callbacks(child_callback_type(kind, child), *args) == false
118
- return false
118
+ # @param [ true | false ] with_children Flag specifies whether callbacks of embedded document should be run.
119
+ def run_callbacks(kind, with_children: true, &block)
120
+ if with_children
121
+ cascadable_children(kind).each do |child|
122
+ if child.run_callbacks(child_callback_type(kind, child), with_children: with_children) == false
123
+ return false
124
+ end
119
125
  end
120
126
  end
121
127
  if callback_executable?(kind)
122
- super(kind, *args, &block)
128
+ super(kind, &block)
123
129
  else
124
130
  true
125
131
  end
126
132
  end
127
133
 
134
+ # Run the callbacks for embedded documents.
135
+ #
136
+ # @param [ Symbol ] kind The type of callback to execute.
137
+ # @param [ Array<Document> ] children Children to exeute callbacks on. If
138
+ # nil, callbacks will be executed on all cascadable children of
139
+ # the document.
140
+ #
141
+ # @api private
142
+ def _mongoid_run_child_callbacks(kind, children: nil, &block)
143
+ child, *tail = (children || cascadable_children(kind))
144
+ if child.nil?
145
+ return block&.call
146
+ elsif tail.empty?
147
+ return child.run_callbacks(child_callback_type(kind, child), &block)
148
+ else
149
+ return child.run_callbacks(child_callback_type(kind, child)) do
150
+ _mongoid_run_child_callbacks(kind, children: tail, &block)
151
+ end
152
+ end
153
+ end
154
+
155
+ # This is used to store callbacks to be executed later. A good use case for
156
+ # this is delaying the after_find and after_initialize callbacks until the
157
+ # associations are set on the document. This can also be used to delay
158
+ # applying the defaults on a document.
159
+ #
160
+ # @return [ Array<Symbol> ] an array of symbols that represent the pending callbacks.
161
+ #
162
+ # @api private
163
+ def pending_callbacks
164
+ @pending_callbacks ||= [].to_set
165
+ end
166
+
167
+ # @api private
168
+ def pending_callbacks=(value)
169
+ @pending_callbacks = value
170
+ end
171
+
172
+ # Run the pending callbacks. If the callback is :apply_defaults, we will apply
173
+ # the defaults for this document. Otherwise, the callback is passed to the
174
+ # run_callbacks function.
175
+ #
176
+ # @api private
177
+ def run_pending_callbacks
178
+ pending_callbacks.each do |cb|
179
+ if [:apply_defaults, :apply_post_processed_defaults].include?(cb)
180
+ send(cb)
181
+ else
182
+ self.run_callbacks(cb, with_children: false)
183
+ end
184
+ end
185
+ pending_callbacks.clear
186
+ end
187
+
128
188
  private
129
189
 
130
190
  # We need to hook into this for autosave, since we don't want it firing if
@@ -102,13 +102,22 @@ module Mongoid
102
102
  def prepare_insert(options = {})
103
103
  return self if performing_validations?(options) &&
104
104
  invalid?(options[:context] || :create)
105
- result = run_callbacks(:save) do
106
- run_callbacks(:create) do
107
- yield(self)
108
- post_process_insert
105
+ run_callbacks(:save, with_children: false) do
106
+ run_callbacks(:create, with_children: false) do
107
+ run_callbacks(:persist_parent, with_children: false) do
108
+ _mongoid_run_child_callbacks(:save) do
109
+ _mongoid_run_child_callbacks(:create) do
110
+ result = yield(self)
111
+ if !result.is_a?(Document) || result.errors.empty?
112
+ post_process_insert
113
+ post_process_persist(result, options)
114
+ end
115
+ end
116
+ end
117
+ end
109
118
  end
110
119
  end
111
- post_process_persist(result, options) and self
120
+ self
112
121
  end
113
122
 
114
123
  module ClassMethods
@@ -96,13 +96,20 @@ module Mongoid
96
96
  return false if performing_validations?(options) &&
97
97
  invalid?(options[:context] || :update)
98
98
  process_flagged_destroys
99
- result = run_callbacks(:save) do
100
- run_callbacks(:update) do
101
- yield(self)
102
- true
99
+ run_callbacks(:save, with_children: false) do
100
+ run_callbacks(:update, with_children: false) do
101
+ run_callbacks(:persist_parent, with_children: false) do
102
+ _mongoid_run_child_callbacks(:save) do
103
+ _mongoid_run_child_callbacks(:update) do
104
+ result = yield(self)
105
+ self.previously_new_record = false
106
+ post_process_persist(result, options)
107
+ true
108
+ end
109
+ end
110
+ end
103
111
  end
104
112
  end
105
- post_process_persist(result, options) and result
106
113
  end
107
114
 
108
115
  # Update the document in the database.
@@ -18,7 +18,7 @@ module Mongoid
18
18
  # @return [ true ] True.
19
19
  def upsert(options = {})
20
20
  prepare_upsert(options) do
21
- collection.find(atomic_selector).update_one(
21
+ collection.find(atomic_selector).replace_one(
22
22
  as_attributes, upsert: true, session: _session)
23
23
  end
24
24
  end
@@ -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.
@@ -122,6 +124,21 @@ module Mongoid
122
124
  options == other.options
123
125
  end
124
126
 
127
+ # Whether the client of the context can be reused later, and therefore should
128
+ # not be closed.
129
+ #
130
+ # If the persistence context is requested with :client option only, it means
131
+ # that the context should use a client configured in mongoid.yml.
132
+ # Such clients should not be closed when the context is cleared since they
133
+ # will be reused later.
134
+ #
135
+ # @return [ true | false ] True if client can be reused, otherwise false.
136
+ #
137
+ # @api private
138
+ def reusable_client?
139
+ @options.keys == [:client]
140
+ end
141
+
125
142
  private
126
143
 
127
144
  def set_options!(opts)
@@ -211,7 +228,7 @@ module Mongoid
211
228
  def clear(object, cluster = nil, original_context = nil)
212
229
  if context = get(object)
213
230
  unless cluster.nil? || context.cluster.equal?(cluster)
214
- context.client.close
231
+ context.client.close unless context.reusable_client?
215
232
  end
216
233
  end
217
234
  ensure
@@ -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,7 @@ 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
+ Mongo::QueryCache.clear
42
18
  end
43
19
 
44
20
  # Set whether the cache is enabled.
@@ -48,11 +24,7 @@ module Mongoid
48
24
  #
49
25
  # @param [ true, false ] value The enabled value.
50
26
  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
27
+ Mongo::QueryCache.enabled = value
56
28
  end
57
29
 
58
30
  # Is the query cache enabled on the current thread?
@@ -62,11 +34,7 @@ module Mongoid
62
34
  #
63
35
  # @return [ true, false ] If the cache is enabled.
64
36
  def enabled?
65
- if defined?(Mongo::QueryCache)
66
- Mongo::QueryCache.enabled?
67
- else
68
- !!Thread.current["[mongoid]:query_cache:enabled"]
69
- end
37
+ Mongo::QueryCache.enabled?
70
38
  end
71
39
 
72
40
  # Execute the block while using the query cache.
@@ -76,21 +44,7 @@ module Mongoid
76
44
  #
77
45
  # @return [ Object ] The result of the block.
78
46
  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
47
+ Mongo::QueryCache.cache(&block)
94
48
  end
95
49
 
96
50
  # Execute the block with the query cache disabled.
@@ -100,217 +54,11 @@ module Mongoid
100
54
  #
101
55
  # @return [ Object ] The result of the block.
102
56
  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
194
- end
195
- end
196
-
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
57
+ Mongo::QueryCache.uncached(&block)
212
58
  end
213
59
  end
214
60
 
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
61
+ Middleware = Mongo::QueryCache::Middleware
309
62
  end
310
63
  end
311
64
 
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
@@ -23,11 +23,15 @@ module Mongoid
23
23
 
24
24
  reloaded = _reload
25
25
  if Mongoid.raise_not_found_error && (reloaded.nil? || reloaded.empty?)
26
- raise Errors::DocumentNotFound.new(self.class, _id, _id)
26
+ shard_keys = atomic_selector.with_indifferent_access.slice(*shard_key_fields, :_id)
27
+ raise Errors::DocumentNotFound.new(self.class, _id, shard_keys)
27
28
  end
28
29
  @attributes = reloaded
29
- @attributes_before_type_cast = {}
30
- changed_attributes.clear
30
+ @attributes_before_type_cast = @attributes.dup
31
+ @changed_attributes = {}
32
+ @previous_changes = {}
33
+ @previous_attributes = {}
34
+ @previously_new_record = false
31
35
  reset_readonly
32
36
  apply_defaults
33
37
  reload_relations
@@ -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