mongoid 7.6.2 → 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 (333) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +2 -0
  3. data/README.md +3 -3
  4. data/Rakefile +21 -85
  5. data/lib/config/locales/en.yml +46 -56
  6. data/lib/mongoid/association/accessors.rb +32 -3
  7. data/lib/mongoid/association/bindable.rb +48 -0
  8. data/lib/mongoid/association/builders.rb +4 -2
  9. data/lib/mongoid/association/depending.rb +4 -8
  10. data/lib/mongoid/association/eager_loadable.rb +29 -7
  11. data/lib/mongoid/association/embedded/batchable.rb +28 -5
  12. data/lib/mongoid/association/embedded/embedded_in/binding.rb +24 -2
  13. data/lib/mongoid/association/embedded/embedded_in.rb +2 -1
  14. data/lib/mongoid/association/embedded/embeds_many/binding.rb +1 -0
  15. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +1 -1
  16. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +40 -18
  17. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +18 -4
  18. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +21 -2
  19. data/lib/mongoid/association/macros.rb +2 -1
  20. data/lib/mongoid/association/many.rb +5 -0
  21. data/lib/mongoid/association/nested/many.rb +5 -39
  22. data/lib/mongoid/association/nested/nested_buildable.rb +0 -14
  23. data/lib/mongoid/association/proxy.rb +12 -0
  24. data/lib/mongoid/association/referenced/auto_save.rb +3 -2
  25. data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
  26. data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
  27. data/lib/mongoid/association/referenced/belongs_to.rb +1 -1
  28. data/lib/mongoid/association/referenced/counter_cache.rb +8 -8
  29. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +64 -11
  30. data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +4 -1
  31. data/lib/mongoid/association/referenced/has_many/enumerable.rb +10 -18
  32. data/lib/mongoid/association/referenced/has_many/proxy.rb +11 -107
  33. data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -1
  34. data/lib/mongoid/association/referenced/has_one/proxy.rb +8 -11
  35. data/lib/mongoid/association/referenced/syncable.rb +2 -2
  36. data/lib/mongoid/association/relatable.rb +38 -4
  37. data/lib/mongoid/attributes/processing.rb +9 -2
  38. data/lib/mongoid/attributes.rb +30 -27
  39. data/lib/mongoid/cacheable.rb +2 -2
  40. data/lib/mongoid/changeable.rb +37 -2
  41. data/lib/mongoid/clients/factory.rb +0 -4
  42. data/lib/mongoid/clients/options.rb +4 -0
  43. data/lib/mongoid/clients/sessions.rb +2 -14
  44. data/lib/mongoid/config.rb +15 -73
  45. data/lib/mongoid/contextual/aggregable/memory.rb +22 -20
  46. data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
  47. data/lib/mongoid/contextual/map_reduce.rb +2 -2
  48. data/lib/mongoid/contextual/memory.rb +63 -47
  49. data/lib/mongoid/contextual/mongo.rb +173 -287
  50. data/lib/mongoid/contextual/none.rb +33 -15
  51. data/lib/mongoid/copyable.rb +32 -8
  52. data/lib/mongoid/criteria/includable.rb +24 -20
  53. data/lib/mongoid/criteria/marshalable.rb +10 -2
  54. data/lib/mongoid/criteria/queryable/extensions/array.rb +2 -15
  55. data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -4
  56. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
  57. data/lib/mongoid/criteria/queryable/extensions/date.rb +6 -1
  58. data/lib/mongoid/criteria/queryable/extensions/date_time.rb +6 -1
  59. data/lib/mongoid/criteria/queryable/extensions/hash.rb +0 -16
  60. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -1
  61. data/lib/mongoid/criteria/queryable/extensions/object.rb +2 -1
  62. data/lib/mongoid/criteria/queryable/extensions/range.rb +13 -5
  63. data/lib/mongoid/criteria/queryable/extensions/regexp.rb +1 -1
  64. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +3 -1
  65. data/lib/mongoid/criteria/queryable/extensions/time.rb +6 -1
  66. data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +6 -1
  67. data/lib/mongoid/criteria/queryable/mergeable.rb +0 -12
  68. data/lib/mongoid/criteria/queryable/optional.rb +3 -9
  69. data/lib/mongoid/criteria/queryable/options.rb +1 -1
  70. data/lib/mongoid/criteria/queryable/selectable.rb +2 -133
  71. data/lib/mongoid/criteria/queryable/selector.rb +90 -5
  72. data/lib/mongoid/criteria/queryable/smash.rb +39 -6
  73. data/lib/mongoid/criteria/queryable/storable.rb +1 -1
  74. data/lib/mongoid/criteria/queryable.rb +11 -6
  75. data/lib/mongoid/criteria.rb +1 -28
  76. data/lib/mongoid/deprecable.rb +36 -0
  77. data/lib/mongoid/deprecation.rb +25 -0
  78. data/lib/mongoid/document.rb +88 -33
  79. data/lib/mongoid/equality.rb +4 -4
  80. data/lib/mongoid/errors/document_not_found.rb +6 -2
  81. data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
  82. data/lib/mongoid/errors/invalid_field.rb +5 -1
  83. data/lib/mongoid/errors/invalid_field_type.rb +26 -0
  84. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
  85. data/lib/mongoid/errors.rb +2 -3
  86. data/lib/mongoid/extensions/array.rb +8 -6
  87. data/lib/mongoid/extensions/big_decimal.rb +29 -10
  88. data/lib/mongoid/extensions/binary.rb +42 -0
  89. data/lib/mongoid/extensions/boolean.rb +8 -2
  90. data/lib/mongoid/extensions/date.rb +26 -20
  91. data/lib/mongoid/extensions/date_time.rb +1 -1
  92. data/lib/mongoid/extensions/float.rb +4 -5
  93. data/lib/mongoid/extensions/hash.rb +13 -32
  94. data/lib/mongoid/extensions/integer.rb +4 -5
  95. data/lib/mongoid/extensions/object.rb +2 -0
  96. data/lib/mongoid/extensions/range.rb +41 -10
  97. data/lib/mongoid/extensions/regexp.rb +11 -4
  98. data/lib/mongoid/extensions/set.rb +11 -4
  99. data/lib/mongoid/extensions/string.rb +2 -13
  100. data/lib/mongoid/extensions/symbol.rb +3 -14
  101. data/lib/mongoid/extensions/time.rb +27 -16
  102. data/lib/mongoid/extensions/time_with_zone.rb +1 -2
  103. data/lib/mongoid/extensions.rb +1 -0
  104. data/lib/mongoid/factory.rb +42 -7
  105. data/lib/mongoid/fields/foreign_key.rb +7 -0
  106. data/lib/mongoid/fields/validators/macro.rb +3 -9
  107. data/lib/mongoid/fields.rb +49 -7
  108. data/lib/mongoid/findable.rb +21 -16
  109. data/lib/mongoid/indexable/specification.rb +1 -1
  110. data/lib/mongoid/indexable/validators/options.rb +4 -1
  111. data/lib/mongoid/interceptable.rb +69 -9
  112. data/lib/mongoid/matchable.rb +1 -6
  113. data/lib/mongoid/matcher/eq_impl_with_regexp.rb +5 -3
  114. data/lib/mongoid/matcher/regex.rb +9 -8
  115. data/lib/mongoid/matcher.rb +0 -1
  116. data/lib/mongoid/persistable/creatable.rb +14 -5
  117. data/lib/mongoid/persistable/updatable.rb +12 -5
  118. data/lib/mongoid/persistence_context.rb +8 -42
  119. data/lib/mongoid/query_cache.rb +6 -258
  120. data/lib/mongoid/railties/controller_runtime.rb +1 -1
  121. data/lib/mongoid/reloadable.rb +7 -3
  122. data/lib/mongoid/scopable.rb +9 -11
  123. data/lib/mongoid/selectable.rb +1 -2
  124. data/lib/mongoid/shardable.rb +11 -35
  125. data/lib/mongoid/stateful.rb +27 -1
  126. data/lib/mongoid/threaded.rb +0 -3
  127. data/lib/mongoid/timestamps/created.rb +1 -1
  128. data/lib/mongoid/timestamps/updated.rb +1 -1
  129. data/lib/mongoid/touchable.rb +2 -3
  130. data/lib/mongoid/traversable.rb +1 -0
  131. data/lib/mongoid/validatable/uniqueness.rb +2 -1
  132. data/lib/mongoid/version.rb +1 -5
  133. data/lib/mongoid/warnings.rb +3 -5
  134. data/lib/mongoid.rb +1 -0
  135. data/spec/config/mongoid.yml +16 -0
  136. data/spec/integration/app_spec.rb +8 -20
  137. data/spec/integration/associations/belongs_to_spec.rb +18 -0
  138. data/spec/integration/associations/embedded_spec.rb +15 -0
  139. data/spec/integration/associations/embeds_many_spec.rb +15 -2
  140. data/spec/integration/associations/embeds_one_spec.rb +18 -0
  141. data/spec/integration/associations/foreign_key_spec.rb +9 -0
  142. data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
  143. data/spec/integration/associations/has_one_spec.rb +97 -1
  144. data/spec/integration/associations/scope_option_spec.rb +1 -1
  145. data/spec/integration/callbacks_models.rb +95 -1
  146. data/spec/integration/callbacks_spec.rb +226 -4
  147. data/spec/integration/criteria/range_spec.rb +95 -1
  148. data/spec/integration/discriminator_key_spec.rb +115 -76
  149. data/spec/integration/dots_and_dollars_spec.rb +277 -0
  150. data/spec/integration/i18n_fallbacks_spec.rb +1 -15
  151. data/spec/integration/matcher_examples_spec.rb +20 -13
  152. data/spec/integration/matcher_operator_data/regex.yml +0 -21
  153. data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
  154. data/spec/integration/matcher_operator_spec.rb +3 -5
  155. data/spec/integration/persistence/range_field_spec.rb +350 -0
  156. data/spec/mongoid/association/counter_cache_spec.rb +1 -1
  157. data/spec/mongoid/association/depending_spec.rb +9 -9
  158. data/spec/mongoid/association/eager_spec.rb +2 -1
  159. data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
  160. data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
  161. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +69 -9
  162. data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
  163. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +198 -8
  164. data/spec/mongoid/association/embedded/embeds_many_models.rb +36 -0
  165. data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +12 -0
  166. data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
  167. data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
  168. data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
  169. data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
  170. data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
  171. data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
  172. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +15 -0
  173. data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
  174. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -2
  175. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +36 -51
  176. data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
  177. data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
  178. data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
  179. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +2 -56
  180. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +60 -156
  181. data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
  182. data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
  183. data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
  184. data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
  185. data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
  186. data/spec/mongoid/association/syncable_spec.rb +14 -0
  187. data/spec/mongoid/atomic/paths_spec.rb +0 -14
  188. data/spec/mongoid/attributes/nested_spec.rb +73 -198
  189. data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
  190. data/spec/mongoid/attributes/projector_spec.rb +1 -5
  191. data/spec/mongoid/attributes_spec.rb +480 -27
  192. data/spec/mongoid/cacheable_spec.rb +3 -3
  193. data/spec/mongoid/changeable_spec.rb +130 -13
  194. data/spec/mongoid/clients/factory_spec.rb +22 -60
  195. data/spec/mongoid/clients/sessions_spec.rb +0 -38
  196. data/spec/mongoid/clients_spec.rb +2 -2
  197. data/spec/mongoid/config_spec.rb +52 -15
  198. data/spec/mongoid/contextual/aggregable/memory_spec.rb +371 -231
  199. data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
  200. data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
  201. data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
  202. data/spec/mongoid/contextual/memory_spec.rb +467 -156
  203. data/spec/mongoid/contextual/mongo_spec.rb +566 -426
  204. data/spec/mongoid/contextual/none_spec.rb +11 -19
  205. data/spec/mongoid/copyable_spec.rb +451 -2
  206. data/spec/mongoid/criteria/findable_spec.rb +86 -210
  207. data/spec/mongoid/criteria/includable_spec.rb +1492 -0
  208. data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
  209. data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
  210. data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
  211. data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
  212. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +1 -2
  213. data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
  214. data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
  215. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +1 -2
  216. data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
  217. data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
  218. data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
  219. data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
  220. data/spec/mongoid/criteria/queryable/optional_spec.rb +0 -484
  221. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +50 -2
  222. data/spec/mongoid/criteria/queryable/selectable_spec.rb +77 -85
  223. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +0 -200
  224. data/spec/mongoid/criteria/queryable/selector_spec.rb +16 -77
  225. data/spec/mongoid/criteria/queryable/storable_spec.rb +0 -72
  226. data/spec/mongoid/criteria_spec.rb +469 -1203
  227. data/spec/mongoid/document_fields_spec.rb +173 -24
  228. data/spec/mongoid/document_spec.rb +32 -41
  229. data/spec/mongoid/equality_spec.rb +12 -12
  230. data/spec/mongoid/errors/document_not_found_spec.rb +29 -2
  231. data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
  232. data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
  233. data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
  234. data/spec/mongoid/errors/no_environment_spec.rb +3 -3
  235. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
  236. data/spec/mongoid/extensions/array_spec.rb +16 -2
  237. data/spec/mongoid/extensions/big_decimal_spec.rb +697 -212
  238. data/spec/mongoid/extensions/binary_spec.rb +44 -9
  239. data/spec/mongoid/extensions/boolean_spec.rb +68 -82
  240. data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
  241. data/spec/mongoid/extensions/date_spec.rb +71 -1
  242. data/spec/mongoid/extensions/date_time_spec.rb +15 -9
  243. data/spec/mongoid/extensions/float_spec.rb +48 -76
  244. data/spec/mongoid/extensions/hash_spec.rb +30 -236
  245. data/spec/mongoid/extensions/integer_spec.rb +45 -66
  246. data/spec/mongoid/extensions/range_spec.rb +255 -54
  247. data/spec/mongoid/extensions/regexp_spec.rb +58 -33
  248. data/spec/mongoid/extensions/set_spec.rb +106 -0
  249. data/spec/mongoid/extensions/string_spec.rb +53 -25
  250. data/spec/mongoid/extensions/symbol_spec.rb +18 -25
  251. data/spec/mongoid/extensions/time_spec.rb +634 -66
  252. data/spec/mongoid/extensions/time_with_zone_spec.rb +17 -31
  253. data/spec/mongoid/factory_spec.rb +61 -1
  254. data/spec/mongoid/fields_spec.rb +321 -50
  255. data/spec/mongoid/findable_spec.rb +64 -29
  256. data/spec/mongoid/indexable/specification_spec.rb +2 -2
  257. data/spec/mongoid/indexable_spec.rb +16 -19
  258. data/spec/mongoid/interceptable_spec.rb +584 -5
  259. data/spec/mongoid/interceptable_spec_models.rb +235 -4
  260. data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
  261. data/spec/mongoid/mongoizable_spec.rb +285 -0
  262. data/spec/mongoid/persistable/creatable_spec.rb +2 -2
  263. data/spec/mongoid/persistable/deletable_spec.rb +2 -2
  264. data/spec/mongoid/persistable/destroyable_spec.rb +2 -2
  265. data/spec/mongoid/persistable/upsertable_spec.rb +14 -0
  266. data/spec/mongoid/persistence_context_spec.rb +24 -0
  267. data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
  268. data/spec/mongoid/query_cache_spec.rb +1 -156
  269. data/spec/mongoid/reloadable_spec.rb +35 -2
  270. data/spec/mongoid/scopable_spec.rb +36 -34
  271. data/spec/mongoid/serializable_spec.rb +14 -7
  272. data/spec/mongoid/shardable_models.rb +0 -14
  273. data/spec/mongoid/shardable_spec.rb +61 -153
  274. data/spec/mongoid/stateful_spec.rb +28 -0
  275. data/spec/mongoid/timestamps_spec.rb +390 -0
  276. data/spec/mongoid/timestamps_spec_models.rb +67 -0
  277. data/spec/mongoid/touchable_spec.rb +116 -0
  278. data/spec/mongoid/touchable_spec_models.rb +12 -8
  279. data/spec/mongoid/traversable_spec.rb +4 -11
  280. data/spec/mongoid/validatable/presence_spec.rb +1 -1
  281. data/spec/mongoid/validatable/uniqueness_spec.rb +60 -31
  282. data/spec/mongoid/warnings_spec.rb +35 -0
  283. data/spec/mongoid_spec.rb +1 -7
  284. data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
  285. data/spec/rails/mongoid_spec.rb +4 -16
  286. data/spec/shared/lib/mrss/cluster_config.rb +40 -5
  287. data/spec/shared/lib/mrss/constraints.rb +46 -7
  288. data/spec/shared/lib/mrss/docker_runner.rb +21 -17
  289. data/spec/shared/lib/mrss/eg_config_utils.rb +31 -0
  290. data/spec/shared/lib/mrss/event_subscriber.rb +5 -15
  291. data/spec/shared/lib/mrss/lite_constraints.rb +2 -10
  292. data/spec/shared/lib/mrss/server_version_registry.rb +29 -18
  293. data/spec/shared/lib/mrss/spec_organizer.rb +3 -32
  294. data/spec/shared/lib/mrss/utils.rb +6 -28
  295. data/spec/shared/share/Dockerfile.erb +114 -38
  296. data/spec/shared/shlib/distro.sh +0 -10
  297. data/spec/shared/shlib/server.sh +83 -64
  298. data/spec/shared/shlib/set_env.sh +81 -16
  299. data/spec/support/constraints.rb +24 -0
  300. data/spec/support/expectations.rb +17 -20
  301. data/spec/support/macros.rb +30 -0
  302. data/spec/support/models/augmentation.rb +12 -0
  303. data/spec/support/models/band.rb +3 -0
  304. data/spec/support/models/catalog.rb +24 -0
  305. data/spec/support/models/circus.rb +3 -0
  306. data/spec/support/models/fanatic.rb +8 -0
  307. data/spec/support/models/implant.rb +9 -0
  308. data/spec/support/models/label.rb +2 -0
  309. data/spec/support/models/passport.rb +9 -0
  310. data/spec/support/models/person.rb +1 -0
  311. data/spec/support/models/player.rb +2 -0
  312. data/spec/support/models/powerup.rb +12 -0
  313. data/spec/support/models/registry.rb +1 -0
  314. data/spec/support/models/school.rb +14 -0
  315. data/spec/support/models/shield.rb +18 -0
  316. data/spec/support/models/student.rb +14 -0
  317. data/spec/support/models/weapon.rb +12 -0
  318. data.tar.gz.sig +0 -0
  319. metadata +695 -650
  320. metadata.gz.sig +0 -0
  321. data/lib/mongoid/errors/eager_load.rb +0 -23
  322. data/lib/mongoid/errors/in_memory_regexp_timeout.rb +0 -26
  323. data/lib/mongoid/errors/invalid_value.rb +0 -17
  324. data/lib/mongoid/field_readable.rb +0 -70
  325. data/lib/mongoid/matcher/regexp_budget.rb +0 -389
  326. data/spec/integration/matcher_regexp_timeout_spec.rb +0 -215
  327. data/spec/integration/query_operator_guard_spec.rb +0 -89
  328. data/spec/mongoid/errors/eager_load_spec.rb +0 -31
  329. data/spec/mongoid/matcher/regexp_budget_spec.rb +0 -570
  330. data/spec/shared/CANDIDATE.md +0 -28
  331. data/spec/shared/lib/mrss/release/candidate.rb +0 -287
  332. data/spec/shared/lib/mrss/release/product_data.rb +0 -144
  333. data/spec/shared/lib/tasks/candidate.rake +0 -64
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 34b19075685074c30826364928a28ddf7ac83dd34ce316b4519a1d211a003c3e
4
- data.tar.gz: b58093fe7252f378f286f4e1051ad286e1795ebedceb6d4458b89a1f02a384c7
3
+ metadata.gz: f4aba01720c23aaef7cb2c1ca3045e351a3499bb80758f4ddbdf2cc15baa9cd4
4
+ data.tar.gz: '082d09a7a072d85b8a19f884efc7805107732a32f0e90fe953785eabfae25bb7'
5
5
  SHA512:
