mongoid 2.8.1 → 3.0.0.rc

Sign up to get free protection for your applications and to get access to all the features.
Files changed (351) hide show
  1. data/CHANGELOG.md +802 -58
  2. data/LICENSE +1 -1
  3. data/README.md +10 -11
  4. data/Rakefile +2 -8
  5. data/lib/config/locales/en.yml +441 -51
  6. data/lib/mongoid.rb +24 -39
  7. data/lib/mongoid/atomic.rb +16 -33
  8. data/lib/mongoid/atomic/modifiers.rb +2 -2
  9. data/lib/mongoid/atomic/paths/embedded.rb +4 -5
  10. data/lib/mongoid/atomic/paths/embedded/many.rb +6 -6
  11. data/lib/mongoid/atomic/paths/embedded/one.rb +5 -5
  12. data/lib/mongoid/atomic/paths/root.rb +4 -5
  13. data/lib/mongoid/attributes.rb +95 -32
  14. data/lib/mongoid/attributes/processing.rb +14 -10
  15. data/lib/mongoid/attributes/readonly.rb +56 -0
  16. data/lib/mongoid/callbacks.rb +90 -27
  17. data/lib/mongoid/collections/retry.rb +2 -3
  18. data/lib/mongoid/components.rb +11 -23
  19. data/lib/mongoid/config.rb +87 -233
  20. data/lib/mongoid/config/environment.rb +5 -6
  21. data/lib/mongoid/config/inflections.rb +6 -0
  22. data/lib/mongoid/config/options.rb +1 -1
  23. data/lib/mongoid/config/validators.rb +3 -0
  24. data/lib/mongoid/config/validators/option.rb +25 -0
  25. data/lib/mongoid/config/validators/session.rb +140 -0
  26. data/lib/mongoid/contextual.rb +50 -0
  27. data/lib/mongoid/contextual/aggregable/memory.rb +98 -0
  28. data/lib/mongoid/contextual/aggregable/mongo.rb +181 -0
  29. data/lib/mongoid/contextual/atomic.rb +179 -0
  30. data/lib/mongoid/contextual/command.rb +43 -0
  31. data/lib/mongoid/contextual/find_and_modify.rb +66 -0
  32. data/lib/mongoid/contextual/map_reduce.rb +273 -0
  33. data/lib/mongoid/contextual/memory.rb +383 -0
  34. data/lib/mongoid/contextual/mongo.rb +543 -0
  35. data/lib/mongoid/copyable.rb +3 -34
  36. data/lib/mongoid/criteria.rb +436 -250
  37. data/lib/mongoid/criterion/inspection.rb +14 -8
  38. data/lib/mongoid/criterion/scoping.rb +114 -44
  39. data/lib/mongoid/dirty.rb +152 -67
  40. data/lib/mongoid/document.rb +69 -50
  41. data/lib/mongoid/errors.rb +22 -1
  42. data/lib/mongoid/errors/ambiguous_relationship.rb +51 -0
  43. data/lib/mongoid/errors/callback.rb +5 -6
  44. data/lib/mongoid/errors/delete_restriction.rb +29 -0
  45. data/lib/mongoid/errors/document_not_found.rb +98 -17
  46. data/lib/mongoid/errors/eager_load.rb +3 -6
  47. data/lib/mongoid/errors/invalid_collection.rb +3 -3
  48. data/lib/mongoid/errors/invalid_config_option.rb +27 -0
  49. data/lib/mongoid/errors/invalid_database.rb +3 -3
  50. data/lib/mongoid/errors/invalid_field.rb +54 -8
  51. data/lib/mongoid/errors/invalid_field_option.rb +35 -0
  52. data/lib/mongoid/errors/invalid_find.rb +3 -3
  53. data/lib/mongoid/errors/invalid_index.rb +28 -0
  54. data/lib/mongoid/errors/invalid_options.rb +4 -4
  55. data/lib/mongoid/errors/invalid_scope.rb +24 -0
  56. data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +38 -0
  57. data/lib/mongoid/errors/invalid_storage_options.rb +27 -0
  58. data/lib/mongoid/errors/invalid_time.rb +3 -6
  59. data/lib/mongoid/errors/inverse_not_found.rb +29 -0
  60. data/lib/mongoid/errors/mixed_relations.rb +4 -9
  61. data/lib/mongoid/errors/mixed_session_configuration.rb +28 -0
  62. data/lib/mongoid/errors/mongoid_error.rb +54 -3
  63. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +28 -0
  64. data/lib/mongoid/errors/no_default_session.rb +23 -0
  65. data/lib/mongoid/errors/no_environment.rb +3 -3
  66. data/lib/mongoid/errors/no_map_reduce_output.rb +24 -0
  67. data/lib/mongoid/errors/no_parent.rb +24 -0
  68. data/lib/mongoid/errors/no_session_config.rb +22 -0
  69. data/lib/mongoid/errors/no_session_database.rb +27 -0
  70. data/lib/mongoid/errors/no_session_hosts.rb +27 -0
  71. data/lib/mongoid/errors/no_sessions_config.rb +20 -0
  72. data/lib/mongoid/errors/readonly_attribute.rb +25 -0
  73. data/lib/mongoid/errors/scope_overwrite.rb +4 -4
  74. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +4 -4
  75. data/lib/mongoid/errors/unknown_attribute.rb +25 -0
  76. data/lib/mongoid/errors/unsaved_document.rb +4 -8
  77. data/lib/mongoid/errors/unsupported_javascript.rb +27 -0
  78. data/lib/mongoid/errors/unsupported_version.rb +4 -4
  79. data/lib/mongoid/errors/validations.rb +7 -6
  80. data/lib/mongoid/errors/versioning_not_on_root.rb +23 -0
  81. data/lib/mongoid/extensions.rb +28 -76
  82. data/lib/mongoid/extensions/array.rb +127 -0
  83. data/lib/mongoid/extensions/big_decimal.rb +42 -0
  84. data/lib/mongoid/extensions/boolean.rb +24 -0
  85. data/lib/mongoid/extensions/date.rb +70 -0
  86. data/lib/mongoid/extensions/date_time.rb +68 -0
  87. data/lib/mongoid/extensions/false_class.rb +26 -0
  88. data/lib/mongoid/extensions/float.rb +44 -0
  89. data/lib/mongoid/extensions/hash.rb +91 -0
  90. data/lib/mongoid/extensions/integer.rb +54 -0
  91. data/lib/mongoid/extensions/module.rb +28 -0
  92. data/lib/mongoid/extensions/nil_class.rb +21 -0
  93. data/lib/mongoid/extensions/object.rb +188 -0
  94. data/lib/mongoid/extensions/object_id.rb +53 -0
  95. data/lib/mongoid/extensions/range.rb +55 -0
  96. data/lib/mongoid/extensions/regexp.rb +27 -0
  97. data/lib/mongoid/extensions/set.rb +55 -0
  98. data/lib/mongoid/extensions/string.rb +155 -0
  99. data/lib/mongoid/extensions/symbol.rb +54 -0
  100. data/lib/mongoid/extensions/time.rb +78 -0
  101. data/lib/mongoid/extensions/time_with_zone.rb +55 -0
  102. data/lib/mongoid/extensions/true_class.rb +26 -0
  103. data/lib/mongoid/factory.rb +1 -1
  104. data/lib/mongoid/fields.rb +129 -194
  105. data/lib/mongoid/fields/foreign_key.rb +134 -0
  106. data/lib/mongoid/fields/localized.rb +73 -0
  107. data/lib/mongoid/fields/standard.rb +268 -0
  108. data/lib/mongoid/fields/validators.rb +2 -0
  109. data/lib/mongoid/fields/validators/macro.rb +83 -0
  110. data/lib/mongoid/finders.rb +42 -43
  111. data/lib/mongoid/hierarchy.rb +25 -14
  112. data/lib/mongoid/identity_map.rb +31 -19
  113. data/lib/mongoid/indexes.rb +66 -15
  114. data/lib/mongoid/indexes/validators/options.rb +80 -0
  115. data/lib/mongoid/inspection.rb +1 -1
  116. data/lib/mongoid/javascript.rb +1 -1
  117. data/lib/mongoid/json.rb +2 -2
  118. data/lib/mongoid/loggable.rb +69 -0
  119. data/lib/mongoid/matchers.rb +1 -1
  120. data/lib/mongoid/matchers/all.rb +7 -8
  121. data/lib/mongoid/matchers/and.rb +3 -3
  122. data/lib/mongoid/matchers/default.rb +6 -4
  123. data/lib/mongoid/matchers/exists.rb +2 -2
  124. data/lib/mongoid/matchers/gt.rb +2 -2
  125. data/lib/mongoid/matchers/gte.rb +2 -2
  126. data/lib/mongoid/matchers/in.rb +3 -7
  127. data/lib/mongoid/matchers/lt.rb +2 -2
  128. data/lib/mongoid/matchers/lte.rb +2 -2
  129. data/lib/mongoid/matchers/ne.rb +2 -2
  130. data/lib/mongoid/matchers/nin.rb +2 -2
  131. data/lib/mongoid/matchers/or.rb +2 -2
  132. data/lib/mongoid/matchers/size.rb +2 -2
  133. data/lib/mongoid/matchers/strategies.rb +3 -3
  134. data/lib/mongoid/multi_parameter_attributes.rb +8 -10
  135. data/lib/mongoid/nested_attributes.rb +17 -9
  136. data/lib/mongoid/observer.rb +1 -2
  137. data/lib/mongoid/paranoia.rb +13 -18
  138. data/lib/mongoid/persistence.rb +43 -39
  139. data/lib/mongoid/persistence/atomic.rb +2 -2
  140. data/lib/mongoid/persistence/atomic/add_to_set.rb +5 -9
  141. data/lib/mongoid/persistence/atomic/bit.rb +5 -7
  142. data/lib/mongoid/persistence/atomic/inc.rb +5 -7
  143. data/lib/mongoid/persistence/atomic/operation.rb +45 -6
  144. data/lib/mongoid/persistence/atomic/pop.rb +5 -7
  145. data/lib/mongoid/persistence/atomic/pull.rb +5 -7
  146. data/lib/mongoid/persistence/atomic/pull_all.rb +5 -7
  147. data/lib/mongoid/persistence/atomic/push.rb +4 -10
  148. data/lib/mongoid/persistence/atomic/push_all.rb +4 -10
  149. data/lib/mongoid/persistence/atomic/rename.rb +6 -7
  150. data/lib/mongoid/persistence/atomic/sets.rb +5 -7
  151. data/lib/mongoid/persistence/atomic/unset.rb +4 -5
  152. data/lib/mongoid/persistence/deletion.rb +2 -2
  153. data/lib/mongoid/persistence/insertion.rb +10 -16
  154. data/lib/mongoid/persistence/modification.rb +5 -9
  155. data/lib/mongoid/persistence/operations.rb +6 -19
  156. data/lib/mongoid/persistence/operations/embedded/insert.rb +7 -6
  157. data/lib/mongoid/persistence/operations/embedded/remove.rb +5 -5
  158. data/lib/mongoid/persistence/operations/insert.rb +4 -4
  159. data/lib/mongoid/persistence/operations/remove.rb +4 -4
  160. data/lib/mongoid/persistence/operations/update.rb +5 -5
  161. data/lib/mongoid/railtie.rb +26 -11
  162. data/lib/mongoid/railties/database.rake +22 -108
  163. data/lib/mongoid/relations.rb +4 -6
  164. data/lib/mongoid/relations/accessors.rb +119 -19
  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 +3 -3
  175. data/lib/mongoid/relations/builders.rb +19 -16
  176. data/lib/mongoid/relations/builders/embedded/in.rb +5 -5
  177. data/lib/mongoid/relations/builders/embedded/many.rb +12 -12
  178. data/lib/mongoid/relations/builders/embedded/one.rb +6 -6
  179. data/lib/mongoid/relations/builders/nested_attributes/many.rb +8 -8
  180. data/lib/mongoid/relations/builders/nested_attributes/one.rb +4 -4
  181. data/lib/mongoid/relations/builders/referenced/in.rb +4 -4
  182. data/lib/mongoid/relations/builders/referenced/many.rb +5 -5
  183. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +7 -5
  184. data/lib/mongoid/relations/builders/referenced/one.rb +5 -5
  185. data/lib/mongoid/relations/cascading.rb +6 -4
  186. data/lib/mongoid/relations/cascading/delete.rb +3 -5
  187. data/lib/mongoid/relations/cascading/destroy.rb +3 -3
  188. data/lib/mongoid/relations/cascading/nullify.rb +3 -3
  189. data/lib/mongoid/relations/cascading/restrict.rb +37 -0
  190. data/lib/mongoid/relations/constraint.rb +4 -3
  191. data/lib/mongoid/relations/conversions.rb +5 -6
  192. data/lib/mongoid/relations/cyclic.rb +7 -7
  193. data/lib/mongoid/relations/embedded/batchable.rb +346 -0
  194. data/lib/mongoid/relations/embedded/in.rb +23 -12
  195. data/lib/mongoid/relations/embedded/many.rb +99 -161
  196. data/lib/mongoid/relations/embedded/one.rb +25 -14
  197. data/lib/mongoid/relations/macros.rb +105 -61
  198. data/lib/mongoid/relations/many.rb +93 -14
  199. data/lib/mongoid/relations/metadata.rb +200 -45
  200. data/lib/mongoid/relations/nested_builder.rb +3 -5
  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 +60 -31
  205. data/lib/mongoid/relations/referenced/in.rb +40 -15
  206. data/lib/mongoid/relations/referenced/many.rb +117 -132
  207. data/lib/mongoid/relations/referenced/many_to_many.rb +101 -46
  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/reloading.rb +12 -14
  213. data/lib/mongoid/scoping.rb +329 -0
  214. data/lib/mongoid/serialization.rb +8 -27
  215. data/lib/mongoid/sessions.rb +359 -0
  216. data/lib/mongoid/sessions/factory.rb +106 -0
  217. data/lib/mongoid/sessions/mongo_uri.rb +93 -0
  218. data/lib/mongoid/sessions/validators.rb +2 -0
  219. data/lib/mongoid/sessions/validators/storage.rb +49 -0
  220. data/lib/mongoid/sharding.rb +6 -6
  221. data/lib/mongoid/state.rb +6 -7
  222. data/lib/mongoid/threaded.rb +167 -59
  223. data/lib/mongoid/threaded/lifecycle.rb +21 -22
  224. data/lib/mongoid/threaded/sessions.rb +0 -0
  225. data/lib/mongoid/timestamps.rb +1 -1
  226. data/lib/mongoid/timestamps/created.rb +8 -4
  227. data/lib/mongoid/timestamps/timeless.rb +6 -4
  228. data/lib/mongoid/timestamps/updated.rb +3 -3
  229. data/lib/mongoid/unit_of_work.rb +61 -0
  230. data/lib/mongoid/validations.rb +27 -19
  231. data/lib/mongoid/validations/associated.rb +2 -2
  232. data/lib/mongoid/validations/format.rb +2 -2
  233. data/lib/mongoid/validations/presence.rb +31 -5
  234. data/lib/mongoid/validations/uniqueness.rb +9 -12
  235. data/lib/mongoid/version.rb +2 -2
  236. data/lib/mongoid/versioning.rb +25 -26
  237. data/lib/rack/mongoid/middleware/identity_map.rb +3 -3
  238. data/lib/rails/generators/mongoid/config/config_generator.rb +1 -1
  239. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +59 -19
  240. data/lib/rails/generators/mongoid/model/model_generator.rb +7 -7
  241. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +2 -2
  242. data/lib/rails/generators/mongoid/observer/observer_generator.rb +4 -4
  243. data/lib/rails/generators/mongoid_generator.rb +5 -5
  244. data/lib/rails/mongoid.rb +69 -25
  245. metadata +110 -137
  246. checksums.yaml +0 -7
  247. data/lib/config/locales/bg.yml +0 -61
  248. data/lib/config/locales/de.yml +0 -61
  249. data/lib/config/locales/en-GB.yml +0 -64
  250. data/lib/config/locales/es.yml +0 -59
  251. data/lib/config/locales/fr.yml +0 -62
  252. data/lib/config/locales/hi.yml +0 -53
  253. data/lib/config/locales/hu.yml +0 -64
  254. data/lib/config/locales/id.yml +0 -62
  255. data/lib/config/locales/it.yml +0 -59
  256. data/lib/config/locales/ja.yml +0 -57
  257. data/lib/config/locales/kr.yml +0 -54
  258. data/lib/config/locales/nl.yml +0 -61
  259. data/lib/config/locales/pl.yml +0 -59
  260. data/lib/config/locales/pt-BR.yml +0 -60
  261. data/lib/config/locales/pt.yml +0 -60
  262. data/lib/config/locales/ro.yml +0 -66
  263. data/lib/config/locales/ru.yml +0 -61
  264. data/lib/config/locales/sv.yml +0 -60
  265. data/lib/config/locales/vi.yml +0 -62
  266. data/lib/config/locales/zh-CN.yml +0 -53
  267. data/lib/mongoid/collection.rb +0 -157
  268. data/lib/mongoid/collections.rb +0 -120
  269. data/lib/mongoid/collections/master.rb +0 -45
  270. data/lib/mongoid/collections/operations.rb +0 -44
  271. data/lib/mongoid/config/database.rb +0 -181
  272. data/lib/mongoid/config/replset_database.rb +0 -80
  273. data/lib/mongoid/contexts.rb +0 -25
  274. data/lib/mongoid/contexts/enumerable.rb +0 -313
  275. data/lib/mongoid/contexts/enumerable/sort.rb +0 -43
  276. data/lib/mongoid/contexts/mongo.rb +0 -487
  277. data/lib/mongoid/criterion/builder.rb +0 -34
  278. data/lib/mongoid/criterion/complex.rb +0 -84
  279. data/lib/mongoid/criterion/creational.rb +0 -34
  280. data/lib/mongoid/criterion/exclusion.rb +0 -110
  281. data/lib/mongoid/criterion/inclusion.rb +0 -290
  282. data/lib/mongoid/criterion/optional.rb +0 -259
  283. data/lib/mongoid/criterion/selector.rb +0 -177
  284. data/lib/mongoid/cursor.rb +0 -88
  285. data/lib/mongoid/default_scope.rb +0 -36
  286. data/lib/mongoid/errors/invalid_type.rb +0 -25
  287. data/lib/mongoid/extensions/array/deep_copy.rb +0 -25
  288. data/lib/mongoid/extensions/array/deletion.rb +0 -29
  289. data/lib/mongoid/extensions/false_class/equality.rb +0 -26
  290. data/lib/mongoid/extensions/hash/criteria_helpers.rb +0 -47
  291. data/lib/mongoid/extensions/hash/deep_copy.rb +0 -25
  292. data/lib/mongoid/extensions/hash/scoping.rb +0 -25
  293. data/lib/mongoid/extensions/integer/checks.rb +0 -23
  294. data/lib/mongoid/extensions/nil/collectionization.rb +0 -23
  295. data/lib/mongoid/extensions/object/checks.rb +0 -29
  296. data/lib/mongoid/extensions/object/deep_copy.rb +0 -21
  297. data/lib/mongoid/extensions/object/reflections.rb +0 -48
  298. data/lib/mongoid/extensions/object/substitutable.rb +0 -15
  299. data/lib/mongoid/extensions/object/yoda.rb +0 -44
  300. data/lib/mongoid/extensions/object_id/conversions.rb +0 -60
  301. data/lib/mongoid/extensions/proc/scoping.rb +0 -25
  302. data/lib/mongoid/extensions/string/checks.rb +0 -36
  303. data/lib/mongoid/extensions/string/conversions.rb +0 -22
  304. data/lib/mongoid/extensions/string/inflections.rb +0 -118
  305. data/lib/mongoid/extensions/symbol/checks.rb +0 -23
  306. data/lib/mongoid/extensions/symbol/inflections.rb +0 -67
  307. data/lib/mongoid/extensions/true_class/equality.rb +0 -26
  308. data/lib/mongoid/extras.rb +0 -31
  309. data/lib/mongoid/fields/internal/array.rb +0 -77
  310. data/lib/mongoid/fields/internal/big_decimal.rb +0 -63
  311. data/lib/mongoid/fields/internal/bignum.rb +0 -10
  312. data/lib/mongoid/fields/internal/binary.rb +0 -11
  313. data/lib/mongoid/fields/internal/boolean.rb +0 -58
  314. data/lib/mongoid/fields/internal/date.rb +0 -51
  315. data/lib/mongoid/fields/internal/date_time.rb +0 -28
  316. data/lib/mongoid/fields/internal/false_class.rb +0 -10
  317. data/lib/mongoid/fields/internal/fixnum.rb +0 -10
  318. data/lib/mongoid/fields/internal/float.rb +0 -47
  319. data/lib/mongoid/fields/internal/foreign_keys/array.rb +0 -88
  320. data/lib/mongoid/fields/internal/foreign_keys/object.rb +0 -56
  321. data/lib/mongoid/fields/internal/hash.rb +0 -11
  322. data/lib/mongoid/fields/internal/integer.rb +0 -59
  323. data/lib/mongoid/fields/internal/localized.rb +0 -62
  324. data/lib/mongoid/fields/internal/nil_class.rb +0 -53
  325. data/lib/mongoid/fields/internal/object.rb +0 -11
  326. data/lib/mongoid/fields/internal/object_id.rb +0 -46
  327. data/lib/mongoid/fields/internal/range.rb +0 -61
  328. data/lib/mongoid/fields/internal/set.rb +0 -57
  329. data/lib/mongoid/fields/internal/string.rb +0 -42
  330. data/lib/mongoid/fields/internal/symbol.rb +0 -43
  331. data/lib/mongoid/fields/internal/time.rb +0 -23
  332. data/lib/mongoid/fields/internal/time_with_zone.rb +0 -23
  333. data/lib/mongoid/fields/internal/timekeeping.rb +0 -122
  334. data/lib/mongoid/fields/internal/true_class.rb +0 -10
  335. data/lib/mongoid/fields/mappings.rb +0 -42
  336. data/lib/mongoid/fields/serializable.rb +0 -270
  337. data/lib/mongoid/identity.rb +0 -92
  338. data/lib/mongoid/keys.rb +0 -144
  339. data/lib/mongoid/logger.rb +0 -45
  340. data/lib/mongoid/multi_database.rb +0 -36
  341. data/lib/mongoid/named_scope.rb +0 -166
  342. data/lib/mongoid/relations/embedded/atomic.rb +0 -89
  343. data/lib/mongoid/relations/embedded/atomic/operation.rb +0 -63
  344. data/lib/mongoid/relations/embedded/atomic/pull.rb +0 -65
  345. data/lib/mongoid/relations/embedded/atomic/push_all.rb +0 -59
  346. data/lib/mongoid/relations/embedded/atomic/set.rb +0 -61
  347. data/lib/mongoid/relations/embedded/atomic/unset.rb +0 -41
  348. data/lib/mongoid/relations/referenced/batch.rb +0 -73
  349. data/lib/mongoid/relations/referenced/batch/insert.rb +0 -57
  350. data/lib/mongoid/safety.rb +0 -105
  351. data/lib/mongoid/scope.rb +0 -31
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
4
- module Referenced #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
+ module Referenced
5
5
 
