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
@@ -2,9 +2,10 @@
2
2
  require "mongoid/relations/cascading/delete"
3
3
  require "mongoid/relations/cascading/destroy"
4
4
  require "mongoid/relations/cascading/nullify"
5
+ require "mongoid/relations/cascading/restrict"
5
6
 
6
- module Mongoid # :nodoc:
7
- module Relations #:nodoc:
7
+ module Mongoid
8
+ module Relations
8
9
 
9
10
  # This module defines the behaviour for setting up cascading deletes and
10
11
  # nullifies for relations, and how to delegate to the approriate strategy.
@@ -33,7 +34,7 @@ module Mongoid # :nodoc:
33
34
  end
34
35
  end
35
36
 
36
- module ClassMethods #:nodoc:
37
+ module ClassMethods
37
38
 
38
39
  # Attempt to add the cascading information for the document to know how
39
40
  # to handle associated documents on a removal.
@@ -47,7 +48,8 @@ module Mongoid # :nodoc:
47
48
  #
48
49
  # @since 2.0.0.rc.1
49
50
  def cascade(metadata)
50
- tap { self.cascades += [ metadata.name.to_s ] if metadata.dependent? }
51
+ cascades.push(metadata.name.to_s) if metadata.dependent?
52
+ self
51
53
  end
52
54
  end
53
55
  end
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
4
- module Cascading #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
+ module Cascading
5
5
  class Delete
6
6
 
7
7
  attr_accessor :document, :relation, :metadata
@@ -32,9 +32,7 @@ module Mongoid # :nodoc:
32
32
  def cascade
33
33
  if relation
34
34
  if relation.cascades.empty?
35
- safety = Threaded.safety_options
36
35
  relation.clear
37
- Threaded.safety_options = safety
38
36
  else
39
37
  ::Array.wrap(relation).each { |doc| doc.delete }
40
38
  end
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
4
- module Cascading #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
+ module Cascading
5
5
  class Destroy
6
6
 
7
7
  attr_accessor :document, :relation, :metadata
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
4
- module Cascading #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
+ module Cascading
5
5
  class Nullify
6
6
 
7
7
  attr_accessor :document, :relation, :metadata
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Relations
4
+ module Cascading
5
+ class Restrict
6
+
7
+ attr_accessor :document, :relation, :metadata
8
+
9
+ # Initialize the new cascade strategy, which will set up the relation
10
+ # and the metadata.
11
+ #
12
+ # @example Instantiate the strategy
13
+ # Strategy.new(document, metadata)
14
+ #
15
+ # @param [ Document ] document The document to cascade from.
16
+ # @param [ Metadata ] metadata The relation's metadata.
17
+ #
18
+ # @return [ Strategy ] The new strategy.
19
+ def initialize(document, metadata)
20
+ @document, @metadata = document, metadata
21
+ @relation = document.send(metadata.name)
22
+ end
23
+
24
+ # Execute the cascading deletion for the relation if it already exists.
25
+ # This should be optimized in the future potentially not to load all
26
+ # objects from the db.
27
+ #
28
+ # @example Perform the cascading delete.
29
+ # strategy.cascade
30
+ def cascade
31
+ raise Errors::DeleteRestriction.new(document, metadata.name) unless relation.blank?
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
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
  # Used for converting foreign key values to the correct type based on the
6
6
  # types of ids that the document stores.
@@ -35,7 +35,8 @@ module Mongoid # :nodoc:
35
35
  # @since 2.0.0.rc.7
36
36
  def convert(object)
37
37
  return object if metadata.polymorphic?
38
- BSON::ObjectId.convert(metadata.klass, object)
38
+ klass = metadata.klass
39
+ klass.using_object_ids? ? BSON::ObjectId.mongoize(object) : object
39
40
  end
40
41
  end
41
42
  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
  # Contains utility methods for object id conversion.
6
6
  module Conversions
@@ -23,11 +23,10 @@ module Mongoid #:nodoc:
23
23
  if inverse.using_object_ids? || object.is_a?(BSON::ObjectId)
24
24
  object
25
25
  else
26
- object.tap do |obj|
27
- if obj.is_a?(String)
28
- obj.unconvertable_to_bson = true
29
- end
26
+ if object.is_a?(String)
27
+ object.unconvertable_to_bson = true
30
28
  end
29
+ object
31
30
  end
