mongoid 2.4.10 → 3.0.0

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 (356) hide show
  1. data/CHANGELOG.md +949 -10
  2. data/LICENSE +1 -1
  3. data/README.md +10 -11
  4. data/Rakefile +3 -17
  5. data/lib/config/locales/en.yml +455 -51
  6. data/lib/mongoid/atomic/modifiers.rb +2 -2
  7. data/lib/mongoid/atomic/paths/embedded/many.rb +6 -6
  8. data/lib/mongoid/atomic/paths/embedded/one.rb +5 -5
  9. data/lib/mongoid/atomic/paths/embedded.rb +4 -5
  10. data/lib/mongoid/atomic/paths/root.rb +4 -5
  11. data/lib/mongoid/atomic.rb +70 -16
  12. data/lib/mongoid/attributes/processing.rb +14 -10
  13. data/lib/mongoid/attributes/readonly.rb +56 -0
  14. data/lib/mongoid/attributes.rb +95 -32
  15. data/lib/mongoid/callbacks.rb +106 -43
  16. data/lib/mongoid/components.rb +12 -23
  17. data/lib/mongoid/config/environment.rb +7 -4
  18. data/lib/mongoid/config/inflections.rb +6 -0
  19. data/lib/mongoid/config/options.rb +1 -1
  20. data/lib/mongoid/config/validators/option.rb +25 -0
  21. data/lib/mongoid/config/validators/session.rb +140 -0
  22. data/lib/mongoid/config/validators.rb +3 -0
  23. data/lib/mongoid/config.rb +104 -225
  24. data/lib/mongoid/contextual/aggregable/memory.rb +109 -0
  25. data/lib/mongoid/contextual/aggregable/mongo.rb +181 -0
  26. data/lib/mongoid/contextual/atomic.rb +179 -0
  27. data/lib/mongoid/contextual/command.rb +43 -0
  28. data/lib/mongoid/contextual/find_and_modify.rb +68 -0
  29. data/lib/mongoid/contextual/map_reduce.rb +273 -0
  30. data/lib/mongoid/contextual/memory.rb +406 -0
  31. data/lib/mongoid/contextual/mongo.rb +662 -0
  32. data/lib/mongoid/contextual.rb +50 -0
  33. data/lib/mongoid/copyable.rb +7 -25
  34. data/lib/mongoid/criteria.rb +515 -245
  35. data/lib/mongoid/criterion/inspection.rb +14 -8
  36. data/lib/mongoid/criterion/scoping.rb +114 -44
  37. data/lib/mongoid/dirty.rb +152 -67
  38. data/lib/mongoid/document.rb +71 -52
  39. data/lib/mongoid/errors/ambiguous_relationship.rb +51 -0
  40. data/lib/mongoid/errors/callback.rb +5 -6
  41. data/lib/mongoid/errors/delete_restriction.rb +29 -0
  42. data/lib/mongoid/errors/document_not_found.rb +98 -17
  43. data/lib/mongoid/errors/eager_load.rb +3 -6
  44. data/lib/mongoid/errors/invalid_collection.rb +3 -3
  45. data/lib/mongoid/errors/invalid_config_option.rb +27 -0
  46. data/lib/mongoid/errors/invalid_database.rb +3 -3
  47. data/lib/mongoid/errors/invalid_field.rb +54 -8
  48. data/lib/mongoid/errors/invalid_field_option.rb +35 -0
  49. data/lib/mongoid/errors/invalid_find.rb +3 -3
  50. data/lib/mongoid/errors/invalid_index.rb +28 -0
  51. data/lib/mongoid/errors/invalid_options.rb +4 -4
  52. data/lib/mongoid/errors/invalid_scope.rb +24 -0
  53. data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +38 -0
  54. data/lib/mongoid/errors/invalid_storage_options.rb +27 -0
  55. data/lib/mongoid/errors/invalid_time.rb +3 -6
  56. data/lib/mongoid/errors/inverse_not_found.rb +29 -0
  57. data/lib/mongoid/errors/mixed_relations.rb +4 -9
  58. data/lib/mongoid/errors/mixed_session_configuration.rb +28 -0
  59. data/lib/mongoid/errors/mongoid_error.rb +54 -3
  60. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +28 -0
  61. data/lib/mongoid/errors/no_default_session.rb +23 -0
  62. data/lib/mongoid/errors/no_environment.rb +3 -3
  63. data/lib/mongoid/errors/no_map_reduce_output.rb +24 -0
  64. data/lib/mongoid/errors/no_metadata.rb +21 -0
  65. data/lib/mongoid/errors/no_parent.rb +24 -0
  66. data/lib/mongoid/errors/no_session_config.rb +22 -0
  67. data/lib/mongoid/errors/no_session_database.rb +27 -0
  68. data/lib/mongoid/errors/no_session_hosts.rb +27 -0
  69. data/lib/mongoid/errors/no_sessions_config.rb +20 -0
  70. data/lib/mongoid/errors/readonly_attribute.rb +25 -0
  71. data/lib/mongoid/errors/scope_overwrite.rb +4 -4
  72. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +4 -4
  73. data/lib/mongoid/errors/unknown_attribute.rb +25 -0
  74. data/lib/mongoid/errors/unsaved_document.rb +4 -8
  75. data/lib/mongoid/errors/unsupported_javascript.rb +27 -0
  76. data/lib/mongoid/errors/unsupported_version.rb +4 -4
  77. data/lib/mongoid/errors/validations.rb +7 -6
  78. data/lib/mongoid/errors/versioning_not_on_root.rb +23 -0
  79. data/lib/mongoid/errors.rb +23 -1
  80. data/lib/mongoid/evolvable.rb +19 -0
  81. data/lib/mongoid/extensions/array.rb +164 -0
  82. data/lib/mongoid/extensions/big_decimal.rb +42 -0
  83. data/lib/mongoid/extensions/boolean.rb +24 -0
  84. data/lib/mongoid/extensions/date.rb +70 -0
  85. data/lib/mongoid/extensions/date_time.rb +73 -0
  86. data/lib/mongoid/extensions/false_class.rb +38 -0
  87. data/lib/mongoid/extensions/float.rb +56 -0
  88. data/lib/mongoid/extensions/hash.rb +123 -0
  89. data/lib/mongoid/extensions/integer.rb +66 -0
  90. data/lib/mongoid/extensions/module.rb +28 -0
  91. data/lib/mongoid/extensions/nil_class.rb +21 -0
  92. data/lib/mongoid/extensions/object.rb +238 -0
  93. data/lib/mongoid/extensions/object_id.rb +54 -0
  94. data/lib/mongoid/extensions/range.rb +79 -0
  95. data/lib/mongoid/extensions/regexp.rb +27 -0
  96. data/lib/mongoid/extensions/set.rb +55 -0
  97. data/lib/mongoid/extensions/string.rb +181 -0
  98. data/lib/mongoid/extensions/symbol.rb +54 -0
  99. data/lib/mongoid/extensions/time.rb +78 -0
  100. data/lib/mongoid/extensions/time_with_zone.rb +55 -0
  101. data/lib/mongoid/extensions/true_class.rb +38 -0
  102. data/lib/mongoid/extensions.rb +28 -76
  103. data/lib/mongoid/factory.rb +1 -1
  104. data/lib/mongoid/fields/foreign_key.rb +150 -0
  105. data/lib/mongoid/fields/localized.rb +73 -0
  106. data/lib/mongoid/fields/standard.rb +268 -0
  107. data/lib/mongoid/fields/validators/macro.rb +83 -0
  108. data/lib/mongoid/fields/validators.rb +2 -0
  109. data/lib/mongoid/fields.rb +142 -208
  110. data/lib/mongoid/finders.rb +45 -50
  111. data/lib/mongoid/hierarchy.rb +44 -15
  112. data/lib/mongoid/identity_map.rb +49 -21
  113. data/lib/mongoid/indexes/validators/options.rb +80 -0
  114. data/lib/mongoid/indexes.rb +66 -15
  115. data/lib/mongoid/inspection.rb +1 -1
  116. data/lib/mongoid/json.rb +2 -2
  117. data/lib/mongoid/loggable.rb +69 -0
  118. data/lib/mongoid/matchers/all.rb +7 -8
  119. data/lib/mongoid/matchers/and.rb +3 -3
  120. data/lib/mongoid/matchers/default.rb +6 -4
  121. data/lib/mongoid/matchers/exists.rb +2 -2
  122. data/lib/mongoid/matchers/gt.rb +2 -2
  123. data/lib/mongoid/matchers/gte.rb +2 -2
  124. data/lib/mongoid/matchers/in.rb +3 -7
  125. data/lib/mongoid/matchers/lt.rb +2 -2
  126. data/lib/mongoid/matchers/lte.rb +2 -2
  127. data/lib/mongoid/matchers/ne.rb +2 -2
  128. data/lib/mongoid/matchers/nin.rb +2 -2
  129. data/lib/mongoid/matchers/or.rb +2 -2
  130. data/lib/mongoid/matchers/size.rb +2 -2
  131. data/lib/mongoid/matchers/strategies.rb +3 -3
  132. data/lib/mongoid/matchers.rb +1 -1
  133. data/lib/mongoid/multi_parameter_attributes.rb +9 -11
  134. data/lib/mongoid/nested_attributes.rb +17 -9
  135. data/lib/mongoid/observer.rb +1 -2
  136. data/lib/mongoid/paranoia.rb +10 -44
  137. data/lib/mongoid/persistence/atomic/add_to_set.rb +5 -9
  138. data/lib/mongoid/persistence/atomic/bit.rb +5 -7
  139. data/lib/mongoid/persistence/atomic/inc.rb +5 -7
  140. data/lib/mongoid/persistence/atomic/operation.rb +45 -6
  141. data/lib/mongoid/persistence/atomic/pop.rb +5 -7
  142. data/lib/mongoid/persistence/atomic/pull.rb +5 -7
  143. data/lib/mongoid/persistence/atomic/pull_all.rb +5 -7
  144. data/lib/mongoid/persistence/atomic/push.rb +4 -10
  145. data/lib/mongoid/persistence/atomic/push_all.rb +4 -10
  146. data/lib/mongoid/persistence/atomic/rename.rb +6 -7
  147. data/lib/mongoid/persistence/atomic/sets.rb +5 -7
  148. data/lib/mongoid/persistence/atomic/unset.rb +4 -5
  149. data/lib/mongoid/persistence/atomic.rb +2 -2
  150. data/lib/mongoid/persistence/deletion.rb +2 -2
  151. data/lib/mongoid/persistence/insertion.rb +10 -16
  152. data/lib/mongoid/persistence/modification.rb +5 -9
  153. data/lib/mongoid/persistence/operations/embedded/insert.rb +7 -6
  154. data/lib/mongoid/persistence/operations/embedded/remove.rb +5 -5
  155. data/lib/mongoid/persistence/operations/insert.rb +4 -4
  156. data/lib/mongoid/persistence/operations/remove.rb +4 -4
  157. data/lib/mongoid/persistence/operations/update.rb +5 -5
  158. data/lib/mongoid/persistence/operations/upsert.rb +28 -0
  159. data/lib/mongoid/persistence/operations.rb +22 -19
  160. data/lib/mongoid/persistence/upsertion.rb +30 -0
  161. data/lib/mongoid/persistence.rb +94 -39
  162. data/lib/mongoid/railtie.rb +26 -11
  163. data/lib/mongoid/railties/database.rake +22 -108
  164. data/lib/mongoid/relations/accessors.rb +120 -20
  165. data/lib/mongoid/relations/auto_save.rb +59 -5
  166. data/lib/mongoid/relations/binding.rb +211 -2
  167. data/lib/mongoid/relations/bindings/embedded/in.rb +16 -22
  168. data/lib/mongoid/relations/bindings/embedded/many.rb +9 -50
  169. data/lib/mongoid/relations/bindings/embedded/one.rb +10 -16
  170. data/lib/mongoid/relations/bindings/referenced/in.rb +31 -57
  171. data/lib/mongoid/relations/bindings/referenced/many.rb +8 -20
  172. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +15 -19
  173. data/lib/mongoid/relations/bindings/referenced/one.rb +10 -24
  174. data/lib/mongoid/relations/builder.rb +4 -4
  175. data/lib/mongoid/relations/builders/embedded/in.rb +5 -5
  176. data/lib/mongoid/relations/builders/embedded/many.rb +12 -12
  177. data/lib/mongoid/relations/builders/embedded/one.rb +6 -6
  178. data/lib/mongoid/relations/builders/nested_attributes/many.rb +8 -8
  179. data/lib/mongoid/relations/builders/nested_attributes/one.rb +5 -5
  180. data/lib/mongoid/relations/builders/referenced/in.rb +4 -4
  181. data/lib/mongoid/relations/builders/referenced/many.rb +6 -6
  182. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +7 -5
  183. data/lib/mongoid/relations/builders/referenced/one.rb +5 -5
  184. data/lib/mongoid/relations/builders.rb +19 -16
  185. data/lib/mongoid/relations/cascading/delete.rb +3 -5
  186. data/lib/mongoid/relations/cascading/destroy.rb +3 -3
  187. data/lib/mongoid/relations/cascading/nullify.rb +3 -3
  188. data/lib/mongoid/relations/cascading/restrict.rb +37 -0
  189. data/lib/mongoid/relations/cascading.rb +10 -7
  190. data/lib/mongoid/relations/constraint.rb +4 -3
  191. data/lib/mongoid/relations/conversions.rb +6 -7
  192. data/lib/mongoid/relations/cyclic.rb +7 -7
  193. data/lib/mongoid/relations/embedded/batchable.rb +347 -0
  194. data/lib/mongoid/relations/embedded/in.rb +23 -12
  195. data/lib/mongoid/relations/embedded/many.rb +100 -161
  196. data/lib/mongoid/relations/embedded/one.rb +25 -14
  197. data/lib/mongoid/relations/macros.rb +105 -60
  198. data/lib/mongoid/relations/many.rb +93 -14
  199. data/lib/mongoid/relations/metadata.rb +277 -47
  200. data/lib/mongoid/relations/nested_builder.rb +4 -6
  201. data/lib/mongoid/relations/one.rb +2 -2
  202. data/lib/mongoid/relations/options.rb +2 -2
  203. data/lib/mongoid/relations/polymorphic.rb +9 -9
  204. data/lib/mongoid/relations/proxy.rb +62 -31
  205. data/lib/mongoid/relations/referenced/in.rb +40 -15
  206. data/lib/mongoid/relations/referenced/many.rb +162 -130
  207. data/lib/mongoid/relations/referenced/many_to_many.rb +104 -48
  208. data/lib/mongoid/relations/referenced/one.rb +34 -13
  209. data/lib/mongoid/relations/reflections.rb +3 -3
  210. data/lib/mongoid/relations/synchronization.rb +19 -23
  211. data/lib/mongoid/relations/targets/enumerable.rb +86 -57
  212. data/lib/mongoid/relations/touchable.rb +32 -0
  213. data/lib/mongoid/relations.rb +22 -6
  214. data/lib/mongoid/reloading.rb +12 -14
  215. data/lib/mongoid/scoping.rb +312 -0
  216. data/lib/mongoid/serialization.rb +94 -42
  217. data/lib/mongoid/sessions/factory.rb +108 -0
  218. data/lib/mongoid/sessions/mongo_uri.rb +93 -0
  219. data/lib/mongoid/sessions/validators/storage.rb +49 -0
  220. data/lib/mongoid/sessions/validators.rb +2 -0
  221. data/lib/mongoid/sessions.rb +383 -0
  222. data/lib/mongoid/sharding.rb +6 -6
  223. data/lib/mongoid/state.rb +6 -7
  224. data/lib/mongoid/threaded/lifecycle.rb +21 -21
  225. data/lib/mongoid/threaded/sessions.rb +0 -0
  226. data/lib/mongoid/threaded.rb +219 -59
  227. data/lib/mongoid/timestamps/created.rb +8 -4
  228. data/lib/mongoid/timestamps/timeless.rb +6 -4
  229. data/lib/mongoid/timestamps/updated.rb +4 -3
  230. data/lib/mongoid/timestamps.rb +1 -1
  231. data/lib/mongoid/unit_of_work.rb +61 -0
  232. data/lib/mongoid/validations/associated.rb +2 -2
  233. data/lib/mongoid/validations/format.rb +2 -2
  234. data/lib/mongoid/validations/presence.rb +34 -4
  235. data/lib/mongoid/validations/uniqueness.rb +11 -12
  236. data/lib/mongoid/validations.rb +28 -20
  237. data/lib/mongoid/version.rb +2 -2
  238. data/lib/mongoid/versioning.rb +25 -26
  239. data/lib/mongoid.rb +37 -37
  240. data/lib/rack/mongoid/middleware/identity_map.rb +3 -3
  241. data/lib/rails/generators/mongoid/config/config_generator.rb +1 -1
  242. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +65 -17
  243. data/lib/rails/generators/mongoid/model/model_generator.rb +7 -7
  244. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +2 -2
  245. data/lib/rails/generators/mongoid/observer/observer_generator.rb +4 -4
  246. data/lib/rails/generators/mongoid_generator.rb +5 -5
  247. data/lib/rails/mongoid.rb +73 -26
  248. metadata +103 -148
  249. data/lib/config/locales/bg.yml +0 -61
  250. data/lib/config/locales/de.yml +0 -61
  251. data/lib/config/locales/en-GB.yml +0 -64
  252. data/lib/config/locales/es.yml +0 -59
  253. data/lib/config/locales/fr.yml +0 -62
  254. data/lib/config/locales/hi.yml +0 -53
  255. data/lib/config/locales/hu.yml +0 -64
  256. data/lib/config/locales/id.yml +0 -62
  257. data/lib/config/locales/it.yml +0 -59
  258. data/lib/config/locales/ja.yml +0 -57
  259. data/lib/config/locales/kr.yml +0 -54
  260. data/lib/config/locales/nl.yml +0 -61
  261. data/lib/config/locales/pl.yml +0 -59
  262. data/lib/config/locales/pt-BR.yml +0 -60
  263. data/lib/config/locales/pt.yml +0 -60
  264. data/lib/config/locales/ro.yml +0 -66
  265. data/lib/config/locales/ru.yml +0 -61
  266. data/lib/config/locales/sv.yml +0 -60
  267. data/lib/config/locales/vi.yml +0 -62
  268. data/lib/config/locales/zh-CN.yml +0 -53
  269. data/lib/mongoid/collection.rb +0 -157
  270. data/lib/mongoid/collections/master.rb +0 -45
  271. data/lib/mongoid/collections/operations.rb +0 -44
  272. data/lib/mongoid/collections/retry.rb +0 -59
  273. data/lib/mongoid/collections.rb +0 -120
  274. data/lib/mongoid/config/database.rb +0 -181
  275. data/lib/mongoid/config/replset_database.rb +0 -80
  276. data/lib/mongoid/contexts/enumerable/sort.rb +0 -43
  277. data/lib/mongoid/contexts/enumerable.rb +0 -313
  278. data/lib/mongoid/contexts/mongo.rb +0 -487
  279. data/lib/mongoid/contexts.rb +0 -25
  280. data/lib/mongoid/criterion/builder.rb +0 -34
  281. data/lib/mongoid/criterion/complex.rb +0 -84
  282. data/lib/mongoid/criterion/creational.rb +0 -34
  283. data/lib/mongoid/criterion/exclusion.rb +0 -108
  284. data/lib/mongoid/criterion/inclusion.rb +0 -290
  285. data/lib/mongoid/criterion/optional.rb +0 -259
  286. data/lib/mongoid/criterion/selector.rb +0 -177
  287. data/lib/mongoid/cursor.rb +0 -88
  288. data/lib/mongoid/default_scope.rb +0 -36
  289. data/lib/mongoid/errors/invalid_type.rb +0 -25
  290. data/lib/mongoid/extensions/array/deep_copy.rb +0 -25
  291. data/lib/mongoid/extensions/array/deletion.rb +0 -29
  292. data/lib/mongoid/extensions/false_class/equality.rb +0 -26
  293. data/lib/mongoid/extensions/hash/criteria_helpers.rb +0 -47
  294. data/lib/mongoid/extensions/hash/deep_copy.rb +0 -25
  295. data/lib/mongoid/extensions/hash/scoping.rb +0 -25
  296. data/lib/mongoid/extensions/integer/checks.rb +0 -23
  297. data/lib/mongoid/extensions/nil/collectionization.rb +0 -23
  298. data/lib/mongoid/extensions/object/checks.rb +0 -29
  299. data/lib/mongoid/extensions/object/deep_copy.rb +0 -21
  300. data/lib/mongoid/extensions/object/reflections.rb +0 -48
  301. data/lib/mongoid/extensions/object/substitutable.rb +0 -15
  302. data/lib/mongoid/extensions/object/yoda.rb +0 -44
  303. data/lib/mongoid/extensions/object_id/conversions.rb +0 -60
  304. data/lib/mongoid/extensions/proc/scoping.rb +0 -25
  305. data/lib/mongoid/extensions/string/checks.rb +0 -36
  306. data/lib/mongoid/extensions/string/conversions.rb +0 -22
  307. data/lib/mongoid/extensions/string/inflections.rb +0 -118
  308. data/lib/mongoid/extensions/symbol/checks.rb +0 -23
  309. data/lib/mongoid/extensions/symbol/inflections.rb +0 -67
  310. data/lib/mongoid/extensions/true_class/equality.rb +0 -26
  311. data/lib/mongoid/extras.rb +0 -31
  312. data/lib/mongoid/fields/internal/array.rb +0 -76
  313. data/lib/mongoid/fields/internal/big_decimal.rb +0 -63
  314. data/lib/mongoid/fields/internal/bignum.rb +0 -10
  315. data/lib/mongoid/fields/internal/binary.rb +0 -11
  316. data/lib/mongoid/fields/internal/boolean.rb +0 -58
  317. data/lib/mongoid/fields/internal/date.rb +0 -51
  318. data/lib/mongoid/fields/internal/date_time.rb +0 -28
  319. data/lib/mongoid/fields/internal/false_class.rb +0 -10
  320. data/lib/mongoid/fields/internal/fixnum.rb +0 -10
  321. data/lib/mongoid/fields/internal/float.rb +0 -47
  322. data/lib/mongoid/fields/internal/foreign_keys/array.rb +0 -88
  323. data/lib/mongoid/fields/internal/foreign_keys/object.rb +0 -56
  324. data/lib/mongoid/fields/internal/hash.rb +0 -11
  325. data/lib/mongoid/fields/internal/integer.rb +0 -59
  326. data/lib/mongoid/fields/internal/localized.rb +0 -62
  327. data/lib/mongoid/fields/internal/nil_class.rb +0 -53
  328. data/lib/mongoid/fields/internal/object.rb +0 -11
  329. data/lib/mongoid/fields/internal/object_id.rb +0 -46
  330. data/lib/mongoid/fields/internal/range.rb +0 -61
  331. data/lib/mongoid/fields/internal/set.rb +0 -57
  332. data/lib/mongoid/fields/internal/string.rb +0 -42
  333. data/lib/mongoid/fields/internal/symbol.rb +0 -43
  334. data/lib/mongoid/fields/internal/time.rb +0 -23
  335. data/lib/mongoid/fields/internal/time_with_zone.rb +0 -23
  336. data/lib/mongoid/fields/internal/timekeeping.rb +0 -122
  337. data/lib/mongoid/fields/internal/true_class.rb +0 -10
  338. data/lib/mongoid/fields/mappings.rb +0 -42
  339. data/lib/mongoid/fields/serializable.rb +0 -270
  340. data/lib/mongoid/identity.rb +0 -92
  341. data/lib/mongoid/javascript/functions.yml +0 -63
  342. data/lib/mongoid/javascript.rb +0 -20
  343. data/lib/mongoid/keys.rb +0 -144
  344. data/lib/mongoid/logger.rb +0 -45
  345. data/lib/mongoid/multi_database.rb +0 -36
  346. data/lib/mongoid/named_scope.rb +0 -166
  347. data/lib/mongoid/relations/embedded/atomic/operation.rb +0 -63
  348. data/lib/mongoid/relations/embedded/atomic/pull.rb +0 -65
  349. data/lib/mongoid/relations/embedded/atomic/push_all.rb +0 -59
  350. data/lib/mongoid/relations/embedded/atomic/set.rb +0 -61
  351. data/lib/mongoid/relations/embedded/atomic/unset.rb +0 -41
  352. data/lib/mongoid/relations/embedded/atomic.rb +0 -89
  353. data/lib/mongoid/relations/referenced/batch/insert.rb +0 -57
  354. data/lib/mongoid/relations/referenced/batch.rb +0 -73
  355. data/lib/mongoid/safety.rb +0 -105
  356. data/lib/mongoid/scope.rb +0 -31