6
6
  # This class defines the behaviour for all relations that are a
7
7
  # many-to-many between documents in different collections.
@@ -25,29 +25,51 @@ module Mongoid # :nodoc:
25
25
  #
26
26
  # @since 2.0.0.beta.1
27
27
  def <<(*args)
28
- batched do
29
- [].tap do |ids|
30
- args.flatten.each do |doc|
31
- next unless doc
32
- append(doc)
33
- if persistable? || _creating?
34
- ids.push(doc.id)
35
- doc.save
36
- else
37
- base.send(metadata.foreign_key).push(doc.id)
38
- base.synced[metadata.foreign_key] = false
39
- end
40
- end
28
+ docs = args.flatten
29
+ return concat(docs) if docs.size > 1
30
+ if doc = docs.first
31
+ if !target.include?(doc)
32
+ append(doc)
33
+ base.push(foreign_key, doc.id)
41
34
  if persistable? || _creating?
42
- base.push_all(metadata.foreign_key, ids)
43
- base.synced[metadata.foreign_key] = false
35
+ doc.save
44
36
  end
45
37
  end
46
38
  end
39
+ unsynced(base, foreign_key) and self
47
40
  end
48
- alias :concat :<<
49
41
  alias :push :<<
50
42
 
43
+ # Appends an array of documents to the relation. Performs a batch
44
+ # insert of the documents instead of persisting one at a time.
45
+ #
46
+ # @example Concat with other documents.
47
+ # person.posts.concat([ post_one, post_two ])
48
+ #
49
+ # @param [ Array<Document> ] documents The docs to add.
50
+ #
51
+ # @return [ Array<Document> ] The documents.
52
+ #
53
+ # @since 2.4.0
54
+ def concat(documents)
55
+ ids, inserts = [], []
56
+ documents.each do |doc|
57
+ next if doc.nil? || target.include?(doc)
58
+ append(doc)
59
+ if persistable? || _creating?
60
+ ids.push(doc.id)
61
+ save_or_delay(doc, inserts)
62
+ else
63
+ base.send(foreign_key).push(doc.id) and unsynced(base, foreign_key)
64
+ end
65
+ end
66
+ if persistable? || _creating?
67
+ base.push_all(foreign_key, ids)
68
+ end
69
+ persist_delayed(inserts)
70
+ self
71
+ end
72
+
51
73
  # Build a new document from the attributes and append it to this