32
31
  end
33
32
  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 module provides convenience macros for using cyclic embedded
6
6
  # relations.
@@ -11,7 +11,7 @@ module Mongoid # :nodoc:
11
11
  class_attribute :cyclic
12
12
  end
13
13
 
14
- module ClassMethods #:nodoc:
14
+ module ClassMethods
15
15
 
16
16
  # Create a cyclic embedded relation that creates a tree hierarchy for
17
17
  # the document and many embedded child documents.
@@ -38,9 +38,9 @@ module Mongoid # :nodoc:
38
38
  def recursively_embeds_many(options = {})
39
39
  embeds_many(
40
40
  cyclic_child_name,
41
- options.merge(:class_name => self.name, :cyclic => true)
41
+ options.merge(class_name: self.name, cyclic: true)
42
42
  )
43
- embedded_in cyclic_parent_name, :class_name => self.name, :cyclic => true
43
+ embedded_in cyclic_parent_name, class_name: self.name, cyclic: true
44
44
  end
45
45
 
46
46
  # Create a cyclic embedded relation that creates a single self
@@ -68,9 +68,9 @@ module Mongoid # :nodoc:
68
68
  def recursively_embeds_one(options = {})
69
69
  embeds_one(
70
70
  cyclic_child_name(false),
71
- options.merge(:class_name => self.name, :cyclic => true)
71
+ options.merge(class_name: self.name, cyclic: true)
72
72
  )
73
- embedded_in cyclic_parent_name, :class_name => self.name, :cyclic => true
73
+ embedded_in cyclic_parent_name, class_name: self.name, cyclic: true
74
74
  end
75
75
 
76
76
  private