6
- metadata.gz: 587e4d3e9116f64de81e3ef8ea8db1a1971b85745ed0c8c4884b738a2357dfb8669a05f35d5ba662f433e41644ccab38912de3ef2f0bfc6fb2f886ee26834e78
7
- data.tar.gz: 48433d3580da9f35b4ea0d043a169d1015ef59a993c34619a990b79acfaf2dcdd55d880f8067e714675d0c552554fbb60c5c72d029f77ce608c92524304a5b15
6
+ metadata.gz: 35fedeedf4ad08f7f250600101eab0af7460e2b1c727448d0e880e418b195a18c33c8b672f2472e8291d2984d13e0781f271d8b034fab0753a80a7a76e62e6fd
7
+ data.tar.gz: f5da886e2b77b820c4d8928edc3c9f19d090712e17fd2efc484af0e13cd1e659dbf6f19270e4c53462779536e8b924b9cc65da3aeeed65cd98a1a5fbcb1e1649
checksums.yaml.gz.sig ADDED
@@ -0,0 +1,2 @@
1
+ ��q��'g�����x�o�Z�Ɏ�5�m���X|���#
2
+ �����7�X�!��I�eo��"�.\
data/README.md CHANGED
@@ -19,9 +19,9 @@ Compatibility
19
19
 