@@ -1,12 +1,12 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
4
 
5
5
  # The "Grand Poobah" of information about any relation is this class. It
6
6
  # contains everything you could ever possible want to know.
7
7
  class Metadata < Hash
8
8
 
9
- delegate :foreign_key_default, :stores_foreign_key?, :to => :relation
9
+ delegate :foreign_key_default, :stores_foreign_key?, to: :relation
10
10
 
11
11
  # Returns the as option of the relation.
12
12
  #
@@ -32,6 +32,19 @@ module Mongoid # :nodoc:
32
32
  !!as
33
33
  end
34
34
 
35
+ # Is the relation autobuilding if accessed via the getter and the
36
+ # document is new.
37
+ #
38
+ # @example Is the relation autobuilding?
39
+ # metadata.autobuilding?
40
+ #
41
+ # @return [ true, false ] If the relation autobuilds.
42
+ #
43
+ # @since 3.0.0
44
+ def autobuilding?
45
+ !!self[:autobuild]
46
+ end
47
+
35
48
  # Returns the autosave option of the relation.
36
49
  #
37
50
  # @example Get the autosave option.
@@ -82,11 +95,7 @@ module Mongoid # :nodoc:
82
95
  # @since 2.0.0.rc.1
83
96
  def cascade_strategy
84
97
  if dependent?