52
74
  # relation without saving.
53
75
  #
@@ -72,13 +94,13 @@ module Mongoid # :nodoc:
72
94
  options, type = {}, options
73
95
  end
74
96
 
75
- Factory.build(type || klass, attributes, options).tap do |doc|
76
- base.send(metadata.foreign_key).push(doc.id)
77
- append(doc)
78
- doc.apply_proc_defaults
79
- doc.synced[metadata.inverse_foreign_key] = false
80
- yield(doc) if block_given?
81
- end
97
+ doc = Factory.build(type || klass, attributes, options)
98
+ base.send(foreign_key).push(doc.id)
99
+ append(doc)
100
+ doc.apply_post_processed_defaults
101
+ unsynced(doc, inverse_foreign_key)
102
+ yield(doc) if block_given?
103
+ doc
82
104
  end
83
105
  alias :new :build
84
106
 
@@ -95,12 +117,12 @@ module Mongoid # :nodoc:
95
117
  #
96
118
  # @since 2.1.0
97
119
  def delete(document)
98
- super.tap do |doc|
99
- if doc && persistable?
100
- base.pull(metadata.foreign_key, doc.id)
101
- base.synced[metadata.foreign_key] = false
102
- end
120
+ doc = super
121
+ if doc && persistable?
122
+ base.pull(foreign_key, doc.id)
123
+ unsynced(base, foreign_key)
103
124
  end