@@ -0,0 +1,346 @@
1
+ # encoding: utf-8
2
+ module Mongoid
3
+ module Relations
4
+ module Embedded
5
+
6
+ # Contains behaviour for executing operations in batch on embedded
7
+ # documents.
8
+ module Batchable
9
+
10
+ # Insert new documents as a batch push ($pushAll). This ensures that
11
+ # all callbacks are run at the appropriate time and only 1 request is
12
+ # made to the database.
13
+ #
14
+ # @example Execute the batch push.
15
+ # batchable.batch_insert([ doc_one, doc_two ])
16
+ #
17
+ # @param [ Array<Document> ] docs The docs to add.
18
+ #
19
+ # @return [ Array<Hash> ] The inserts.
20
+ #
21
+ # @since 3.0.0
22
+ def batch_insert(docs)
23
+ execute_batch_insert(docs, "$pushAll")
24
+ end
25
+
26
+ # Clear all of the docs out of the relation in a single swipe.
27
+ #
28
+ # @example Clear all docs.
29
+ # batchable.batch_clear(docs)
30
+ #
31
+ # @param [ Array<Document> ] docs The docs to clear.
32
+ #
33
+ # @return [ Array ] The empty array.
34
+ #
35
+ # @since 3.0.0
36
+ def batch_clear(docs)
37
+ pre_process_batch_remove(docs, :delete)
38
+ unless docs.empty?
39
+ collection.find(selector).update("$unset" => { path => true })
40
+ post_process_batch_remove(docs, :delete)
41
+ end
42
+ _unscoped.clear
43
+ end
44
+
45
+ # Batch remove the provided documents as a $pullAll.
46
+ #
47
+ # @example Batch remove the documents.
48
+ # batchable.batch_remove([ doc_one, doc_two ])
49
+ #
50
+ # @param [ Array<Document> ] docs The docs to remove.
51
+ # @param [ Symbol ] method Delete or destroy.
52
+ #
53
+ # @since 3.0.0
54
+ def batch_remove(docs, method = :delete)
55
+ removals = pre_process_batch_remove(docs, method)
56
+ if !docs.empty? && !_assigning?
57
+ collection.find(selector).update("$pullAll" => { path => removals })
58
+ post_process_batch_remove(docs, method)
59
+ end
60
+ Threaded.clear_options!
61
+ reindex
62
+ end
63
+
64
+ # Batch replace the provided documents as a $set.
65
+ #
66
+ # @example Batch replace the documents.
67
+ # batchable.batch_replace([ doc_one, doc_two ])
68
+ #
69
+ # @param [ Array<Document> ] docs The docs to replace with.
70
+ #
71
+ # @return [ Array<Hash> ] The inserts.
72
+ #
73
+ # @since 3.0.0
74
+ def batch_replace(docs)
75
+ if docs.blank?
76
+ if _assigning? && !empty?
77
+ base.atomic_unsets.push(first.atomic_path)
78
+ end
79
+ batch_remove(target.dup)
80
+ else
81
+ base.delayed_atomic_sets.clear
82
+ docs = normalize_docs(docs).compact
83
+ target.clear and _unscoped.clear
84
+ inserts = execute_batch_insert(docs, "$set")
85
+ add_atomic_sets(inserts)
86
+ end
87
+ end
88
+
89
+ private
90
+
91
+ # Add the atomic sets to the base document.
92
+ #
93
+ # @api private
94
+ #
95
+ # @example Add the atomic sets.
96
+ # batchable.add_atomic_sets([{ field: value }])
97
+ #
98
+ # @param [ Array<Hash> ] sets The atomic sets.
99
+ #
100
+ # @since 3.0.0
101
+ def add_atomic_sets(sets)
102
+ if _assigning?
103
+ base.collect_children.each do |child|
104
+ child.delayed_atomic_sets.clear
105
+ end
106
+ base.delayed_atomic_sets[path] = sets
107
+ end
108
+ end
109
+
110
+ # Perform a batch persist of the provided documents with the supplied
111
+ # operation.
112
+ #
113
+ # @api private
114
+ #
115
+ # @example Perform a batch operation.
116
+ # batchable.execute_batch(docs, "$set")
117
+ #
118
+ # @param [ Array<Document> ] docs The docs to persist.
119
+ # @param [ String ] operation The atomic operation.
120
+ #
121
+ # @return [ Array<Hash> ] The inserts.
122
+ #
123
+ # @since 3.0.0
124
+ def execute_batch_insert(docs, operation)
125
+ self.inserts_valid = true
126
+ inserts = pre_process_batch_insert(docs)
127
+ if insertable?
128
+ collection.find(selector).update(operation => { path => inserts })
129
+ post_process_batch_insert(docs)
130
+ end
131
+ inserts
132
+ end
133
+
134
+ # Are we in a state to be able to batch insert?
135
+ #
136
+ # @api private
137
+ #
138
+ # @example Can inserts be performed?
139
+ # batchable.insertable?
140
+ #
141
+ # @return [ true, false ] If inserts can be performed.
142
+ #
143
+ # @since 3.0.0
144
+ def insertable?
145
+ persistable? && !_assigning? && inserts_valid
146
+ end
147
+
148
+ # Are the inserts currently valid?
149
+ #
150
+ # @api private
151
+ #
152
+ # @example Are the inserts currently valid.
153
+ # batchable.inserts_valid
154
+ #
155
+ # @return [ true, false ] If inserts are currently valid.
156
+ #
157
+ # @since 3.0.0
158
+ def inserts_valid
159
+ @inserts_valid
160
+ end
161
+
162
+ # Set the inserts valid flag.
163
+ #
164
+ # @api private
165
+ #
166
+ # @example Set the flag.
167
+ # batchable.inserts_valid = true
168
+ #
169
+ # @param [ true, false ] value The flag.
170
+ #
171
+ # @return [ true, false ] The flag.
172
+ #
173
+ # @since 3.0.0
174
+ def inserts_valid=(value)
175
+ @inserts_valid = value
176
+ end
177
+
178
+ # Normalize the documents, in case they were provided as an array of
179
+ # hashes.
180
+ #
181
+ # @api private
182
+ #
183
+ # @example Normalize the docs.
184
+ # batchable.normalize_docs(docs)
185
+ #
186
+ # @param [ Array<Hash, Document> ] docs The docs to normalize.
187
+ #
188
+ # @return [ Array<Document> ] The docs.
189
+ #
190
+ # @since 3.0.0
191
+ def normalize_docs(docs)
192
+ if docs.first.is_a?(::Hash)
193
+ docs.map do |doc|
194
+ attributes = { metadata: metadata, _parent: base }
195
+ attributes.merge!(doc)
196
+ Factory.build(klass, attributes)
197
+ end
198
+ else
199
+ docs
200
+ end
201
+ end
202
+
203
+ # Get the atomic path.
204
+ #
205
+ # @api private
206
+ #
207
+ # @example Get the atomic path.
208
+ # batchable.path
209
+ #
210
+ # @return [ String ] The atomic path.
211
+ #
212
+ # @since 3.0.0
213
+ def path
214
+ @path ||= _unscoped.first.atomic_path
215
+ end
216
+
217
+ # Set the atomic path.
218
+ #
219
+ # @api private
220
+ #
221
+ # @example Set the atomic path.
222
+ # batchable.path = "addresses"
223
+ #
224
+ # @param [ String ] value The path.
225
+ #
226
+ # @return [ String ] The path.
227
+ #
228
+ # @since 3.0.0
229
+ def path=(value)
230
+ @path = value
231
+ end
232
+
233
+ # Get the selector for executing atomic operations on the collection.
234
+ #
235
+ # @api private
236
+ #
237
+ # @example Get the selector.
238
+ # batchable.selector
239
+ #
240
+ # @return [ Hash ] The atomic selector.
241
+ #
242
+ # @since 3.0.0
243
+ def selector
244
+ @selector ||= base.atomic_selector
245
+ end
246
+
247
+ # Pre processes the batch insert for the provided documents.
248
+ #
249
+ # @api private
250
+ #
251
+ # @example Pre process the documents.
252
+ # batchable.pre_process_batch_insert(docs)
253
+ #
254
+ # @param [ Array<Document> ] docs The documents.
255
+ #
256
+ # @return [ Array<Hash> ] The documents as an array of hashes.
257
+ #
258
+ # @since 3.0.0
259
+ def pre_process_batch_insert(docs)
260
+ docs.map do |doc|
261
+ next unless doc
262
+ append(doc)
263
+ if persistable? && !_assigning?
264
+ self.path = doc.atomic_path unless path
265
+ if doc.valid?(:create)
266
+ doc.run_before_callbacks(:save, :create)
267
+ else
268
+ self.inserts_valid = false
269
+ end
270
+ end
271
+ doc.as_document
272
+ end
273
+ end
274
+
275
+ # Pre process the batch removal.
276
+ #
277
+ # @api private
278
+ #
279
+ # @example Pre process the documents.
280
+ # batchable.pre_process_batch_remove(docs, :delete)
281
+ #
282
+ # @param [ Array<Document> ] docs The documents.
283
+ # @param [ Symbol ] method Delete or destroy.
284
+ #
285
+ # @return [ Array<Hash> ] The documents as hashes.
286
+ #
287
+ # @since 3.0.0
288
+ def pre_process_batch_remove(docs, method)
289
+ docs.map do |doc|
290
+ self.path = doc.atomic_path unless path
291
+ if !_assigning? && !metadata.versioned?
292
+ doc.cascade!
293
+ doc.run_before_callbacks(:destroy) if method == :destroy
294
+ end
295
+ target.delete_one(doc)
296
+ _unscoped.delete_one(doc)
297
+ unbind_one(doc)
298
+ doc.as_document
299
+ end
300
+ end
301
+
302
+ # Post process the documents after batch insert.
303
+ #
304
+ # @api private
305
+ #
306
+ # @example Post process the documents.
307
+ # batchable.post_process_batch_insert(docs)
308
+ #
309
+ # @param [ Array<Documents> ] docs The inserted docs.
310
+ #
311
+ # @return [ Enumerable ] The document enum.
312
+ #
313
+ # @since 3.0.0
314
+ def post_process_batch_insert(docs)
315
+ docs.each do |doc|
316
+ doc.new_record = false
317
+ doc.run_after_callbacks(:create, :save)
318
+ doc.post_persist
319
+ end
320
+ end
321
+
322
+ # Post process the batch removal.
323
+ #
324
+ # @api private
325
+ #
326
+ # @example Post process the documents.
327
+ # batchable.post_process_batch_remove(docs, :delete)
328
+ #
329
+ # @param [ Array<Document> ] docs The documents.
330
+ # @param [ Symbol ] method Delete or destroy.
331
+ #
332
+ # @return [ Array<Document> ] The documents.
333
+ #
334
+ # @since 3.0.0
335
+ def post_process_batch_remove(docs, method)
336
+ docs.each do |doc|
337
+ doc.run_after_callbacks(:destroy) if method == :destroy
338
+ doc.freeze
339
+ doc.destroyed = true
340
+ IdentityMap.remove(doc)
341
+ end
342
+ end
343
+ end
344
+ end
345
+ end
346
+ end