85
- strategy =
86
- %{Mongoid::Relations::Cascading::#{dependent.to_s.classify}}
87
- strategy.constantize
88
- else
89
- return nil
98
+ "Mongoid::Relations::Cascading::#{dependent.to_s.classify}".constantize
90
99
  end
91
100
  end
92
101
 
@@ -114,7 +123,7 @@ module Mongoid # :nodoc:
114
123
  #
115
124
  # @since 2.0.0.rc.1
116
125
  def class_name
117
- @class_name ||= (self[:class_name] || classify).sub(/^::/,"")
126
+ @class_name ||= (self[:class_name] || classify).sub(/\A::/,"")
118
127
  end
119
128
 
120
129
  # Get the foreign key contraint for the metadata.
@@ -135,11 +144,12 @@ module Mongoid # :nodoc:
135
144
  # metadata.criteria([ id_one, id_two ])
136
145
  #
137
146
  # @param [ Object ] object The foreign key used for the query.
147
+ # @param [ Class ] type The base class.
138
148
  #
139
149
  # @return [ Criteria ] The criteria.
140
150
  #
141
151
  # @since 2.1.0
142
- def criteria(object, type = nil)
152
+ def criteria(object, type)
143
153
  query = relation.criteria(self, object, type)
144
154
  order ? query.order_by(order) : query
145
155
  end
@@ -253,7 +263,7 @@ module Mongoid # :nodoc:
253
263
  #
254
264
  # @since 2.3.3
255
265
  def forced_nil_inverse?
256
- has_key?(:inverse_of) && inverse_of.nil?
266
+ @forced_nil_inverse ||= has_key?(:inverse_of) && inverse_of.nil?
257
267
  end
258
268
 
259
269
  # Handles all the logic for figuring out what the foreign_key is for each
@@ -348,19 +358,42 @@ module Mongoid # :nodoc:
348
358
  #
349
359
  # @since 2.0.0.rc.1
350
360
  def inspect
351
- "#<Mongoid::Relations::Metadata\n" <<
352
- " class_name: #{class_name},\n" <<
353
- " cyclic: #{cyclic || "No"},\n" <<
354
- " dependent: #{dependent || "None"},\n" <<
355
- " inverse_of: #{inverse_of || "N/A"},\n" <<
356
- " key: #{key},\n" <<
357
- " macro: #{macro},\n" <<
358
- " name: #{name},\n" <<
359
- " order: #{order.inspect || "No"},\n" <<
360
- " polymorphic: #{polymorphic? || "No"},\n" <<
361
- " relation: #{relation},\n" <<
362
- " setter: #{setter},\n" <<
363
- " versioned: #{versioned? || "No"}>\n"
361
+ ::I18n.translate(
362
+ "mongoid.inspection.metadata",
363
+ {
364
+ autobuild: autobuilding?,
365
+ class_name: class_name,
366
+ cyclic: cyclic.inspect,
367
+ dependent: dependent.inspect,
368
+ inverse_of: inverse_of.inspect,
369
+ key: key,
370
+ locale: :en,
371
+ macro: macro,
372
+ name: name,
373
+ order: order.inspect,
374
+ polymorphic: polymorphic?,
375
+ relation: relation,
376
+ setter: setter,
377
+ versioned: versioned?
378
+ }
379
+ )
380
+ end
381
+
382
+ # Get the name of the inverse relations if they exists. If this is a
383
+ # polymorphic relation then just return the :as option that was defined.
384
+ #
385
+ # @example Get the names of the inverses.
386
+ # metadata.inverses
387
+ #
388
+ # @param [ Document ] other The document to aid in the discovery.
389
+ #
390
+ # @return [ Array<Symbol> ] The inverse name.
391
+ def inverses(other = nil)
392
+ if self[:polymorphic]
393
+ lookup_inverses(other)
394
+ else
395
+ @inverses ||= determine_inverses
396
+ end
364
397
  end
365
398
 
366
399
  # Get the name of the inverse relation if it exists. If this is a
@@ -375,9 +408,8 @@ module Mongoid # :nodoc:
375
408
  #
376
409
  # @since 2.0.0.rc.1
377
410
  def inverse(other = nil)
378
- return self[:inverse_of] if has_key?(:inverse_of)
379
- return self[:as] || lookup_inverse(other) if polymorphic?
380
- @inverse ||= (cyclic? ? cyclic_inverse : inverse_relation)
411
+ invs = inverses(other)
412
+ invs.first if invs.count == 1
381
413
  end
382
414
 
383
415
  # Returns the inverse_class_name option of the relation.
@@ -479,7 +511,8 @@ module Mongoid # :nodoc:
479
511
  #
480
512
  # @since 2.0.0.rc.1
481
513
  def inverse_setter(other = nil)
482
- "#{inverse(other)}="
514
+ inv = inverse(other)
515
+ inv ? "#{inv}=" : nil
483
516
  end
484
517
 
485
518
  # Returns the name of the field in which to store the name of the class
@@ -492,8 +525,7 @@ module Mongoid # :nodoc:
492
525
  #
493
526
  # @since 2.0.0.rc.1
494
527
  def inverse_type
495
- @inverse_type ||=
496
- relation.stores_foreign_key? && polymorphic? ? "#{name}_type" : nil
528
+ @inverse_type ||= determine_inverse_for(:type)
497
529
  end
498
530
 
499
531
  # Gets the setter for the field that sets the type of document on a
@@ -509,6 +541,31 @@ module Mongoid # :nodoc:
509
541
  @inverse_type_setter ||= inverse_type ? "#{inverse_type}=" : nil
510
542
  end
511
543
 
544
+ # Returns the name of the field in which to store the name of the inverse
545
+ # field for the polymorphic relation.
546
+ #
547
+ # @example Get the name of the field.
548
+ # metadata.inverse_of_field
549
+ #
550
+ # @return [ String ] The name of the field for storing the name of the
551
+ # inverse field.
552
+ #
553
+ # @since 2.4.5
554
+ def inverse_of_field
555
+ @inverse_of_field ||= determine_inverse_for(:field)
556
+ end
557
+
558
+ # Gets the setter for the field that stores the name of the inverse field
559
+ # on a polymorphic relation.
560
+ #
561
+ # @example Get the inverse type setter.
562
+ # metadata.inverse_of_field_setter
563
+ #
564
+ # @return [ String ] The name of the setter.
565
+ def inverse_of_field_setter
566
+ @inverse_of_field_setter ||= inverse_of_field ? "#{inverse_of_field}=" : nil
567
+ end
568
+
512
569
  # This returns the key that is to be used to grab the attributes for the
513
570
  # relation or the foreign key or id that a referenced relation will use
514
571
  # to query for the object.
@@ -689,6 +746,17 @@ module Mongoid # :nodoc:
689
746
  @type_setter ||= type ? "#{type}=" : nil
690
747
  end
691
748
 
749
+
750
+ # Key where embedded document is save.
751
+ # By default is the name of relation
752
+ #
753
+ # @return [ String ] the name of key where save
754
+ #
755
+ # @since 3.0.0
756
+ def store_as
757
+ @store_as ||= (self[:store_as].try(:to_s) || name.to_s)
758
+ end
759
+
692
760
  # Are we validating this relation automatically?
693
761
  #
694
762
  # @example Is automatic validation on?
@@ -754,6 +822,18 @@ module Mongoid # :nodoc:
754
822
  !!order
755
823
  end
756
824
 
825
+ # Is this relation touchable?
826
+ #
827
+ # @example Is the relation touchable?
828
+ # metadata.touchable?
829
+ #
830
+ # @return [ true, false ] If the relation can be touched.
831
+ #
832
+ # @since 3.0.0
833
+ def touchable?
834
+ !!self[:touch]
835
+ end
836
+
757
837
  private
758
838
 
759
839
  # Returns the class name for the relation.
@@ -761,11 +841,84 @@ module Mongoid # :nodoc:
761
841
  # @example Get the class name.
762
842
  # metadata.classify
763
843
  #
764
- # @return [ String ] If embedded_in, the camelized, else classified.
844
+ # @return [ String ] The classified name.
765
845
  #
766
846
  # @since 2.0.0.rc.1
767
847
  def classify
768
- macro == :embedded_in ? name.to_s.camelize : name.to_s.classify
848
+ @classify ||= "#{find_module}::#{name.to_s.classify}"
849
+ end
850
+
851
+ # Get the name for the inverse field.
852
+ #
853
+ # @api private
854
+ #
855
+ # @example Get the inverse field name.
856
+ # metadata.determine_inverse_for(:type)
857
+ #
858
+ # @param [ Symbol ] field The inverse field name.
859
+ #
860
+ # @return [ String ] The name of the field.
861
+ #
862
+ # @since 3.0.0
863
+ def determine_inverse_for(field)
864
+ relation.stores_foreign_key? && polymorphic? ? "#{name}_#{field}" : nil
865
+ end
866
+
867
+ # Deterimene the inverses that can be memoized.
868
+ #
869
+ # @api private
870
+ #
871
+ # @example Determin the inverses.
872
+ # metadata.determine_inverses
873
+ #
874
+ # @return [ Array<Symbol> ] The inverses.
875
+ #
876
+ # @since 3.0.0
877
+ def determine_inverses
878
+ return [ inverse_of ] if has_key?(:inverse_of)
879
+ return [ as ] if has_key?(:as)
880
+ return [ cyclic_inverse ] if self[:cyclic]
881
+ [ inverse_relation ]
882
+ end
883
+
884
+ # Find the module the class with the specific name is in.
885
+ # This is done by starting at the inverse_class_name's
886
+ # module and stepping down to see where it is defined.
887
+ #
888
+ # @api private
889
+ #
890
+ # @example Find the module.
891
+ # metadata.find_module
892
+ #
893
+ # @return [ String ] The module.
894
+ #
895
+ # @since 3.0.0
896
+ def find_module
897
+ if inverse_class_name.present?
898
+ parts = inverse_class_name.split('::')
899
+ modules = parts.size.times.map { |i| parts.first(i).join('::') }.reverse
900
+ find_from_parts(modules)
901
+ end
902
+ end
903
+
904
+ # Find the modules from a reversed list.
905
+ #
906
+ # @api private
907
+ #
908
+ # @example Find the module from the parts.
909
+ # metadata.find_from_parts([ "Namespace", "Module" ])
910
+ #
911
+ # @param [ Array<String> ] The modules.
912
+ #
913
+ # @return [ String ] The matching module.
914
+ #
915
+ # @since 3.0.0
916
+ def find_from_parts(modules)
917
+ modules.find do |mod|
918
+ ActiveSupport::Inflector.constantize(mod).constants.include?(
919
+ name.to_s.classify.to_sym
920
+ )
921
+ end
769
922
  end
770
923
 
771
924
  # Get the name of the inverse relation in a cyclic relation.
@@ -820,11 +973,7 @@ module Mongoid # :nodoc:
820
973
  return self[:foreign_key].to_s if self[:foreign_key]
821
974
  suffix = relation.foreign_key_suffix
822
975
  if relation.stores_foreign_key?
823
- if relation.macro == :references_and_referenced_in_many
824
- "#{name.to_s.singularize}#{suffix}"
825
- else
826
- "#{name}#{suffix}"
827
- end
976
+ relation.foreign_key(name)
828
977
  else
829
978
  if polymorphic?
830
979
  "#{self[:as]}#{suffix}"
@@ -861,15 +1010,63 @@ module Mongoid # :nodoc:
861
1010
  #
862
1011
  # @since 2.0.0.rc.1
863
1012
  def determine_inverse_relation
864
- default = klass.relations[inverse_klass.name.underscore]
1013
+ default = foreign_key_match || klass.relations[inverse_klass.name.underscore]
865
1014
  return default.name if default
866
- klass.relations.each_pair do |key, meta|
867
- next if meta.versioned? || meta.name == name
868
- if meta.class_name == inverse_class_name
869
- return key.to_sym
1015
+ names = inverse_relation_candidate_names
1016
+ if names.size > 1
1017
+ raise Errors::AmbiguousRelationship.new(klass, inverse_klass, name, names)
1018
+ end
1019
+ names.first
1020
+ end
1021
+
1022
+ # Return metadata where the foreign key matches the foreign key on this
1023
+ # relation.
1024
+ #
1025
+ # @api private
1026
+ #
1027
+ # @example Return a foreign key match.
1028
+ # meta.foreign_key_match
1029
+ #
1030
+ # @return [ Metadata ] A match, if any.
1031
+ #
1032
+ # @since 2.4.11
1033
+ def foreign_key_match
1034
+ if fk = self[:foreign_key]
1035
+ relations_metadata.detect do |meta|
1036
+ fk == meta.foreign_key if meta.stores_foreign_key?
870
1037
  end
871
1038
  end
872
- return nil
1039
+ end
1040
+
1041
+ # Get the inverse relation candidates.
1042
+ #
1043
+ # @api private
1044
+ #
1045
+ # @example Get the inverse relation candidates.
1046
+ # metadata.inverse_relation_candidates
1047
+ #
1048
+ # @return [ Array<Metdata> ] The candidates.
1049
+ #
1050
+ # @since 3.0.0
1051
+ def inverse_relation_candidates
1052
+ relations_metadata.select do |meta|
1053
+ next if meta.versioned? || meta.name == name
1054
+ meta.class_name == inverse_class_name
1055
+ end
1056
+ end
1057
+
1058
+ # Get the candidates for inverse relations.
1059
+ #
1060
+ # @api private
1061
+ #
1062
+ # @example Get the candidates.
1063
+ # metadata.inverse_relation_candidates
1064
+ #
1065
+ # @return [ Array<Symbol> ] The candidates.
1066
+ #
1067
+ # @since 3.0.0
1068
+ def inverse_relation_candidate_names
1069
+ @candidate_names ||= inverse_relation_candidates.map(&:name)
873
1070
  end
874
1071
 
875
1072
  # Determine the key for the relation in the attributes.
@@ -881,7 +1078,7 @@ module Mongoid # :nodoc:
881
1078
  #
882
1079
  # @since 2.0.0.rc.1
883
1080
  def determine_key
884
- return name.to_s if relation.embedded?
1081
+ return store_as.to_s if relation.embedded?
885
1082
  relation.stores_foreign_key? ? foreign_key : "_id"
886
1083
  end
887
1084
 
@@ -909,6 +1106,26 @@ module Mongoid # :nodoc:
909
1106
  @inverse_name ||= inverse_klass.name.underscore
910
1107
  end
911
1108
 
1109
+ # For polymorphic children, we need to figure out the inverse from the
1110
+ # actual instance on the other side, since we cannot know the exact class
1111
+ # name to infer it from at load time.
1112
+ #
1113
+ # @example Find the inverses.
1114
+ # metadata.lookup_inverses(other)
1115
+ #
1116
+ # @param [ Document ] : The inverse document.
1117
+ #
1118
+ # @return [ Array<String> ] The inverse names.
1119
+ def lookup_inverses(other)
1120
+ if other
1121
+ matches = []
1122
+ other.class.relations.values.each do |meta|
1123
+ matches.push(meta.name) if meta.as == name
1124
+ end
1125
+ matches
1126
+ end
1127
+ end
1128
+
912
1129
  # For polymorphic children, we need to figure out the inverse from the
913
1130
  # actual instance on the other side, since we cannot know the exact class
914
1131
  # name to infer it from at load time.
@@ -922,11 +1139,24 @@ module Mongoid # :nodoc:
922
1139
  #
923
1140
  # @since 2.0.0.rc.1
924
1141
  def lookup_inverse(other)
925
- return nil unless other
926
- other.class.relations.each_pair do |key, meta|
927
- return meta.name if meta.as == name
1142
+ if invs = lookup_inverses(other) && invs.count == 1
1143
+ invs.first
928
1144
  end
929
1145
  end
1146
+
1147
+ # Get the relation metadata only.
1148
+ #
1149
+ # @api private
1150
+ #
1151
+ # @example Get the relation metadata.
1152
+ # metadata.relations_metadata
1153
+ #
1154
+ # @return [ Array<Metadata> ] The metadata.
1155
+ #
1156
+ # @since 3.0.0
1157
+ def relations_metadata
1158
+ klass.relations.values
1159
+ end
930
1160
  end
931
1161
  end
932
1162
  end
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
4
 
5
5
  # This is the superclass for builders that are in charge of handling
6
6
  # creation, deletion, and updates of documents through that ever so lovely
@@ -57,19 +57,17 @@ module Mongoid # :nodoc:
57
57
 
58
58
  # Convert an id to its appropriate type.
59
59
  #
60
- # @todo Durran: Move this into a common reusable place.
61
- #
62
60
  # @example Convert the id.
63
61
  # builder.convert_id(Person, "4d371b444835d98b8b000010")
64
62
  #
65
63
  # @param [ Class ] klass The class we're trying to convert for.
66
64
  # @param [ String ] id The id, usually coming from the form.
67
65
  #
68
- # @return [ BSON::ObjectId, String, Object ] The converted id.
66
+ # @return [ Moped::BSON::ObjectId, String, Object ] The converted id.
69
67
  #
70
68
  # @since 2.0.0.rc.6
71
69
  def convert_id(klass, id)
72
- BSON::ObjectId.convert(klass, id)
70
+ klass.using_object_ids? ? Moped::BSON::ObjectId.mongoize(id) : id
73
71
  end
74
72
  end
75
73
  end
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
4
 
5
5
  # This is the superclass for one to one relations and defines the common
6
6
  # behaviour or those proxies.
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
4
 
5
5
  # This module contains the validating logic for options passed to relation
6
6
  # macros.
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
4
 
5
5
  # This module contains the behaviour for handling polymorphic relational
6
6
  # associations.
@@ -11,7 +11,7 @@ module Mongoid # :nodoc:
11
11
  class_attribute :polymorphic
12
12
  end
13
13
 
14
- module ClassMethods #:nodoc:
14
+ module ClassMethods
15
15
 
16
16
  # Attempts to set up the information needed to handle a polymorphic
17
17
  # relation, if the metadata checks out.
@@ -25,14 +25,14 @@ module Mongoid # :nodoc:
25
25
  #
26
26
  # @since 2.0.0.rc.1
27
27
  def polymorph(metadata)
28
- tap do |klass|
29
- if metadata.polymorphic?
30
- klass.polymorphic = true
31
- if metadata.relation.stores_foreign_key?
32
- field(metadata.inverse_type, :type => String)
33
- end
28
+ if metadata.polymorphic?
29
+ self.polymorphic = true
30
+ if metadata.relation.stores_foreign_key?
31
+ field(metadata.inverse_type, type: String)
32
+ field(metadata.inverse_of_field, type: Symbol)
34
33
  end
35
34
  end
35
+ self
36
36
  end
37
37
  end
38
38
  end
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
4
 
5
5
  # This class is the superclass for all relation proxy objects, and contains
6
6
  # common behaviour for all of them.
@@ -18,9 +18,9 @@ module Mongoid # :nodoc:
18
18
  attr_accessor :base, :loaded, :metadata, :target
19
19
 
20
20
  # Backwards compatibility with Mongoid beta releases.
21
- delegate :klass, :to => :metadata
22
- delegate :bind_one, :unbind_one, :to => :binding
23
- delegate :collection_name, :to => :base
21
+ delegate :klass, :foreign_key, :inverse_foreign_key, to: :metadata
22
+ delegate :bind_one, :unbind_one, to: :binding
23
+ delegate :collection_name, to: :base
24
24
 
25
25
  # Convenience for setting the target and the metadata properties since
26
26
  # all proxies will need to do this.
@@ -52,6 +52,35 @@ module Mongoid # :nodoc:
52
52
  target
53
53
  end
54
54
 
55
+ # Tell the next persistance operation to store in a specific collection,
56
+ # database or session.
57
+ #
58
+ # @example Save the current document to a different collection.
59
+ # model.with(collection: "secondary").save
60
+ #
61
+ # @example Save the current document to a different database.
62
+ # model.with(database: "secondary").save
63
+ #
64
+ # @example Save the current document to a different session.
65
+ # model.with(session: "replica_set").save
66
+ #
67
+ # @example Save with a combination of options.
68
+ # model.with(session: "sharded", database: "secondary").save
69
+ #
70
+ # @param [ Hash ] options The storage options.
71
+ #
72
+ # @option options [ String, Symbol ] :collection The collection name.
73
+ # @option options [ String, Symbol ] :database The database name.
74
+ # @option options [ String, Symbol ] :session The session name.
75
+ #
76
+ # @return [ Document ] The current document.
77
+ #
78
+ # @since 3.0.0
79
+ def with(options)
80
+ Threaded.set_persistence_options(klass, options)
81
+ self
82
+ end
83
+
55
84
  protected
56
85
 
57
86
  # Get the collection from the root of the hierarchy.
@@ -67,22 +96,6 @@ module Mongoid # :nodoc:
67
96
  root.collection unless root.embedded?
68
97
  end
69
98
 
70
- # Return a new document for the type of class we want to instantiate.
71
- # If the type is provided use that, otherwise the klass from the
72
- # metadata.
73
- #
74
- # @example Get an instantiated document.
75
- # proxy.instantiated(Person)
76
- #
77
- # @param [ Class ] type The type of class to instantiate.
78
- #
79
- # @return [ Document ] The freshly created document.
80
- #
81
- # @since 2.0.0.rc.1
82
- def instantiated(type = nil)
83
- type ? type.new : metadata.klass.new
84
- end
85
-
86
99
  # Takes the supplied document and sets the metadata on it.
87
100
  #
88
101
  # @example Set the metadata.
@@ -132,16 +145,34 @@ module Mongoid # :nodoc:
132
145
  raise Errors::UnsavedDocument.new(base, doc)
133
146
  end
134
147
 
135
- # Get the class of the root document in the hierarchy.
136
- #
137
- # @example Get the root's class.
138
- # proxy.root_class
139
- #
140
- # @return [ Class ] The root class.
141
- #
142
- # @since 2.1.8
143
- def root_class
144
- @root_class ||= base._root.class
148
+ class << self
149
+
150
+ # Get the criteria that is used to eager load a relation of this
151
+ # type.
152
+ #
153
+ # @example Get the eager load criteria.
154
+ # Proxy.eager_load(metadata, criteria)
155
+ #
156
+ # @param [ Metadata ] metadata The relation metadata.
157
+ # @param [ Array<Object> ] ids The ids of the base docs.
158
+ #
159
+ # @return [ Criteria ] The criteria to eager load the relation.
160
+ #
161
+ # @since 2.2.0
162
+ def eager_load_ids(metadata, ids)
163
+ klass, foreign_key = metadata.klass, metadata.foreign_key
164
+ eager_loaded = klass.any_in(foreign_key => ids).entries
165
+ unless eager_loaded.empty?
166
+ eager_loaded.each do |doc|
167
+ base_id = doc.__send__(foreign_key)
168
+ yield(doc, { foreign_key => base_id })
169
+ end
170
+ else
171
+ ids.each do |id|
172
+ IdentityMap.clear_many(klass, { foreign_key => id })
173
+ end
174
+ end
175
+ end
145
176
  end
146
177
  end
147
178
  end