125
+ doc
104
126
  end
105
127
 
106
128
  # Removes all associations between the base document and the target
@@ -113,12 +135,12 @@ module Mongoid # :nodoc:
113
135
  # @since 2.0.0.rc.1
114
136
  def nullify
115
137
  unless metadata.forced_nil_inverse?
116
- criteria.pull(metadata.inverse_foreign_key, base.id)
138
+ criteria.pull(inverse_foreign_key, base.id)
117
139
  end
118
140
  if persistable?
119
141
  base.set(
120
- metadata.foreign_key,
121
- base.send(metadata.foreign_key).clear
142
+ foreign_key,
143
+ base.send(foreign_key).clear
122
144
  )
123
145
  end
124
146
  target.clear do |doc|
@@ -142,10 +164,9 @@ module Mongoid # :nodoc:
142
164
  #
143
165
  # @since 2.0.0.rc.1
144
166
  def substitute(replacement)
145
- tap do |proxy|
146
- proxy.purge
147
- proxy.push(replacement.compact.uniq) unless replacement.blank?
148
- end
167
+ purge
168
+ push(replacement.compact.uniq) unless replacement.blank?
169
+ self
149
170
  end
150
171
 
151
172
  # Get a criteria for the documents without the default scoping
@@ -158,7 +179,7 @@ module Mongoid # :nodoc:
158
179
  #
