mongoid 2.8.1 → 3.0.0.rc

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 (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,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,32 @@ 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
+ cleared = false
164
+ klass, foreign_key = metadata.klass, metadata.foreign_key
165
+ klass.any_in(foreign_key => ids).each do |doc|
166
+ selector = { foreign_key => doc.send(foreign_key) }
167
+ unless cleared
168
+ IdentityMap.clear_many(klass, selector)
169
+ cleared = true
170
+ end
171
+ yield(doc, foreign_key => doc.send(foreign_key))
172
+ end
173
+ end
145
174
  end
146
175
  end
147
176
  end
@@ -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 handles all behaviour for relations that are either
7
7
  # one-to-many or one-to-one, where the foreign key is store on this side
@@ -25,6 +25,18 @@ module Mongoid # :nodoc:
25
25
  end
26
26
  end
27
27
 
28
+ # Removes the association between the base document and the target
29
+ # document by deleting the foreign key and the reference, orphaning
30
+ # the target document in the process.
31
+ #
32
+ # @example Nullify the relation.
33
+ # person.game.nullify
34
+ #
35
+ def nullify
36
+ unbind_one
37
+ target.save
38
+ end
39
+
28
40
  # Substitutes the supplied target documents for the existing document
29
41
  # in the relation.
30
42
  #
@@ -38,12 +50,11 @@ module Mongoid # :nodoc:
38
50
  #
39
51
  # @since 2.0.0.rc.1
40
52
  def substitute(replacement)
41
- tap do |proxy|
42
- proxy.unbind_one
43
- return nil unless replacement
44
- proxy.target = replacement
45
- proxy.bind_one
46
- end
53
+ unbind_one
54
+ return nil unless replacement
55
+ self.target = replacement
56
+ bind_one
57
+ self
47
58
  end
48
59
 
49
60
  private
@@ -107,7 +118,7 @@ module Mongoid # :nodoc:
107
118
  #
108
119
  # @since 2.1.0
109
120
  def criteria(metadata, object, type = nil)
110
- type.where(:_id => object)
121
+ type.where(_id: object)
111
122
  end
112
123
 
113
124
  # Get the criteria that is used to eager load a relation of this
@@ -124,8 +135,8 @@ module Mongoid # :nodoc:
124
135
  # @since 2.2.0
125
136
  def eager_load(metadata, ids)
126
137
  raise Errors::EagerLoad.new(metadata.name) if metadata.polymorphic?
127
- klass, foreign_key = metadata.klass, metadata.foreign_key
128
- klass.any_in("_id" => ids).each do |doc|
138
+ klass, _ = metadata.klass, metadata.foreign_key
139
+ klass.any_in("_id" => ids.uniq).each do |doc|
129
140
  IdentityMap.set(doc)
130
141
  end
131
142
  end
@@ -143,6 +154,20 @@ module Mongoid # :nodoc:
143
154
  false
144
155
  end
145
156
 
157
+ # Get the foreign key for the provided name.
158
+ #
159
+ # @example Get the foreign key.
160
+ # Referenced::In.foreign_key(:person)
161
+ #
162
+ # @param [ Symbol ] name The name.
163
+ #
164
+ # @return [ String ] The foreign key.
165
+ #
166
+ # @since 3.0.0
167
+ def foreign_key(name)
168
+ "#{name}#{foreign_key_suffix}"
169
+ end
170
+
146
171
  # Get the default value for the foreign key.
147
172
  #
148
173
  # @example Get the default.
@@ -173,9 +198,9 @@ module Mongoid # :nodoc:
173
198
  # @example Get the macro.
174
199
  # Referenced::In.macro
175
200
  #
176
- # @return [ Symbol ] :referenced_in
201
+ # @return [ Symbol ] :belongs_to
177
202
  def macro
178
- :referenced_in
203
+ :belongs_to
179
204
  end
180
205
 
181
206
  # Return the nested builder that is responsible for generating the documents
@@ -240,7 +265,7 @@ module Mongoid # :nodoc:
240
265
  #
241
266
  # @since 2.1.0
242
267
  def valid_options
243
- [ :autosave, :foreign_key, :index, :polymorphic, :touch ]
268
+ [ :autobuild, :autosave, :dependent, :foreign_key, :index, :polymorphic, :touch ]
244
269
  end
245
270
 
246
271
  # Get the default validation setting for the relation. Determines if
@@ -1,15 +1,14 @@
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-many between documents in different collections.
8
8
  class Many < Relations::Many
9
- include Batch
10
9
 
11
- delegate :count, :to => :criteria
12
- delegate :first, :in_memory, :last, :reset, :uniq, :to => :target
10
+ delegate :count, to: :criteria
11
+ delegate :first, :in_memory, :last, :reset, :uniq, to: :target
13
12
 
14
13
  # Appends a document or array of documents to the relation. Will set
15
14
  # the parent and update the index in the process.
@@ -35,17 +34,13 @@ module Mongoid #:nodoc:
35
34
  append(doc)
36
35
  doc.save if persistable? && !_assigning? && !doc.validated?
37
36
  end
37
+ self
38
38
  end
39
39
  alias :push :<<
40
40
 
41
41
  # Appends an array of documents to the relation. Performs a batch
42
42
  # insert of the documents instead of persisting one at a time.
43
43
  #
44
- # @note When performing batch inserts the *after* callbacks will get
45
- # executed before the documents have actually been persisted to the
46
- # database due to an issue with Active Support's callback system - we
47
- # cannot explicitly fire the after callbacks by themselves.
48
- #
49
44
  # @example Concat with other documents.
50
45
  # person.posts.concat([ post_one, post_two ])
51
46
  #
@@ -55,13 +50,14 @@ module Mongoid #:nodoc:
55
50
  #
56
51
  # @since 2.4.0
57
52
  def concat(documents)
58
- batched do
59
- documents.each do |doc|
60
- next unless doc
61
- append(doc)
62
- doc.save if persistable?
63
- end
53
+ inserts = []
54
+ documents.each do |doc|
55
+ next unless doc
56
+ append(doc)
57
+ save_or_delay(doc, inserts) if persistable?
64
58
  end
59
+ persist_delayed(inserts)
60
+ self
65
61
  end
66
62
 
67
63
  # Build a new document from the attributes and append it to this
@@ -87,66 +83,15 @@ module Mongoid #:nodoc:
87
83
  options, type = {}, options
88
84
  end
89
85
 
90
- Factory.build(type || klass, attributes, options).tap do |doc|
91
- append(doc)
92
- doc.apply_proc_defaults
93
- yield(doc) if block_given?
94
- doc.run_callbacks(:build) { doc }
95
- end
86
+ doc = Factory.build(type || klass, attributes, options)
87
+ append(doc)
88
+ doc.apply_post_processed_defaults
89
+ yield(doc) if block_given?
90
+ doc.run_callbacks(:build) { doc }
91
+ doc
96
92
  end
97
93
  alias :new :build
98
94
 
99
- # Creates a new document on the references many relation. This will
100
- # save the document if the parent has been persisted.
101
- #
102
- # @example Create and save the new document.
103
- # person.posts.create(:text => "Testing")
104
- #
105
- # @overload create(attributes = nil, options = {}, type = nil)
106
- # @param [ Hash ] attributes The attributes to create with.
107
- # @param [ Hash ] options The scoped assignment options.
108
- # @param [ Class ] type The optional type of document to create.
109
- #
110
- # @overload create(attributes = nil, type = nil)
111
- # @param [ Hash ] attributes The attributes to create with.
112
- # @param [ Class ] type The optional type of document to create.
113
- #
114
- # @return [ Document ] The newly created document.
115
- #
116
- # @since 2.0.0.beta.1
117
- def create(attributes = nil, options = {}, type = nil, &block)
118
- build(attributes, options, type, &block).tap do |doc|
119
- base.persisted? ? doc.save : raise_unsaved(doc)
120
- end
121
- end
122
-
123
- # Creates a new document on the references many relation. This will
124
- # save the document if the parent has been persisted and will raise an
125
- # error if validation fails.
126
- #
127
- # @example Create and save the new document.
128
- # person.posts.create!(:text => "Testing")
129
- #
130
- # @overload create!(attributes = nil, options = {}, type = nil)
131
- # @param [ Hash ] attributes The attributes to create with.
132
- # @param [ Hash ] options The scoped assignment options.
133
- # @param [ Class ] type The optional type of document to create.
134
- #
135
- # @overload create!(attributes = nil, type = nil)
136
- # @param [ Hash ] attributes The attributes to create with.
137
- # @param [ Class ] type The optional type of document to create.
138
- #
139
- # @raise [ Errors::Validations ] If validation failed.
140
- #
141
- # @return [ Document ] The newly created document.
142
- #
143
- # @since 2.0.0.beta.1
144
- def create!(attributes = nil, options = {}, type = nil, &block)
145
- build(attributes, options, type, &block).tap do |doc|
146
- base.persisted? ? doc.save! : raise_unsaved(doc)
147
- end
148
- end
149
-
150
95
  # Delete the document from the relation. This will set the foreign key
151
96
  # on the document to nil. If the dependent options on the relation are
152
97
  # :delete or :destroy the appropriate removal will occur.
@@ -175,7 +120,7 @@ module Mongoid #:nodoc:
175
120
  # person.posts.delete_all
176
121
  #
177
122
  # @example Conditonally delete all documents in the relation.
178
- # person.posts.delete_all(:conditions => { :title => "Testing" })
123
+ # person.posts.delete_all({ :title => "Testing" })
179
124
  #
180
125
  # @param [ Hash ] conditions Optional conditions to delete with.
181
126
  #
@@ -193,7 +138,7 @@ module Mongoid #:nodoc:
193
138
  # person.posts.destroy_all
194
139
  #
195
140
  # @example Conditonally destroy all documents in the relation.
196
- # person.posts.destroy_all(:conditions => { :title => "Testing" })
141
+ # person.posts.destroy_all({ :title => "Testing" })
197
142
  #
198
143
  # @param [ Hash ] conditions Optional conditions to destroy with.
199
144
  #
@@ -230,27 +175,13 @@ module Mongoid #:nodoc:
230
175
  # @example Find by multiple ids.
231
176
  # person.posts.find([ BSON::ObjectId.new, BSON::ObjectId.new ])
232
177
  #
233
- # @example Conditionally find all matching documents.
234
- # person.posts.find(:all, :conditions => { :title => "Sir" })
235
- #
236
- # @example Conditionally find the first document.
237
- # person.posts.find(:first, :conditions => { :title => "Sir" })
238
- #
239
- # @example Conditionally find the last document.
240
- # person.posts.find(:last, :conditions => { :title => "Sir" })
241
- #
242
- # @note This will keep matching documents in memory for iteration
243
- # later.
244
- #
245
- # @param [ Moped::BSON::ObjectId, Array<Moped::BSON::ObjectId> ] arg The ids.
178
+ # @param [ BSON::ObjectId, Array<BSON::ObjectId> ] arg The ids.
246
179
  #
247
180
  # @return [ Document, Criteria ] The matching document(s).
248
181
  #
249
182
  # @since 2.0.0.beta.1
250
183
  def find(*args)
251
- matching = criteria.find(*args)
252
- Array(matching).each { |doc| target.push(doc) }
253
- matching
184
+ criteria.find(*args)
254
185
  end
255
186
 
256
187
  # Instantiate a new references_many relation. Will set the foreign key
@@ -279,7 +210,7 @@ module Mongoid #:nodoc:
279
210
  #
280
211
  # @since 2.0.0.rc.1
281
212
  def nullify
282
- criteria.update(metadata.foreign_key => nil)
213
+ criteria.update(foreign_key => nil)
283
214
  target.clear do |doc|
284
215
  unbind_one(doc)
285
216
  end
@@ -321,19 +252,18 @@ module Mongoid #:nodoc:
321
252
  #
322
253
  # @since 2.0.0.rc.1
323
254
  def substitute(replacement)
324
- tap do |proxy|
325
- if replacement
326
- new_docs, docs = replacement.compact.uniq, []
327
- new_ids = new_docs.map { |doc| doc.id }
328
- remove_not_in(new_ids)
329
- new_docs.each do |doc|
330
- docs.push(doc) if doc.send(metadata.foreign_key) != base.id
331
- end
332
- proxy.concat(docs)
333
- else
334
- proxy.purge
255
+ if replacement
256
+ new_docs, docs = replacement.compact, []
257
+ new_ids = new_docs.map { |doc| doc.id }
258
+ remove_not_in(new_ids)
259
+ new_docs.each do |doc|
260
+ docs.push(doc) if doc.send(foreign_key) != base.id
335
261
  end
262
+ concat(docs)
263
+ else
264
+ purge
336
265
  end
266
+ self
337
267
  end
338
268
 
339
269
  # Get a criteria for the documents without the default scoping
@@ -347,7 +277,7 @@ module Mongoid #:nodoc:
347
277
  # @since 2.4.0
348
278
  def unscoped
349
279
  klass.unscoped.where(
350
- metadata.foreign_key => Conversions.flag(base.id, metadata)
280
+ foreign_key => Conversions.flag(base.id, metadata)
351
281
  )
352
282
  end
353
283
 
@@ -404,7 +334,7 @@ module Mongoid #:nodoc:
404
334
  #
405
335
  # @since 2.0.0.beta.1
406
336
  def criteria
407
- Many.criteria(metadata, Conversions.flag(base.id, metadata))
337
+ Many.criteria(metadata, Conversions.flag(base.id, metadata), base.class)
408
338
  end
409
339
 
410
340
  # Perform the necessary cascade operations for documents that just got
@@ -450,6 +380,27 @@ module Mongoid #:nodoc:
450
380
  end
451
381
  end
452
382
 
383
+ # Persist all the delayed batch inserts.
384
+ #
385
+ # @api private
386
+ #
387
+ # @example Persist the delayed batch inserts.
388
+ # relation.persist_delayed([ doc ])
389
+ #
390
+ # @param [ Array<Document> ] inserts The delayed inserts.
391
+ #
392
+ # @since 3.0.0
393
+ def persist_delayed(inserts)
394
+ if inserts.any?
395
+ collection.insert(inserts.map(&:as_document))
396
+ inserts.each do |doc|
397
+ doc.new_record = false
398
+ doc.run_after_callbacks(:create, :save)
399
+ doc.post_persist
400
+ end
401
+ end
402
+ end
403
+
453
404
  # Are we able to persist this relation?
454
405
  #
455
406
  # @example Can we persist the relation?
@@ -469,7 +420,7 @@ module Mongoid #:nodoc:
469
420
  # person.posts.delete_all
470
421
  #
471
422
  # @example Conditonally delete all documents in the relation.
472
- # person.posts.delete_all(:conditions => { :title => "Testing" })
423
+ # person.posts.delete_all({ :title => "Testing" })
473
424
  #
474
425
  # @param [ Hash ] conditions Optional conditions to delete with.
475
426
  # @param [ Symbol ] The deletion method to call.
@@ -478,21 +429,19 @@ module Mongoid #:nodoc:
478
429
  #
479
430
  # @since 2.1.0
480
431
  def remove_all(conditions = nil, method = :delete_all)
481
- selector = (conditions || {})[:conditions] || {}
482
- klass.send(method, :conditions => selector.merge!(criteria.selector)).tap do
483
- target.delete_if do |doc|
484
- if doc.matches?(selector)
485
- unbind_one(doc) and true
486
- end
432
+ selector = conditions || {}
433
+ removed = klass.send(method, selector.merge!(criteria.selector))
434
+ target.delete_if do |doc|
435
+ if doc.matches?(selector)
436
+ unbind_one(doc) and true
487
437
  end
488
438
  end
439
+ removed
489
440
  end
490
441
 
491
442
  # Remove all the documents in the proxy that do not have the provided
492
443
  # ids.
493
444
  #
494
- # @todo: Durran: Refactor 3.0. Temp for bug fix in 2.4.
495
- #
496
445
  # @example Remove all documents without the ids.
497
446
  # proxy.remove_not_in([ id ])
498
447
  #
@@ -500,17 +449,16 @@ module Mongoid #:nodoc:
500
449
  #
501
450
  # @since 2.4.0
502
451
  def remove_not_in(ids)
503
- removed = criteria.not_in(:_id => ids)
452
+ removed = criteria.not_in(_id: ids)
504
453
  if metadata.destructive?
505
454
  removed.delete_all
506
455
  else
507
- removed.update(metadata.foreign_key => nil)
456
+ removed.update(foreign_key => nil)
508
457
  end
509
458
  in_memory.each do |doc|
510
459
  if !ids.include?(doc.id)
511
460
  unbind_one(doc)
512
- added.try { |p| p.delete_one(doc) }
513
- loaded.try { |p| p.delete_one(doc) }
461
+ target.delete(doc)
514
462
  if metadata.destructive?
515
463
  doc.destroyed = true
516
464
  end
@@ -518,6 +466,27 @@ module Mongoid #:nodoc:
518
466
  end
519
467
  end
520
468
 
469
+ # Save a persisted document immediately or delay a new document for
470
+ # batch insert.
471
+ #
472
+ # @api private
473
+ #
474
+ # @example Save or delay the document.
475
+ # relation.save_or_delay(doc, [])
476
+ #
477
+ # @param [ Document ] doc The document.
478
+ # @param [ Array<Document> ] inserts The inserts.
479
+ #
480
+ # @since 3.0.0
481
+ def save_or_delay(doc, inserts)
482
+ if doc.new_record? && doc.valid?(:create)
483
+ inserts.push(doc)
484
+ doc.run_before_callbacks(:save, :create)
485
+ else
486
+ doc.save
487
+ end
488
+ end
489
+
521
490
  class << self
522
491
 
523
492
  # Return the builder that is responsible for generating the documents
@@ -551,7 +520,18 @@ module Mongoid #:nodoc:
551
520
  #
552
521
  # @since 2.1.0
553
522
  def criteria(metadata, object, type = nil)
554
- metadata.klass.where(metadata.foreign_key => object)
523
+ crit = metadata.klass.where(metadata.foreign_key => object)
524
+
525
+ if metadata.polymorphic?
526
+ crit = crit.where(metadata.type => type.name)
527
+ end
528
+
529
+ inverse_metadata = metadata.inverse_metadata(metadata.klass)
530
+ if inverse_metadata && inverse_metadata.inverse_of_field
531
+ crit = crit.any_in(inverse_metadata.inverse_of_field => [metadata.name, nil])
532
+ end
533
+
534
+ crit
555
535
  end
556
536
 
557
537
  # Eager load the relation based on the criteria.
@@ -566,16 +546,7 @@ module Mongoid #:nodoc:
566
546
  #
567
547
  # @since 2.2.0
568
548
  def eager_load(metadata, ids)
569
- cleared = false
570
- klass, foreign_key = metadata.klass, metadata.foreign_key
571
- klass.any_in(foreign_key => ids).each do |doc|
572
- base_id = doc.send(foreign_key)
573
- unless cleared
574
- IdentityMap.clear_many(klass, foreign_key => base_id)
575
- cleared = true
576
- end
577
- IdentityMap.set_many(doc, foreign_key => base_id)
578
- end
549
+ eager_load_ids(metadata, ids) { |doc, key| IdentityMap.set_many(doc, key) }
579
550
  end
580
551
 
581
552
  # Returns true if the relation is an embedded one. In this case
@@ -591,6 +562,20 @@ module Mongoid #:nodoc:
591
562
  false
592
563
  end
593
564
 
565
+ # Get the foreign key for the provided name.
566
+ #
567
+ # @example Get the foreign key.
568
+ # Referenced::Many.foreign_key(:person)
569
+ #
570
+ # @param [ Symbol ] name The name.
571
+ #
572
+ # @return [ String ] The foreign key.
573
+ #
574
+ # @since 3.0.0
575
+ def foreign_key(name)
576
+ "#{name}#{foreign_key_suffix}"
577
+ end
578
+
594
579
  # Get the default value for the foreign key.
595
580
  #
596
581
  # @example Get the default.
@@ -621,9 +606,9 @@ module Mongoid #:nodoc:
621
606
  # @example Get the macro.
622
607
  # Referenced::Many.macro
623
608
  #
624
- # @return [ Symbol ] :references_many
609
+ # @return [ Symbol ] :has_many
625
610
  def macro
626
- :references_many
611
+ :has_many
627
612
  end
628
613
 
629
614
  # Return the nested builder that is responsible for generating the documents