20
20
  Mongoid supports and is tested against:
21
21
 
22
- - MRI 2.7 - 3.1
22
+ - MRI 2.6 - 3.1
23
23
  - JRuby 9.3
24
- - MongoDB server 3.6 - 8.0
24
+ - MongoDB server 3.6 - 6.0
25
25
 
26
26
  Issues
27
27
  ------
@@ -40,7 +40,7 @@ License
40
40
  -------
41
41
 
42
42
  Copyright (c) 2009-2016 Durran Jordan
43
- Copyright (c) 2015-present MongoDB, Inc.
43
+ Copyright (c) 2015-2020 MongoDB, Inc.
44
44
 
45
45
  Permission is hereby granted, free of charge, to any person obtaining
46
46
  a copy of this software and associated documentation files (the
data/Rakefile CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
- # rubocop:todo all
3
2
 
4
3
  require "bundler"
4
+ require "bundler/gem_tasks"
5
5
  Bundler.setup
6
6
 
7
7
  ROOT = File.expand_path(File.join(File.dirname(__FILE__)))
@@ -10,53 +10,25 @@ $: << File.join(ROOT, 'spec/shared/lib')
10
10
 
11
11
  require "rake"
12
12
  require "rspec/core/rake_task"
13
+ require 'mrss/spec_organizer'
13
14
 
14
- if File.exist?('./spec/shared/lib/tasks/candidate.rake')
15
- load 'spec/shared/lib/tasks/candidate.rake'
16
- end
15
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
16
+ require "mongoid/version"
17
+
18
+ tasks = Rake.application.instance_variable_get('@tasks')
19
+ tasks['release:do'] = tasks.delete('release')
17
20
 
18
- desc 'Build the gem'
21
+ task :gem => :build
19
22
  task :build do
20
- command = %w[ gem build ]
21
- command << "--output=#{ENV['GEM_FILE_NAME']}" if ENV['GEM_FILE_NAME']
22
- command << (ENV['GEMSPEC'] || 'mongoid.gemspec')
23
- system(*command)
23
+ system "gem build mongoid.gemspec"
24
24
  end
25
25
 
26
- # `rake version` is used by the deployment system so get the release version
27
- # of the product beng deployed. It must do nothing more than just print the
28
- # product version number.
29
- #
30
- # See the mongodb-labs/driver-github-tools/ruby/publish Github action.
31
- desc "Print the current value of Mongoid::VERSION"
32
- task :version do
33
- require 'mongoid/version'
34
-
35
- puts Mongoid::VERSION
26
+ task :install => :build do
27
+ system "sudo gem install mongoid-#{Mongoid::VERSION}.gem"
36
28
  end
37
29
 
38
- # overrides the default Bundler-provided `release` task, which also
39
- # builds the gem. Our release process assumes the gem has already
40
- # been built (and signed via GPG), so we just need `rake release` to
41
- # push the gem to rubygems.
42
30
  task :release do
43
- require 'mongoid/version'
44
-
45
- if ENV['GITHUB_ACTION'].nil?
46
- abort <<~WARNING
47
- `rake release` must be invoked from the `Mongoid Release` GitHub action,
48
- and must not be invoked locally. This ensures the gem is properly signed
49
- and distributed by the appropriate user.
50
-
51
- Note that it is the `rubygems/release-gem@v1` step in the `Mongoid Release`
52
- action that invokes this task. Do not rename or remove this task, or the
53
- release-gem step will fail. Reimplement this task with caution.
54
-
55
- mongoid-#{Mongoid::VERSION}.gem was NOT pushed to RubyGems.
56
- WARNING
57
- end
58
-
59
- system 'gem', 'push', "mongoid-#{Mongoid::VERSION}.gem"
31
+ raise "Please use ./release.sh to release"
60
32
  end
61
33
 
62
34
  RSpec::Core::RakeTask.new("spec") do |spec|
@@ -68,46 +40,6 @@ RSpec::Core::RakeTask.new('spec:progress') do |spec|
68
40
  spec.pattern = "spec/**/*_spec.rb"
69
41
  end
70
42
 
71
- desc 'Build and validate the evergreen config'
72
- task eg: %w[ eg:build eg:validate ]
73
-
74
- # 'eg' == 'evergreen', but evergreen is too many letters for convenience
75
- namespace :eg do
76
- desc 'Builds the .evergreen/config.yml file from the templates'
77
- task :build do
78
- ruby '.evergreen/update-evergreen-configs'
79
- end
80
-
81
- desc 'Validates the .evergreen/config.yml file'
82
- task :validate do
83
- system 'evergreen validate --project mongoid .evergreen/config.yml'
84
- end
85
-
86
- desc 'Updates the evergreen executable to the latest available version'
87
- task :update do
88
- system 'evergreen get-update --install'
89
- end
90
-
91
- desc 'Runs the current branch as an evergreen patch'
92
- task :patch do
93
- system 'evergreen patch --uncommitted --project mongoid --browse --auto-description --yes'
94
- end
95
- end
96
-
97
- namespace :generate do
98
- desc 'Generates a mongoid.yml from the template'
99
- task :config do
100
- require 'mongoid'
101
- require 'erb'
102
-
103
- template_path = 'lib/rails/generators/mongoid/config/templates/mongoid.yml'
104
- database_name = ENV['DATABASE_NAME'] || 'my_db'
105
-
106
- config = ERB.new(File.read(template_path), trim_mode: '-').result(binding)
107
- File.write('mongoid.yml', config)
108
- end
109
- end
110
-
111
43
  CLASSIFIERS = [
112
44
  [%r,^mongoid/attribute,, :attributes],
113
45
  [%r,^mongoid/association/[or],, :associations_referenced],
@@ -123,8 +55,6 @@ RUN_PRIORITY = %i(
123
55
  )
124
56
 
125
57
  def spec_organizer
126
- require 'mrss/spec_organizer'
127
-
128
58
  Mrss::SpecOrganizer.new(
129
59
  root: ROOT,
130
60
  classifiers: CLASSIFIERS,
@@ -158,12 +88,18 @@ desc "Generate all documentation"
158
88
  task :docs => 'docs:yard'
159
89
 
160
90
  namespace :docs do
161
- desc "Generate yard documentation"
91
+ desc "Generate yard documention"
162
92
  task :yard do
163
- require "mongoid/version"
164
-
165
93
  out = File.join('yard-docs', Mongoid::VERSION)
166
94
  FileUtils.rm_rf(out)
167
95
  system "yardoc -o #{out} --title mongoid-#{Mongoid::VERSION}"
168
96
  end
169
97
  end
98
+
99
+ namespace :release do
100
+ task :check_private_key do
101
+ unless File.exist?('gem-private_key.pem')
102
+ raise "No private key present, cannot release"
103
+ end
104
+ end
105
+ end
@@ -1,4 +1,8 @@
1
1
  en:
2
+ errors:
3
+ messages:
4
+ taken: "has already been taken"
5
+
2
6
  mongoid:
3
7
  errors:
4
8
  messages:
@@ -61,7 +65,7 @@ en:
61
65
  and the following ids were not found: %{missing}."
62
66
  resolution: "Search for an id that is in the database or set
63
67
  the Mongoid.raise_not_found_error configuration option to false,
64
- which will cause a nil to be returned instead of raising this error when
68
+ which will cause nil to be returned instead of raising this error when
65
69
  searching for a single id, or only the matched documents when searching
66
70
  for multiples."
67
71
  document_with_attributes_not_found:
@@ -71,15 +75,17 @@ en:
71
75
  will be raised."
72
76
  resolution: "Search for attributes that are in the database or set
73
77
  the Mongoid.raise_not_found_error configuration option to false,
74
- which will cause a nil to be returned instead of raising this error."
75
- eager_load:
76
- message: "Eager loading :%{name} is not supported since it is a
77
- polymorphic belongs_to association."
78
- summary: "Mongoid cannot currently determine the classes it needs to
79
- eager load when the association is polymorphic. The parents reside in
80
- different collections so a simple id lookup is not sufficient enough."
81
- resolution: "Don't attempt to perform this action and have patience,
82
- maybe this will be supported in the future."
78
+ which will cause nil to be returned instead of raising this error."
79
+ document_with_shard_key_not_found:
80
+ message: "Document not found for class %{klass} with id %{missing} and
81
+ shard key %{shard_key}."
82
+ summary: "When calling %{klass}.find with an id and a shard key, each
83
+ parameter must match a document in the database or this error will
84
+ be raised. The search was for the id: %{missing} with
85
+ shard_key: %{shard_key} and it was not found."
86
+ resolution: "Search for an id/shard key that is in the database or set
87
+ the Mongoid.raise_not_found_error configuration option to false,
88
+ which will cause nil to be returned instead of raising this error."
83
89
  empty_config_file:
84
90
  message: "Empty configuration file: %{path}."
85
91
  summary: "Your mongoid.yml configuration file appears to be empty."
@@ -99,32 +105,6 @@ en:
99
105
  A collation option is only supported if the query is executed on a MongoDB server
100
106
  with version >= 3.4."
101
107
  resolution: "Remove the collation option from the query."
102
- in_memory_regexp_timeout:
103
- message: "Evaluating this query in memory exceeded the %{limit} second
104
- limit that applies to conditions containing a regular expression."
105
- summary: "Mongoid evaluates some conditions in the calling thread
106
- rather than sending them to the server: queries against an embedded
107
- association, removing documents from an association by condition,
108
- and Document#_matches?. A regular expression in such a condition
109
- runs locally. Mongoid limits the total time one in-memory
110
- evaluation may spend matching, because both the cost of a single
111
- match and the number of matches performed grow with the condition,
112
- and a pattern built from end-user input can be made to consume an
113
- unbounded amount of CPU. The limit is cumulative over the whole
114
- evaluation rather than per match. Where the Ruby in use offers no
115
- per-Regexp timeout the limit is enforced as wall clock over the
116
- whole in-memory evaluation, so there it can be exceeded by a large
117
- scan even when the pattern itself is cheap."
118
- resolution: "Check whether the pattern in this query comes from user
119
- input; if it does, validate it before querying. If the query is
120
- legitimate and simply large, raise
121
- Mongoid::Config.in_memory_regexp_time_limit, or set it to nil to
122
- remove the limit entirely. The limit in force is the smaller of
123
- that setting and any global Regexp.timeout the application has set,
124
- so check both. On JRuby, and on MRI before 3.2, there is no
125
- per-Regexp timeout, so what the limit bounds there is the elapsed
126
- time of the whole in-memory evaluation rather than the time spent
127
- matching."
128
108
  invalid_config_file:
129
109
  message: "Invalid configuration file: %{path}."
130
110
  summary: "Your mongoid.yml configuration file does not contain the
@@ -152,6 +132,17 @@ en:
152
132
  allowed."
153
133
  resolution: "Try setting the discriminator key on %{superclass} or one of %{class_name}'s
154
134
  ancestors."
135
+ invalid_dot_dollar_assignment:
136
+ message: "Cannot set the %{attr} attribute on the %{klass} class."
137
+ summary: "Calling the setters for fields that start with a dollar
138
+ sign ($) or contain a dot/period (.) is prohibited. See the
139
+ Mongoid documentation on Field Names with Dots/Periods (.) and
140
+ Dollar Signs ($) for more information."
141
+ resolution: "In order to set fields that start with a dollar
142
+ sign ($) or contain a dot/period (.), the aggregation pipeline can
143
+ be used. MongoDB provides specific operators for working with these
144
+ fields. Refer to the MongoDB documentation here:
145
+ https://www.mongodb.com/docs/manual/core/dot-dollar-considerations/"
155
146
  invalid_elem_match_operator:
156
147
  message: "Invalid $elemMatch operator '%{operator}'."
157
148
  summary: "You misspelled an operator or are using an operator that
@@ -172,7 +163,7 @@ en:
172
163
  resolution: "Valid expression operators are: %{valid_operators}.
173
164
  Ensure you are using one of these operators."
174
165
  invalid_field:
175
- message: "Defining a field named '%{name}' is not allowed."
166
+ message: "Defining a field named '%{field}' is not allowed."
176
167
  summary: "Defining this field would override the method '%{name}',
177
168
  which would cause issues with expectations around the original
178
169
  method and cause extremely hard to debug issues. The original
@@ -207,6 +198,13 @@ en:
207
198
  \_\_end\n\n
208
199
  Refer to:
209
200
  https://docs.mongodb.com/mongoid/current/reference/fields/#custom-field-options"
201
+ invalid_field_type:
202
+ message: "Invalid field type %{type_inspection} for field '%{field}' on model '%{klass}'."
203
+ summary: "Model '%{klass}' defines a field '%{field}' with an unknown type value
204
+ %{type_inspection}."
205
+ resolution: "Please provide a valid type value for the field.
206
+ Refer to:
207
+ https://docs.mongodb.com/mongoid/current/reference/fields/#using-symbols-or-strings-instead-of-classes"
210
208
  invalid_includes:
211
209
  message: "Invalid includes directive: %{klass}.includes(%{args})"
212
210
  summary: "Eager loading in Mongoid only supports providing arguments
@@ -222,7 +220,6 @@ en:
222
220
  Valid options are:\n
223
221
  \_\_background: true|false\n
224
222
  \_\_database: 'database_name'\n
225
- \_\_drop_dups: true|false\n
226
223
  \_\_name: 'index_name'\n
227
224
  \_\_sparse: true|false\n
228
225
  \_\_unique: true|false\n
@@ -241,7 +238,7 @@ en:
241
238
  \_\_language_override\n
242
239
  \_\_default_language\n
243
240
  \_\_collation\n
244
- Valid types are: 1, -1, '2d', '2dsphere', 'geoHaystack', 'text', 'hashed'\n\n
241
+ Valid types are: 1, -1, '2d', '2dsphere', 'geoHaystack (deprecated)', 'text', 'hashed'\n\n
245
242
  Example:\n
246
243
  \_\_class Band\n
247
244
  \_\_\_\_include Mongoid::Document\n
@@ -375,10 +372,6 @@ en:
375
372
  from the child side which association to go in."
376
373
  resolution: "Set the values from the parent, or redefine the association
377
374
  with only a single definition in the parent."
378
- invalid_value:
379
- message: "Value of type %{value_class} cannot be written to a field of type %{field_class}"
380
- summary: "Tried to set a value of type %{value_class} to a field of type %{field_class}"
381
- resolution: "Verify if the value to be set correspond to field definition"
382
375
  mixed_relations:
383
376
  message: "Referencing a(n) %{embedded} document from the %{root}
384
377
  document via a non-embedded association is not allowed since the
@@ -435,19 +428,18 @@ en:
435
428
  summary: "Mongoid attempted to find a document of the class %{klass}
436
429
  but none exist."
437
430
  resolution: "Create a document of class %{klass} or use a finder
438
- method that returns nil when no documents are found instead of
439
- raising an exception."
431
+ method that does not raise an exception when no documents are
432
+ found."
440
433
  no_environment:
441
434
  message: "Could not load the configuration since no environment
442
435
  was defined."
443
- summary: "Mongoid attempted to find the appropriate environment
444
- but no Rails.env, Sinatra::Base.environment, RACK_ENV, or
445
- MONGOID_ENV could be found."
446
- resolution: "Make sure some environment is set from the mentioned
447
- options. Mongoid cannot load configuration from the yaml without
448
- knowing which environment it is in, and we have considered
449
- defaulting to development an undesirable side effect of this not
450
- being defined."
436
+ summary: "Mongoid could not determine the environment to use because
437
+ it was not specified in any of the following locations:
438
+ Rails.env, Sinatra::Base.environment,
439
+ ENV[\"RACK_ENV\"], ENV[\"MONGOID_ENV\"]. Without knowing the
440
+ environment, Mongoid cannot load its configuration."
441
+ resolution: "Please ensure an environment is set in one of the
442
+ listed locations. The environment must be explicitly set."
451
443
  no_map_reduce_output:
452
444
  message: "No output location was specified for the map/reduce
453
445
  operation."
@@ -574,11 +566,9 @@ en:
574
566
  server versions 3.6 and higher."
575
567
  resolution: "Verify that all servers in your deployment are at least
576
568
  version 3.6 or don't attempt to use sessions with older server versions."
577
- taken:
578
- "is already taken"
579
569
  too_many_nested_attribute_records:
580
570
  message: "Accepting nested attributes for %{association} is limited
581
- to %{limit} records."
571
+ to %{limit} documents."
582
572
  summary: "More documents were sent to be processed than the allowed
583
573
  limit."
584
574
  resolution: "The limit is set as an option to the macro, for example:
@@ -42,8 +42,23 @@ module Mongoid
42
42
  # @return [ Proxy ] The association.
43
43
  def create_relation(object, association, selected_fields = nil)
44
44
  type = @attributes[association.inverse_type]
45
- target = association.build(self, object, type, selected_fields)
46
- target ? association.create_relation(self, target) : nil
45
+ target = if t = association.build(self, object, type, selected_fields)
46
+ association.create_relation(self, t)
47
+ else
48
+ nil
49
+ end
50
+
51
+ # Only need to do this on embedded associations. The pending callbacks
52
+ # are only added when materializing the documents, which only happens
53
+ # on embedded associations. There is no call to the database in the
54
+ # construction of a referenced association.
55
+ if association.embedded?
56
+ Array(target).each do |doc|
57
+ doc.try(:run_pending_callbacks)
58
+ end
59
+ end
60
+
61
+ target
47
62
  end
48
63
 
49
64
  # Resets the criteria inside the association proxy. Used by many-to-many
@@ -90,6 +105,19 @@ module Mongoid
90
105
  #
91
106
  # @return [ Proxy ] The association.
92
107
  def get_relation(name, association, object, reload = false)
108
+ field_name = database_field_name(name)
109
+
110
+ # As per the comments under MONGOID-5034, I've decided to only raise on
111
+ # embedded associations for a missing attribute. Rails does not raise
112
+ # for a missing attribute on referenced associations.
113
+ # We also don't want to raise if we're retrieving an association within
114
+ # the codebase. This is often done when retrieving the inverse association
115
+ # during binding or when cascading callbacks. Whenever we retrieve
116
+ # associations within the codebase, we use without_autobuild.
117
+ if !without_autobuild? && association.embedded? && attribute_missing?(field_name)
118
+ raise ActiveModel::MissingAttributeError, "Missing attribute: '#{field_name}'"
119
+ end
120
+
93
121
  if !reload && (value = ivar(name)) != false
94
122
  value
95
123
  else
@@ -291,7 +319,7 @@ module Mongoid
291
319
  ids_method = "#{association.name.to_s.singularize}_ids"
292
320
  association.inverse_class.tap do |klass|
293
321
  klass.re_define_method(ids_method) do
294
- send(association.name).only(:_id).map(&:_id)
322
+ send(association.name).pluck(:_id)
295
323
  end
296
324
  end
297
325
  end
@@ -341,6 +369,7 @@ module Mongoid
341
369
  # @return [ Class ] The class being set up.
342
370
  def self.define_ids_setter!(association)
343
371
  ids_method = "#{association.name.to_s.singularize}_ids="
372
+ association.inverse_class.aliased_associations[ids_method.chop] = association.name.to_s
344
373
  association.inverse_class.tap do |klass|
345
374
  klass.re_define_method(ids_method) do |ids|
346
375
  send(association.setter, association.relation_class.find(ids.reject(&:blank?)))
@@ -60,6 +60,53 @@ module Mongoid
60
60
  end
61
61
  end
62
62
 
63
+ # Remove the associated document from the inverse's association.
64
+ #
65
+ # @param [ Document ] doc The document to remove.
66
+ def remove_associated(doc)
67
+ if inverse = _association.inverse(doc)
68
+ if _association.many?
69
+ remove_associated_many(doc, inverse)
70
+ elsif _association.in_to?
71
+ remove_associated_in_to(doc, inverse)
72
+ end
73
+ end
74
+ end
75
+
76
+ # Remove the associated document from the inverse's association.
77
+ #
78
+ # This method removes the associated on *_many relationships.
79
+ #
80
+ # @param [ Document ] doc The document to remove.
81
+ # @param [ Symbol ] inverse The name of the inverse.
82
+ def remove_associated_many(doc, inverse)
83
+ # We only want to remove the inverse association when the inverse
84
+ # document is in memory.
85
+ if inv = doc.ivar(inverse)
86
+ # This first condition is needed because when assigning the
87
+ # embeds_many association using the same embeds_many
88
+ # association, we delete from the array we are about to assign.
89
+ if _base != inv && (associated = inv.ivar(_association.name))
90
+ associated.delete(doc)
91
+ end
92
+ end
93
+ end
94
+
95
+ # Remove the associated document from the inverse's association.
96
+ #
97
+ # This method removes associated on belongs_to and embedded_in
98
+ # associations.
99
+ #
100
+ # @param [ Document ] doc The document to remove.
101
+ # @param [ Symbol ] inverse The name of the inverse.
102
+ def remove_associated_in_to(doc, inverse)
103
+ # We only want to remove the inverse association when the inverse
104
+ # document is in memory.
105
+ if associated = doc.ivar(inverse)
106
+ associated.send(_association.setter, nil)
107
+ end
108
+ end
109
+
63
110
  # Set the id of the related document in the foreign key field on the
64
111
  # keyed document.
65
112
  #
@@ -134,6 +181,7 @@ module Mongoid
134
181
  # @param [ Document ] doc The document to bind.
135
182
  def bind_from_relational_parent(doc)
136
183
  check_inverse!(doc)
184
+ remove_associated(doc)
137
185
  bind_foreign_key(doc, record_id(_base))
138
186
  bind_polymorphic_type(doc, _base.class.name)
139
187
  bind_inverse(doc, _base)
@@ -46,9 +46,10 @@ module Mongoid
46
46
  association.inverse_class.tap do |klass|
47
47
  klass.re_define_method("build_#{association.name}") do |*args|
48
48
  attributes, _options = parse_args(*args)
49
- document = Factory.build(association.relation_class, attributes)
49
+ document = Factory.execute_build(association.relation_class, attributes, execute_callbacks: false)
50
50
  _building do
51
51
  child = send("#{association.name}=", document)
52
+ child.run_pending_callbacks
52
53
  child.run_callbacks(:build)
53
54
  child
54
55
  end
@@ -69,10 +70,11 @@ module Mongoid
69
70
  association.inverse_class.tap do |klass|
70
71
  klass.re_define_method("create_#{association.name}") do |*args|
71
72
  attributes, _options = parse_args(*args)
72
- document = Factory.build(association.relation_class, attributes)
73
+ document = Factory.execute_build(association.relation_class, attributes, execute_callbacks: false)
73
74
  doc = _assigning do
74
75
  send("#{association.name}=", document)
75
76
  end
77
+ doc.run_pending_callbacks
76
78
  doc.save
77
79
  save if new_record? && association.stores_foreign_key?
78
80
  doc
@@ -11,15 +11,11 @@ module Mongoid
11
11
  included do
12
12
  class_attribute :dependents
13
13
 
14
- # Note the leading underscore: without it, ActiveSupport's
15
- # class_attribute would generate a helper method for this attribute
16
- # that collides with one it generates for :dependents.
17
- #
18
14
  # @api private
19
- class_attribute :_dependents_owner
15
+ class_attribute :dependents_owner
20
16
 
21
17
  self.dependents = []
22
- self._dependents_owner = self
18
+ self.dependents_owner = self
23
19
  end
24
20
 
25
21
  class_methods do
@@ -54,9 +50,9 @@ module Mongoid
54
50
  def self.define_dependency!(association)
55
51
  validate!(association)
56
52
  association.inverse_class.tap do |klass|
57
- if klass._dependents_owner != klass
53
+ if klass.dependents_owner != klass
58
54
  klass.dependents = []
59
- klass._dependents_owner = klass
55
+ klass.dependents_owner = klass
60
56
  end
61
57
 
62
58
  if association.dependent && !klass.dependents.include?(association)
@@ -20,13 +20,35 @@ module Mongoid
20
20
  end
21
21
  end
22
22
 
23
- def preload(relations, docs)
24
- relations.group_by(&:inverse_class_name)
25
- .values
26
- .each do |associations|
27
- associations.group_by(&:relation)
28
- .each do |relation, association|
29
- relation.eager_loader(association, docs).run
23
+ # Load the associations for the given documents. This will be done
24
+ # recursively to load the associations of the given documents'
25
+ # subdocuments.
26
+ #
27
+ # @param [ Array<Association> ] associations The associations to load.
28
+ # @param [ Array<Document> ] document The documents.
29
+ def preload(associations, docs)
30
+ assoc_map = associations.group_by(&:inverse_class_name)
31
+ docs_map = {}
32
+ queue = [ klass.to_s ]
33
+
34
+ while klass = queue.shift
35
+ if as = assoc_map.delete(klass)
36
+ as.each do |assoc|
37
+ queue << assoc.class_name
38
+
39
+ # If this class is nested in the inclusion tree, only load documents
40
+ # for the association above it. If there is no parent association,
41
+ # we will include documents from the documents passed to this method.
42
+ ds = docs
43
+ if assoc.parent_inclusions.length > 0
44
+ ds = assoc.parent_inclusions.map{ |p| docs_map[p].to_a }.flatten
45
+ end
46
+
47
+ res = assoc.relation.eager_loader([assoc], ds).run
48
+
49
+ docs_map[assoc.name] ||= [].to_set
50
+ docs_map[assoc.name].merge(res)
51
+ end
30
52
  end
31
53
  end
32
54
  end
@@ -50,7 +50,7 @@ module Mongoid
50
50
  _unscoped.clear
51
51
  end
52
52
 
53
- # Batch remove the provided documents as a $pullAll.
53
+ # Batch remove the provided documents as a $pullAll or $pull.
54
54
  #
55
55
  # @example Batch remove the documents.
56
56
  # batchable.batch_remove([ doc_one, doc_two ])
@@ -58,13 +58,36 @@ module Mongoid
58
58
  # @param [ Array<Document> ] docs The docs to remove.
59
59
  # @param [ Symbol ] method Delete or destroy.
60
60
  def batch_remove(docs, method = :delete)
61
+ # If the _id is nil, we cannot use $pull and delete by searching for
62
+ # the id. Therefore we have to use pullAll with the documents'
63
+ # attributes.
61
64
  removals = pre_process_batch_remove(docs, method)
65
+ pulls, pull_alls = removals.partition { |o| !o["_id"].nil? }
66
+
67
+ if !_base.persisted?
68
+ post_process_batch_remove(docs, method) unless docs.empty?
69
+ return reindex
70
+ end
71
+
62
72
  if !docs.empty?
63
- collection.find(selector).update_one(
64
- positionally(selector, "$pullAll" => { path => removals }),
73
+ if !pulls.empty?
74
+ collection.find(selector).update_one(
75
+ positionally(selector, "$pull" => { path => { "_id" => { "$in" => pulls.pluck("_id") } } }),
65
76
  session: _session
66
- )
77
+ )
78
+ end
79
+ if !pull_alls.empty?
80
+ collection.find(selector).update_one(
81
+ positionally(selector, "$pullAll" => { path => pull_alls }),
82
+ session: _session
83
+ )
84
+ end
67
85
  post_process_batch_remove(docs, method)
86
+ else
87
+ collection.find(selector).update_one(
88
+ positionally(selector, "$set" => { path => [] }),
89
+ session: _session
90
+ )
68
91
  end
69
92
  reindex
70
93
  end
@@ -90,7 +113,7 @@ module Mongoid
90
113
  batch_remove(_target.dup)
91
114
  end
92
115
  elsif _target != docs
93
- _base.delayed_atomic_sets.clear unless _assigning?
116
+ _base.delayed_atomic_sets.delete(path) unless _assigning?
94
117
  docs = normalize_docs(docs).compact
95
118
  _target.clear and _unscoped.clear
96
119
  _base.delayed_atomic_unsets.delete(path)