159
180
  # @since 2.4.0
160
181
  def unscoped
161
- klass.unscoped.any_in(:_id => base.send(metadata.foreign_key))
182
+ klass.unscoped.any_in(_id: base.send(foreign_key))
162
183
  end
163
184
 
164
185
  private
@@ -198,7 +219,25 @@ module Mongoid # :nodoc:
198
219
  #
199
220
  # @return [ Criteria ] A new criteria.
200
221
  def criteria
201
- ManyToMany.criteria(metadata, base.send(metadata.foreign_key))
222
+ ManyToMany.criteria(metadata, base.send(foreign_key))
223
+ end
224
+
225
+ # Flag the base as unsynced with respect to the foreign key.
226
+ #
227
+ # @api private
228
+ #
229
+ # @example Flag as unsynced.
230
+ # relation.unsynced(doc, :preference_ids)
231
+ #
232
+ # @param [ Document ] doc The document to flag.
233
+ # @param [ Symbol ] key The key to flag on the document.
234
+ #
235
+ # @return [ true ] true.
236
+ #
237
+ # @since 3.0.0
238
+ def unsynced(doc, key)
239
+ doc.synced[key] = false
240
+ true
202
241
  end
203
242
 
204
243
  class << self
@@ -235,7 +274,7 @@ module Mongoid # :nodoc:
235
274
  #
236
275
  # @since 2.1.0
237
276
  def criteria(metadata, object, type = nil)
238
- metadata.klass.any_in(:_id => object)
277
+ metadata.klass.all_of(_id: { "$in" => object })
239
278
  end
240
279
 
241
280
  # Get the criteria that is used to eager load a relation of this
@@ -245,13 +284,15 @@ module Mongoid # :nodoc:
245
284
  # Proxy.eager_load(metadata, criteria)
246
285
  #
247
286
  # @param [ Metadata ] metadata The relation metadata.
248
- # @param [ Criteria ] criteria The criteria being used.
287
+ # @param [ Array<Object> ] ids The ids of the documents to load.
249
288
  #
250
289
  # @return [ Criteria ] The criteria to eager load the relation.
251
290
  #
252
291
  # @since 2.2.0
253
- def eager_load(metadata, criteria)
254
- raise Errors::EagerLoad.new(metadata.name)
292
+ def eager_load(metadata, ids)
293
+ metadata.klass.any_in(_id: ids).each do |doc|
294
+ IdentityMap.set(doc)
295
+ end
255
296
  end
256
297
 
257
298
  # Returns true if the relation is an embedded one. In this case
@@ -267,6 +308,20 @@ module Mongoid # :nodoc:
267
308
  false
268
309
  end
269
310
 
311
+ # Get the foreign key for the provided name.
312
+ #
313
+ # @example Get the foreign key.
314
+ # Referenced::ManyToMany.foreign_key(:person)
315
+ #
316
+ # @param [ Symbol ] name The name.
317
+ #
318
+ # @return [ String ] The foreign key.
319
+ #
320
+ # @since 3.0.0
321
+ def foreign_key(name)
322
+ "#{name.to_s.singularize}#{foreign_key_suffix}"
323
+ end
324
+
270
325
  # Get the default value for the foreign key.
271
326
  #
272
327
  # @example Get the default.
@@ -297,9 +352,9 @@ module Mongoid # :nodoc:
297
352
  # @example Get the macro.
298
353
  # Referenced::ManyToMany.macro
299
354
  #
300
- # @return [ Symbol ] :references_and_referenced_in_many
355
+ # @return [ Symbol ] :has_and_belongs_to_many
301
356
  def macro
302
- :references_and_referenced_in_many
357
+ :has_and_belongs_to_many
303
358
  end
304
359
 
305
360
  # Return the nested builder that is responsible for generating the documents
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
4
- module Referenced #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
+ module Referenced
5
5
 
6
6
  # This class defines the behaviour for all relations that are a
7
7
  # one-to-one between documents in different collections.
@@ -59,8 +59,7 @@ module Mongoid # :nodoc:
59
59
  save if persisted?
60
60
  end
61
61
  end
62
- return nil unless replacement
63
- One.new(base, replacement, metadata)
62
+ One.new(base, replacement, metadata) if replacement
64
63
  end
65
64
 
66
65
  private
@@ -122,7 +121,18 @@ module Mongoid # :nodoc:
122
121
  #
123
122
  # @since 2.1.0
124
123
  def criteria(metadata, object, type = nil)
125
- metadata.klass.where(metadata.foreign_key => object)
124
+ crit = metadata.klass.where(metadata.foreign_key => object)
125
+
126
+ if metadata.polymorphic?
127
+ crit = crit.where(metadata.type => type.name)
128
+ end
129
+
130
+ inverse_metadata = metadata.inverse_metadata(metadata.klass)
131
+ if inverse_metadata.inverse_of_field
132
+ crit = crit.any_in(inverse_metadata.inverse_of_field => [metadata.name, nil])
133
+ end
134
+
135
+ crit
126
136
  end
127
137
 
128
138
  # Get the criteria that is used to eager load a relation of this
@@ -138,10 +148,7 @@ module Mongoid # :nodoc:
138
148
  #
139
149
  # @since 2.2.0
140
150
  def eager_load(metadata, ids)
141
- klass, foreign_key = metadata.klass, metadata.foreign_key
142
- klass.any_in(foreign_key => ids).each do |doc|
143
- IdentityMap.set_one(doc, foreign_key => doc.send(foreign_key))
144
- end
151
+ eager_load_ids(metadata, ids) { |doc, key| IdentityMap.set_one(doc, key) }
145
152
  end
146
153
 
147
154
  # Returns true if the relation is an embedded one. In this case
@@ -157,6 +164,20 @@ module Mongoid # :nodoc:
157
164
  false
158
165
  end
159
166
 
167
+ # Get the foreign key for the provided name.
168
+ #
169
+ # @example Get the foreign key.
170
+ # Referenced::One.foreign_key(:person)
171
+ #
172
+ # @param [ Symbol ] name The name.
173
+ #
174
+ # @return [ String ] The foreign key.
175
+ #
176
+ # @since 3.0.0
177
+ def foreign_key(name)
178
+ "#{name}#{foreign_key_suffix}"
179
+ end
180
+
160
181
  # Get the default value for the foreign key.
161
182
  #
162
183
  # @example Get the default.
@@ -187,9 +208,9 @@ module Mongoid # :nodoc:
187
208
  # @example Get the macro.
188
209
  # Referenced::One.macro
189
210
  #
190
- # @return [ Symbol ] :references_one.
211
+ # @return [ Symbol ] :has_one.
191
212
  def macro
192
- :references_one
213
+ :has_one
193
214
  end
194
215
 
195
216
  # Return the nested builder that is responsible for generating the documents
@@ -254,7 +275,7 @@ module Mongoid # :nodoc:
254
275
  #
255
276
  # @since 2.1.0
256
277
  def valid_options
257
- [ :as, :autosave, :dependent, :foreign_key ]
278
+ [ :as, :autobuild, :autosave, :dependent, :foreign_key ]
258
279
  end
259
280
 
260
281
  # Get the default validation setting for the relation. Determines if
@@ -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
  # The reflections module provides convenience methods that can retrieve
6
6
  # useful information about associations.
@@ -31,7 +31,7 @@ module Mongoid # :nodoc:
31
31
  self.class.reflect_on_all_associations(*macros)
32
32
  end
33
33
 
34
- module ClassMethods #:nodoc
34
+ module ClassMethods
35
35
 
36
36
  # Returns the relation metadata for the supplied name.
37
37
  #
@@ -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 handles the behaviour for synchronizing foreign keys between
6
6
  # both sides of a many to many relations.
@@ -36,8 +36,6 @@ module Mongoid # :nodoc:
36
36
 
37
37
  # Has the document been synced for the foreign key?
38
38
  #
39
- # @todo Change the sync to be key based.
40
- #
41
39
  # @example Has the document been synced?
42
40
  # document.synced?
43
41
  #
@@ -61,7 +59,7 @@ module Mongoid # :nodoc:
61
59
  #
62
60
  # @since 2.2.1
63
61
  def remove_inverse_keys(meta)
64
- meta.criteria(send(meta.foreign_key)).pull(meta.inverse_foreign_key, id)
62
+ meta.criteria(send(meta.foreign_key), self.class).pull(meta.inverse_foreign_key, id)
65
63
  end
66
64
 
67
65
  # Update the inverse keys for the relation.
@@ -91,15 +89,15 @@ module Mongoid # :nodoc:
91
89
  end
92
90
 
93
91
  unless adds.empty?
94
- meta.criteria(adds).add_to_set(meta.inverse_foreign_key, id)
92
+ meta.criteria(adds, self.class).add_to_set(meta.inverse_foreign_key, id)
95
93
  end
96
94
  unless subs.empty?
97
- meta.criteria(subs).pull(meta.inverse_foreign_key, id)
95
+ meta.criteria(subs, self.class).pull(meta.inverse_foreign_key, id)
98
96
  end
99
97
  end
100
98
  end
101
99
 
102
- module ClassMethods #:nodoc:
100
+ module ClassMethods
103
101
 
104
102
  # Set up the syncing of many to many foreign keys.
105
103
  #
@@ -133,15 +131,14 @@ module Mongoid # :nodoc:
133
131
  #
134
132
  # @since 2.1.0
135
133
  def synced_save(metadata)
136
- tap do
137
- set_callback(
138
- :save,
139
- :after,
140
- :if => lambda { |doc| doc.syncable?(metadata) }
141
- ) do |doc|
142
- doc.update_inverse_keys(metadata)
143
- end
134
+ set_callback(
135
+ :save,
136
+ :after,
137
+ if: ->(doc){ doc.syncable?(metadata) }
138
+ ) do |doc|
139
+ doc.update_inverse_keys(metadata)
144
140
  end
141
+ self
145
142
  end
146
143
 
147
144
  # Set up the sync of inverse keys that needs to happen on a destroy.
@@ -155,14 +152,13 @@ module Mongoid # :nodoc:
155
152
  #
156
153
  # @since 2.2.1
157
154
  def synced_destroy(metadata)
158
- tap do
159
- set_callback(
160
- :destroy,
161
- :after
162
- ) do |doc|
163
- doc.remove_inverse_keys(metadata)
164
- end
155
+ set_callback(
156
+ :destroy,
157
+ :after
158
+ ) do |doc|
159
+ doc.remove_inverse_keys(metadata)
165
160
  end
161
+ self
166
162
  end
167
163
  end
168
164
  end
@@ -1,22 +1,22 @@
1
1
  # encoding: utf-8
2
- module Mongoid #:nodoc:
3
- module Relations #:nodoc:
4
- module Targets #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
+ module Targets
5
5
 
6
6
  # This class is the wrapper for all relational associations that have a
7
- # target that can be a criteria or array of loaded documents. This
7
+ # target that can be a criteria or array of _loaded documents. This
8
8
  # handles both cases or a combination of the two.
9
9
  class Enumerable
10
10
  include ::Enumerable
11
11
 
12
12
  # The three main instance variables are collections of documents.
13
13
  #
14
- # @attribute [rw] added Documents that have been appended.
15
- # @attribute [rw] loaded Persisted documents that have been loaded.
16
- # @attribute [rw] unloaded A criteria representing persisted docs.
17
- attr_accessor :added, :loaded, :unloaded
14
+ # @attribute [rw] _added Documents that have been appended.
15
+ # @attribute [rw] _loaded Persisted documents that have been _loaded.
16
+ # @attribute [rw] _unloaded A criteria representing persisted docs.
17
+ attr_accessor :_added, :_loaded, :_unloaded
18
18
 
19
- delegate :===, :is_a?, :kind_of?, :to => :added
19
+ delegate :===, :is_a?, :kind_of?, to: []
20
20
 
21
21
  # Check if the enumerable is equal to the other object.
22
22
  #
@@ -44,7 +44,8 @@ module Mongoid #:nodoc:
44
44
  #
45
45
  # @since 2.1.0
46
46
  def <<(document)
47
- added.push(document)
47
+ _added[document.id] = document
48
+ self
48
49
  end
49
50
  alias :push :<<
50
51
 
@@ -59,14 +60,14 @@ module Mongoid #:nodoc:
59
60
  # doc.unbind
60
61
  # end
61
62
  #
62
- # @return [ Array<Document> ] The cleared out added docs.
63
+ # @return [ Array<Document> ] The cleared out _added docs.
63
64
  #
64
65
  # @since 2.1.0
65
66
  def clear
66
67
  if block_given?
67
68
  in_memory { |doc| yield(doc) }
68
69
  end
69
- loaded.clear and added.clear
70
+ _loaded.clear and _added.clear
70
71
  end
71
72
 
72
73
  # Clones each document in the enumerable.
@@ -94,15 +95,15 @@ module Mongoid #:nodoc:
94
95
  #
95
96
  # @since 2.1.0
96
97
  def delete(document)
97
- (loaded.delete(document) || added.delete(document)).tap do |doc|
98
- unless doc
99
- if unloaded && unloaded.where(:_id => document.id).exists?
100
- yield(document) if block_given?
101
- return document
102
- end
98
+ doc = (_loaded.delete(document.id) || _added.delete(document.id))
99
+ unless doc
100
+ if _unloaded && _unloaded.where(_id: document.id).exists?
101
+ yield(document) if block_given?
102
+ return document
103
103
  end
104
- yield(doc) if block_given?
105
104
  end
105
+ yield(doc) if block_given?
106
+ doc
106
107
  end
107
108
 
108
109
  # Deletes every document in the enumerable for where the block returns
@@ -120,50 +121,52 @@ module Mongoid #:nodoc:
120
121
  # @since 2.1.0
121
122
  def delete_if(&block)
122
123
  load_all!
123
- tap do
124
- loaded.delete_if(&block)
125
- added.delete_if(&block)
124
+ deleted = in_memory.select(&block)
125
+ deleted.each do |doc|
126
+ _loaded.delete(doc.id)
127
+ _added.delete(doc.id)
126
128
  end
129
+ self
127
130
  end
128
131
 
129
132
  # Iterating over this enumerable has to handle a few different
130
133
  # scenarios.
131
134
  #
132
- # If the enumerable has its criteria loaded into memory then it yields
133
- # to all the loaded docs and all the added docs.
135
+ # If the enumerable has its criteria _loaded into memory then it yields
136
+ # to all the _loaded docs and all the _added docs.
134
137
  #
135
- # If the enumerable has not loaded the criteria then it iterates over
138
+ # If the enumerable has not _loaded the criteria then it iterates over
136
139
  # the cursor while loading the documents and then iterates over the
137
- # added docs.
140
+ # _added docs.
138
141
  #
139
142
  # @example Iterate over the enumerable.
140
143
  # enumerable.each do |doc|
141
144
  # puts doc
142
145
  # end
143
146
  #
144
- # @return [ true ] That the enumerable is now loaded.
147
+ # @return [ true ] That the enumerable is now _loaded.
145
148
  #
146
149
  # @since 2.1.0
147
150
  def each
148
- if loaded?
149
- loaded.each do |doc|
151
+ if _loaded?
152
+ _loaded.each_pair do |id, doc|
150
153
  yield(doc)
151
154
  end
152
155
  else
153
- unloaded.each do |doc|
154
- document = added.delete_one(doc) || loaded.delete_one(doc) || doc
156
+ _unloaded.each do |doc|
157
+ document = _added.delete(doc.id) || _loaded.delete(doc.id) || doc
155
158
  yield(document)
156
- loaded.push(document)
159
+ _loaded[document.id] = document
157
160
  end
158
161
  end
159
- added.each do |doc|
162
+ _added.each_pair do |id, doc|
160
163
  yield(doc)
161
164
  end
162
165
  @executed = true
163
166
  end
164
167
 
165
168
  # Is the enumerable empty? Will determine if the count is zero based on
166
- # whether or not it is loaded.
169
+ # whether or not it is _loaded.
167
170
  #
168
171
  # @example Is the enumerable empty?
169
172
  # enumerable.empty?
@@ -172,10 +175,10 @@ module Mongoid #:nodoc:
172
175
  #
173
176
  # @since 2.1.0
174
177
  def empty?
175
- if loaded?
178
+ if _loaded?
176
179
  in_memory.count == 0
177
180
  else
178
- unloaded.count + added.count == 0
181
+ _unloaded.count + _added.count == 0
179
182
  end
180
183
  end
181
184
 
@@ -189,7 +192,7 @@ module Mongoid #:nodoc:
189
192
  #
190
193
  # @since 2.1.0
191
194
  def first
192
- added.first || (loaded? ? loaded.first : unloaded.first)
195
+ matching_document(:first)
193
196
  end
194
197
 
195
198
  # Initialize the new enumerable either with a criteria or an array.
@@ -205,12 +208,31 @@ module Mongoid #:nodoc:
205
208
  # @since 2.1.0
206
209
  def initialize(target)
207
210
  if target.is_a?(Criteria)
208
- @added, @loaded, @unloaded = [], [], target
211
+ @_added, @executed, @_loaded, @_unloaded = {}, false, {}, target
209
212
  else
210
- @added, @executed, @loaded = [], true, target
213
+ @_added, @executed = {}, true
214
+ @_loaded = target.inject({}) do |_target, doc|
215
+ _target[doc.id] = doc
216
+ _target
217
+ end
211
218
  end
212
219
  end
213
220
 
221
+ # Does the target include the provided document?
222
+ #
223
+ # @example Does the target include the document?
224
+ # enumerable.include?(document)
225
+ #
226
+ # @param [ Document ] doc The document to check.
227
+ #
228
+ # @return [ true, false ] If the document is in the target.
229
+ #
230
+ # @since 3.0.0
231
+ def include?(doc)
232
+ return super unless _unloaded
233
+ _unloaded.where(_id: doc.id).exists? || _added.has_key?(doc.id)
234
+ end
235
+
214
236
  # Inspection will just inspect the entries for nice array-style
215
237
  # printing.
216
238
  #
@@ -224,8 +246,8 @@ module Mongoid #:nodoc:
224
246
  entries.inspect
225
247
  end
226
248
 
227
- # Return all the documents in the enumerable that have been loaded or
228
- # added.
249
+ # Return all the documents in the enumerable that have been _loaded or
250
+ # _added.
229
251
  #
230
252
  # @note When passed a block it yields to each document.
231
253
  #
@@ -236,9 +258,9 @@ module Mongoid #:nodoc:
236
258
  #
237
259
  # @since 2.1.0
238
260
  def in_memory
239
- (loaded + added).tap do |docs|
240
- docs.each { |doc| yield(doc) } if block_given?
241
- end
261
+ docs = (_loaded.values + _added.values)
262
+ docs.each { |doc| yield(doc) } if block_given?
263
+ docs
242
264
  end
243
265
 
244
266
  # Get the last document in the enumerable. Will check the new
@@ -251,7 +273,7 @@ module Mongoid #:nodoc:
251
273
  #
252
274
  # @since 2.1.0
253
275
  def last
254
- added.last || (loaded? ? loaded.last : unloaded.last)
276
+ matching_document(:last)
255
277
  end
256
278
 
257
279
  # Loads all the documents in the enumerable from the database.
@@ -259,21 +281,21 @@ module Mongoid #:nodoc:
259
281
  # @example Load all the documents.
260
282
  # enumerable.load_all!
261
283
  #
262
- # @return [ true ] That the enumerable is loaded.
284
+ # @return [ true ] That the enumerable is _loaded.
263
285
  #
264
286
  # @since 2.1.0
265
287
  alias :load_all! :entries
266
288
 
267
- # Has the enumerable been loaded? This will be true if the criteria has
289
+ # Has the enumerable been _loaded? This will be true if the criteria has
268
290
  # been executed or we manually load the entire thing.
269
291
  #
270
- # @example Is the enumerable loaded?
271
- # enumerable.loaded?
292
+ # @example Is the enumerable _loaded?
293
+ # enumerable._loaded?
272
294
  #
273
- # @return [ true, false ] If the enumerable has been loaded.
295
+ # @return [ true, false ] If the enumerable has been _loaded.
274
296
  #
275
297
  # @since 2.1.0
276
- def loaded?
298
+ def _loaded?
277
299
  !!@executed
278
300
  end
279
301
 
@@ -286,7 +308,7 @@ module Mongoid #:nodoc:
286
308
  #
287
309
  # @since 2.1.0
288
310
  def reset
289
- loaded.clear and added.clear
311
+ _loaded.clear and _added.clear
290
312
  @executed = false
291
313
  end
292
314
 
@@ -316,11 +338,11 @@ module Mongoid #:nodoc:
316
338
  #
317
339
  # @since 2.1.0
318
340
  def size
319
- count = (unloaded ? unloaded.count : loaded.count)
341
+ count = (_unloaded ? _unloaded.count : _loaded.count)
320
342
  if count.zero?
321
- count + added.count
343
+ count + _added.count
322
344
  else
323
- count + added.count{ |d| d.new_record? }
345
+ count + _added.values.count{ |d| d.new_record? }
324
346
  end
325
347
  end
326
348
  alias :length :size
@@ -332,7 +354,7 @@ module Mongoid #:nodoc:
332
354
  #
333
355
  # @param [ Hash ] options Optional parameters.
334
356
  #
335
- # @return [ String ] The entries all loaded as a string.
357
+ # @return [ String ] The entries all _loaded as a string.
336
358
  #
337
359
  # @since 2.2.0
338
360
  def to_json(options = {})
@@ -346,7 +368,7 @@ module Mongoid #:nodoc:
346
368
  #
347
369
  # @param [ Hash ] options Optional parameters.
348
370
  #
349
- # @return [ Hash ] The entries all loaded as a hash.
371
+ # @return [ Hash ] The entries all _loaded as a hash.
350
372
  #
351
373
  # @since 2.2.0
352
374
  def as_json(options = {})
@@ -372,6 +394,13 @@ module Mongoid #:nodoc:
372
394
  def method_missing(name, *args, &block)
373
395
  entries.send(name, *args, &block)
374
396
  end
397
+
398
+ def matching_document(location)
399
+ _loaded.try(:values).try(location) ||
400
+ _added[_unloaded.try(location).try(:id)] ||
401
+ _unloaded.try(location) ||
402
+ _added.values.try(location)
403
+ end
375
404
  end
376
405
  end
377
406
  end