mongoid 2.4.9 → 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 +869 -8
  2. data/LICENSE +1 -1
  3. data/README.md +10 -11
  4. data/Rakefile +2 -17
  5. data/lib/config/locales/en.yml +441 -51
  6. data/lib/mongoid/atomic/modifiers.rb +2 -2
  7. data/lib/mongoid/atomic/paths/embedded/many.rb +6 -6
  8. data/lib/mongoid/atomic/paths/embedded/one.rb +5 -5
  9. data/lib/mongoid/atomic/paths/embedded.rb +4 -5
  10. data/lib/mongoid/atomic/paths/root.rb +4 -5
  11. data/lib/mongoid/atomic.rb +16 -6
  12. data/lib/mongoid/attributes/processing.rb +14 -10
  13. data/lib/mongoid/attributes/readonly.rb +56 -0
  14. data/lib/mongoid/attributes.rb +95 -32
  15. data/lib/mongoid/callbacks.rb +100 -42
  16. data/lib/mongoid/collections/retry.rb +2 -3
  17. data/lib/mongoid/components.rb +10 -22
  18. data/lib/mongoid/config/environment.rb +4 -3
  19. data/lib/mongoid/config/inflections.rb +6 -0
  20. data/lib/mongoid/config/options.rb +1 -1
  21. data/lib/mongoid/config/validators/option.rb +25 -0
  22. data/lib/mongoid/config/validators/session.rb +140 -0
  23. data/lib/mongoid/config/validators.rb +3 -0
  24. data/lib/mongoid/config.rb +87 -233
  25. data/lib/mongoid/contextual/aggregable/memory.rb +98 -0
  26. data/lib/mongoid/contextual/aggregable/mongo.rb +181 -0
  27. data/lib/mongoid/contextual/atomic.rb +179 -0
  28. data/lib/mongoid/contextual/command.rb +43 -0
  29. data/lib/mongoid/contextual/find_and_modify.rb +66 -0
  30. data/lib/mongoid/contextual/map_reduce.rb +273 -0
  31. data/lib/mongoid/contextual/memory.rb +383 -0
  32. data/lib/mongoid/contextual/mongo.rb +543 -0
  33. data/lib/mongoid/contextual.rb +50 -0
  34. data/lib/mongoid/copyable.rb +2 -2
  35. data/lib/mongoid/criteria.rb +436 -248
  36. data/lib/mongoid/criterion/inspection.rb +14 -8
  37. data/lib/mongoid/criterion/scoping.rb +114 -44
  38. data/lib/mongoid/dirty.rb +152 -67
  39. data/lib/mongoid/document.rb +68 -49
  40. data/lib/mongoid/errors/ambiguous_relationship.rb +51 -0
  41. data/lib/mongoid/errors/callback.rb +5 -6
  42. data/lib/mongoid/errors/delete_restriction.rb +29 -0
  43. data/lib/mongoid/errors/document_not_found.rb +98 -17
  44. data/lib/mongoid/errors/eager_load.rb +3 -6
  45. data/lib/mongoid/errors/invalid_collection.rb +3 -3
  46. data/lib/mongoid/errors/invalid_config_option.rb +27 -0
  47. data/lib/mongoid/errors/invalid_database.rb +3 -3
  48. data/lib/mongoid/errors/invalid_field.rb +54 -8
  49. data/lib/mongoid/errors/invalid_field_option.rb +35 -0
  50. data/lib/mongoid/errors/invalid_find.rb +3 -3
  51. data/lib/mongoid/errors/invalid_index.rb +28 -0
  52. data/lib/mongoid/errors/invalid_options.rb +4 -4
  53. data/lib/mongoid/errors/invalid_scope.rb +24 -0
  54. data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +38 -0
  55. data/lib/mongoid/errors/invalid_storage_options.rb +27 -0
  56. data/lib/mongoid/errors/invalid_time.rb +3 -6
  57. data/lib/mongoid/errors/inverse_not_found.rb +29 -0
  58. data/lib/mongoid/errors/mixed_relations.rb +4 -9
  59. data/lib/mongoid/errors/mixed_session_configuration.rb +28 -0
  60. data/lib/mongoid/errors/mongoid_error.rb +54 -3
  61. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +28 -0
  62. data/lib/mongoid/errors/no_default_session.rb +23 -0
  63. data/lib/mongoid/errors/no_environment.rb +3 -3
  64. data/lib/mongoid/errors/no_map_reduce_output.rb +24 -0
  65. data/lib/mongoid/errors/no_parent.rb +24 -0
  66. data/lib/mongoid/errors/no_session_config.rb +22 -0
  67. data/lib/mongoid/errors/no_session_database.rb +27 -0
  68. data/lib/mongoid/errors/no_session_hosts.rb +27 -0
  69. data/lib/mongoid/errors/no_sessions_config.rb +20 -0
  70. data/lib/mongoid/errors/readonly_attribute.rb +25 -0
  71. data/lib/mongoid/errors/scope_overwrite.rb +4 -4
  72. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +4 -4
  73. data/lib/mongoid/errors/unknown_attribute.rb +25 -0
  74. data/lib/mongoid/errors/unsaved_document.rb +4 -8
  75. data/lib/mongoid/errors/unsupported_javascript.rb +27 -0
  76. data/lib/mongoid/errors/unsupported_version.rb +4 -4
  77. data/lib/mongoid/errors/validations.rb +7 -6
  78. data/lib/mongoid/errors/versioning_not_on_root.rb +23 -0
  79. data/lib/mongoid/errors.rb +22 -1
  80. data/lib/mongoid/extensions/array.rb +127 -0
  81. data/lib/mongoid/extensions/big_decimal.rb +42 -0
  82. data/lib/mongoid/extensions/boolean.rb +24 -0
  83. data/lib/mongoid/extensions/date.rb +70 -0
  84. data/lib/mongoid/extensions/date_time.rb +68 -0
  85. data/lib/mongoid/extensions/false_class.rb +26 -0
  86. data/lib/mongoid/extensions/float.rb +44 -0
  87. data/lib/mongoid/extensions/hash.rb +91 -0
  88. data/lib/mongoid/extensions/integer.rb +54 -0
  89. data/lib/mongoid/extensions/module.rb +28 -0
  90. data/lib/mongoid/extensions/nil_class.rb +21 -0
  91. data/lib/mongoid/extensions/object.rb +188 -0
  92. data/lib/mongoid/extensions/object_id.rb +53 -0
  93. data/lib/mongoid/extensions/range.rb +55 -0
  94. data/lib/mongoid/extensions/regexp.rb +27 -0
  95. data/lib/mongoid/extensions/set.rb +55 -0
  96. data/lib/mongoid/extensions/string.rb +155 -0
  97. data/lib/mongoid/extensions/symbol.rb +54 -0
  98. data/lib/mongoid/extensions/time.rb +78 -0
  99. data/lib/mongoid/extensions/time_with_zone.rb +55 -0
  100. data/lib/mongoid/extensions/true_class.rb +26 -0
  101. data/lib/mongoid/extensions.rb +28 -76
  102. data/lib/mongoid/factory.rb +4 -4
  103. data/lib/mongoid/fields/foreign_key.rb +134 -0
  104. data/lib/mongoid/fields/localized.rb +73 -0
  105. data/lib/mongoid/fields/standard.rb +268 -0
  106. data/lib/mongoid/fields/validators/macro.rb +83 -0
  107. data/lib/mongoid/fields/validators.rb +2 -0
  108. data/lib/mongoid/fields.rb +129 -194
  109. data/lib/mongoid/finders.rb +42 -43
  110. data/lib/mongoid/hierarchy.rb +25 -14
  111. data/lib/mongoid/identity_map.rb +39 -12
  112. data/lib/mongoid/indexes/validators/options.rb +80 -0
  113. data/lib/mongoid/indexes.rb +66 -15
  114. data/lib/mongoid/inspection.rb +1 -1
  115. data/lib/mongoid/javascript.rb +1 -1
  116. data/lib/mongoid/json.rb +2 -2
  117. data/lib/mongoid/loggable.rb +69 -0
  118. data/lib/mongoid/matchers/all.rb +7 -8
  119. data/lib/mongoid/matchers/and.rb +3 -3
  120. data/lib/mongoid/matchers/default.rb +6 -4
  121. data/lib/mongoid/matchers/exists.rb +2 -2
  122. data/lib/mongoid/matchers/gt.rb +2 -2
  123. data/lib/mongoid/matchers/gte.rb +2 -2
  124. data/lib/mongoid/matchers/in.rb +3 -7
  125. data/lib/mongoid/matchers/lt.rb +2 -2
  126. data/lib/mongoid/matchers/lte.rb +2 -2
  127. data/lib/mongoid/matchers/ne.rb +2 -2
  128. data/lib/mongoid/matchers/nin.rb +2 -2
  129. data/lib/mongoid/matchers/or.rb +2 -2
  130. data/lib/mongoid/matchers/size.rb +2 -2
  131. data/lib/mongoid/matchers/strategies.rb +3 -3
  132. data/lib/mongoid/matchers.rb +1 -1
  133. data/lib/mongoid/multi_parameter_attributes.rb +8 -10
  134. data/lib/mongoid/nested_attributes.rb +17 -9
  135. data/lib/mongoid/observer.rb +1 -2
  136. data/lib/mongoid/paranoia.rb +13 -18
  137. data/lib/mongoid/persistence/atomic/add_to_set.rb +5 -9
  138. data/lib/mongoid/persistence/atomic/bit.rb +5 -7
  139. data/lib/mongoid/persistence/atomic/inc.rb +5 -7
  140. data/lib/mongoid/persistence/atomic/operation.rb +45 -6
  141. data/lib/mongoid/persistence/atomic/pop.rb +5 -7
  142. data/lib/mongoid/persistence/atomic/pull.rb +5 -7
  143. data/lib/mongoid/persistence/atomic/pull_all.rb +5 -7
  144. data/lib/mongoid/persistence/atomic/push.rb +4 -10
  145. data/lib/mongoid/persistence/atomic/push_all.rb +4 -10
  146. data/lib/mongoid/persistence/atomic/rename.rb +6 -7
  147. data/lib/mongoid/persistence/atomic/sets.rb +5 -7
  148. data/lib/mongoid/persistence/atomic/unset.rb +4 -5
  149. data/lib/mongoid/persistence/atomic.rb +2 -2
  150. data/lib/mongoid/persistence/deletion.rb +2 -2
  151. data/lib/mongoid/persistence/insertion.rb +10 -16
  152. data/lib/mongoid/persistence/modification.rb +5 -9
  153. data/lib/mongoid/persistence/operations/embedded/insert.rb +7 -6
  154. data/lib/mongoid/persistence/operations/embedded/remove.rb +5 -5
  155. data/lib/mongoid/persistence/operations/insert.rb +4 -4
  156. data/lib/mongoid/persistence/operations/remove.rb +4 -4
  157. data/lib/mongoid/persistence/operations/update.rb +5 -5
  158. data/lib/mongoid/persistence/operations.rb +6 -19
  159. data/lib/mongoid/persistence.rb +64 -27
  160. data/lib/mongoid/railtie.rb +26 -11
  161. data/lib/mongoid/railties/database.rake +22 -108
  162. data/lib/mongoid/relations/accessors.rb +119 -19
  163. data/lib/mongoid/relations/auto_save.rb +59 -5
  164. data/lib/mongoid/relations/binding.rb +211 -2
  165. data/lib/mongoid/relations/bindings/embedded/in.rb +16 -22
  166. data/lib/mongoid/relations/bindings/embedded/many.rb +9 -50
  167. data/lib/mongoid/relations/bindings/embedded/one.rb +10 -16
  168. data/lib/mongoid/relations/bindings/referenced/in.rb +31 -57
  169. data/lib/mongoid/relations/bindings/referenced/many.rb +8 -20
  170. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +15 -19
  171. data/lib/mongoid/relations/bindings/referenced/one.rb +10 -24
  172. data/lib/mongoid/relations/builder.rb +3 -3
  173. data/lib/mongoid/relations/builders/embedded/in.rb +5 -5
  174. data/lib/mongoid/relations/builders/embedded/many.rb +12 -12
  175. data/lib/mongoid/relations/builders/embedded/one.rb +6 -6
  176. data/lib/mongoid/relations/builders/nested_attributes/many.rb +8 -8
  177. data/lib/mongoid/relations/builders/nested_attributes/one.rb +4 -4
  178. data/lib/mongoid/relations/builders/referenced/in.rb +4 -4
  179. data/lib/mongoid/relations/builders/referenced/many.rb +5 -5
  180. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +7 -5
  181. data/lib/mongoid/relations/builders/referenced/one.rb +5 -5
  182. data/lib/mongoid/relations/builders.rb +19 -16
  183. data/lib/mongoid/relations/cascading/delete.rb +12 -4
  184. data/lib/mongoid/relations/cascading/destroy.rb +3 -3
  185. data/lib/mongoid/relations/cascading/nullify.rb +3 -3
  186. data/lib/mongoid/relations/cascading/restrict.rb +37 -0
  187. data/lib/mongoid/relations/cascading.rb +6 -4
  188. data/lib/mongoid/relations/constraint.rb +4 -3
  189. data/lib/mongoid/relations/conversions.rb +5 -6
  190. data/lib/mongoid/relations/cyclic.rb +7 -7
  191. data/lib/mongoid/relations/embedded/batchable.rb +346 -0
  192. data/lib/mongoid/relations/embedded/in.rb +23 -12
  193. data/lib/mongoid/relations/embedded/many.rb +99 -148
  194. data/lib/mongoid/relations/embedded/one.rb +25 -14
  195. data/lib/mongoid/relations/macros.rb +105 -60
  196. data/lib/mongoid/relations/many.rb +93 -14
  197. data/lib/mongoid/relations/metadata.rb +231 -45
  198. data/lib/mongoid/relations/nested_builder.rb +3 -5
  199. data/lib/mongoid/relations/one.rb +14 -2
  200. data/lib/mongoid/relations/options.rb +2 -2
  201. data/lib/mongoid/relations/polymorphic.rb +9 -9
  202. data/lib/mongoid/relations/proxy.rb +60 -31
  203. data/lib/mongoid/relations/referenced/in.rb +40 -15
  204. data/lib/mongoid/relations/referenced/many.rb +116 -122
  205. data/lib/mongoid/relations/referenced/many_to_many.rb +101 -46
  206. data/lib/mongoid/relations/referenced/one.rb +34 -13
  207. data/lib/mongoid/relations/reflections.rb +3 -3
  208. data/lib/mongoid/relations/synchronization.rb +19 -23
  209. data/lib/mongoid/relations/targets/enumerable.rb +86 -57
  210. data/lib/mongoid/relations/touchable.rb +32 -0
  211. data/lib/mongoid/relations.rb +6 -6
  212. data/lib/mongoid/reloading.rb +12 -14
  213. data/lib/mongoid/scoping.rb +329 -0
  214. data/lib/mongoid/serialization.rb +13 -30
  215. data/lib/mongoid/sessions/factory.rb +106 -0
  216. data/lib/mongoid/sessions/mongo_uri.rb +93 -0
  217. data/lib/mongoid/sessions/validators/storage.rb +49 -0
  218. data/lib/mongoid/sessions/validators.rb +2 -0
  219. data/lib/mongoid/sessions.rb +359 -0
  220. data/lib/mongoid/sharding.rb +6 -6
  221. data/lib/mongoid/state.rb +6 -7
  222. data/lib/mongoid/threaded/lifecycle.rb +21 -21
  223. data/lib/mongoid/threaded/sessions.rb +0 -0
  224. data/lib/mongoid/threaded.rb +167 -59
  225. data/lib/mongoid/timestamps/created.rb +8 -4
  226. data/lib/mongoid/timestamps/timeless.rb +6 -4
  227. data/lib/mongoid/timestamps/updated.rb +3 -3
  228. data/lib/mongoid/timestamps.rb +1 -1
  229. data/lib/mongoid/unit_of_work.rb +61 -0
  230. data/lib/mongoid/validations/associated.rb +2 -2
  231. data/lib/mongoid/validations/format.rb +2 -2
  232. data/lib/mongoid/validations/presence.rb +34 -4
  233. data/lib/mongoid/validations/uniqueness.rb +103 -25
  234. data/lib/mongoid/validations.rb +62 -20
  235. data/lib/mongoid/version.rb +2 -2
  236. data/lib/mongoid/versioning.rb +25 -26
  237. data/lib/mongoid.rb +24 -39
  238. data/lib/rack/mongoid/middleware/identity_map.rb +3 -3
  239. data/lib/rails/generators/mongoid/config/config_generator.rb +1 -1
  240. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +59 -19
  241. data/lib/rails/generators/mongoid/model/model_generator.rb +7 -7
  242. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +2 -2
  243. data/lib/rails/generators/mongoid/observer/observer_generator.rb +4 -4
  244. data/lib/rails/generators/mongoid_generator.rb +5 -5
  245. data/lib/rails/mongoid.rb +69 -25
  246. metadata +93 -155
  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/master.rb +0 -45
  269. data/lib/mongoid/collections/operations.rb +0 -44
  270. data/lib/mongoid/collections.rb +0 -120
  271. data/lib/mongoid/config/database.rb +0 -181
  272. data/lib/mongoid/config/replset_database.rb +0 -80
  273. data/lib/mongoid/contexts/enumerable/sort.rb +0 -43
  274. data/lib/mongoid/contexts/enumerable.rb +0 -313
  275. data/lib/mongoid/contexts/mongo.rb +0 -485
  276. data/lib/mongoid/contexts.rb +0 -25
  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 -108
  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 -76
  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 -31
  341. data/lib/mongoid/named_scope.rb +0 -166
  342. data/lib/mongoid/relations/embedded/atomic/operation.rb +0 -63
  343. data/lib/mongoid/relations/embedded/atomic/pull.rb +0 -65
  344. data/lib/mongoid/relations/embedded/atomic/push_all.rb +0 -59
  345. data/lib/mongoid/relations/embedded/atomic/set.rb +0 -61
  346. data/lib/mongoid/relations/embedded/atomic/unset.rb +0 -41
  347. data/lib/mongoid/relations/embedded/atomic.rb +0 -89
  348. data/lib/mongoid/relations/referenced/batch/insert.rb +0 -57
  349. data/lib/mongoid/relations/referenced/batch.rb +0 -73
  350. data/lib/mongoid/safety.rb +0 -105
  351. data/lib/mongoid/scope.rb +0 -31
@@ -1,13 +1,50 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
4
 
5
5
  # This module contains the behaviour for auto-saving relations in
6
6
  # different collections.
7
7
  module AutoSave
8
8
  extend ActiveSupport::Concern
9
9
 
10
- module ClassMethods #:nodoc:
10
+ included do
11
+ class_attribute :autosaved_relations
12
+ self.autosaved_relations = []
13
+ end
14
+
15
+ # Used to prevent infinite loops in associated autosaves.
16
+ #
17
+ # @example Is the document autosaved?
18
+ # document.autosaved?
19
+ #
20
+ # @return [ true, false ] Has the document already been autosaved?
21
+ #
22
+ # @since 3.0.0
23
+ def autosaved?
24
+ Threaded.autosaved?(self)
25
+ end
26
+
27
+ # Begin the associated autosave.
28
+ #
29
+ # @example Begin autosave.
30
+ # document.begin_autosave
31
+ #
32
+ # @since 3.0.0
33
+ def begin_autosave
34
+ Threaded.begin_autosave(self)
35
+ end
36
+
37
+ # Exit the associated autosave.
38
+ #
39
+ # @example Exit autosave.
40
+ # document.exit_autosave
41
+ #
42
+ # @since 3.0.0
43
+ def exit_autosave
44
+ Threaded.exit_autosave(self)
45
+ end
46
+
47
+ module ClassMethods
11
48
 
12
49
  # Set up the autosave behaviour for references many and references one
13
50
  # relations. When the option is set to true, these relations will get
@@ -21,17 +58,34 @@ module Mongoid # :nodoc:
21
58
  #
22
59
  # @since 2.0.0.rc.1
23
60
  def autosave(metadata)
24
- if metadata.autosave?
25
- set_callback :save, :after do |document|
61
+ if metadata.autosave? && autosavable?(metadata)
62
+ autosaved_relations.push(metadata.name)
63
+ set_callback :save, :after, unless: :autosaved? do |document|
64
+ begin_autosave
26
65
  relation = document.send(metadata.name)
27
66
  if relation
28
67
  (relation.do_or_do_not(:in_memory) || Array.wrap(relation)).each do |doc|
29
68
  doc.save
30
69
  end
31
70
  end
71
+ exit_autosave
32
72
  end
33
73
  end
34
74
  end
75
+
76
+ # Can the autosave be added?
77
+ #
78
+ # @example Can the autosave be added?
79
+ # Person.autosavable?(metadata)
80
+ #
81
+ # @param [ Metadata ] metadata The relation metadata.
82
+ #
83
+ # @return [ true, false ] If the autosave is able to be added.
84
+ #
85
+ # @since 3.0.0
86
+ def autosavable?(metadata)
87
+ !autosaved_relations.include?(metadata.name) && !metadata.embedded?
88
+ end
35
89
  end
36
90
  end
37
91
  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
  # Superclass for all objects that bind relations together.
6
6
  class Binding
@@ -21,6 +21,215 @@ module Mongoid # :nodoc:
21
21
  def initialize(base, target, metadata)
22
22
  @base, @target, @metadata = base, target, metadata
23
23
  end
24
+
25
+ # Execute the provided block inside a binding.
26
+ #
27
+ # @example Execute the binding block.
28
+ # binding.binding do
29
+ # base.foreign_key = 1
30
+ # end
31
+ #
32
+ # @return [ Object ] The result of the yield.
33
+ #
34
+ # @since 3.0.0
35
+ def binding
36
+ unless _binding?
37
+ _binding do
38
+ yield(self) if block_given?
39
+ end
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ # Check if the inverse is properly defined.
46
+ #
47
+ # @api private
48
+ #
49
+ # @example Check the inverse definition.
50
+ # binding.check_inverse!(doc)
51
+ #
52
+ # @param [ Document ] doc The document getting bound.
53
+ #
54
+ # @raise [ Errors::InverseNotFound ] If no inverse found.
55
+ #
56
+ # @since 3.0.0
57
+ def check_inverse!(doc)
58
+ if !metadata.forced_nil_inverse? &&
59
+ !doc.respond_to?(metadata.foreign_key_setter)
60
+ raise Errors::InverseNotFound.new(
61
+ base.class,
62
+ metadata.name,
63
+ doc.class,
64
+ metadata.foreign_key
65
+ )
66
+ end
67
+ end
68
+
69
+ # Check for problems with multiple inverse definitions.
70
+ #
71
+ # @api private
72
+ #
73
+ # @example Check for inverses errors.
74
+ # binding.check_inverses!(doc)
75
+ #
76
+ # @param [ Document ] doc The document to check.
77
+ #
78
+ # @since 3.0.0
79
+ def check_inverses!(doc)
80
+ inverses = metadata.inverses(doc)
81
+ if inverses.count > 1 && base.send(metadata.foreign_key).nil?
82
+ raise Errors::InvalidSetPolymorphicRelation.new(
83
+ metadata.name, base.class.name, target.class.name
84
+ )
85
+ end
86
+ end
87
+
88
+ # Set the id of the related document in the foreign key field on the
89
+ # keyed document.
90
+ #
91
+ # @api private
92
+ #
93
+ # @example Bind the foreign key.
94
+ # binding.bind_foreign_key(post, person.id)
95
+ #
96
+ # @param [ Document ] keyed The document that stores the foreign key.
97
+ # @param [ Object ] id The id of the bound document.
98
+ #
99
+ # @since 3.0.0
100
+ def bind_foreign_key(keyed, id)
101
+ unless keyed.frozen?
102
+ keyed.you_must(metadata.foreign_key_setter, id)
103
+ end
104
+ end
105
+
106
+ # Set the type of the related document on the foreign type field, used
107
+ # when relations are polymorphic.
108
+ #
109
+ # @api private
110
+ #
111
+ # @example Bind the polymorphic type.
112
+ # binding.bind_polymorphic_type(post, "Person")
113
+ #
114
+ # @param [ Document ] typed The document that stores the type field.
115
+ # @param [ String ] name The name of the model.
116
+ #
117
+ # @since 3.0.0
118
+ def bind_polymorphic_type(typed, name)
119
+ if metadata.type
120
+ typed.you_must(metadata.type_setter, name)
121
+ end
122
+ end
123
+
124
+ # Set the type of the related document on the foreign type field, used
125
+ # when relations are polymorphic.
126
+ #
127
+ # @api private
128
+ #
129
+ # @example Bind the polymorphic type.
130
+ # binding.bind_polymorphic_inverse_type(post, "Person")
131
+ #
132
+ # @param [ Document ] typed The document that stores the type field.
133
+ # @param [ String ] name The name of the model.
134
+ #
135
+ # @since 3.0.0
136
+ def bind_polymorphic_inverse_type(typed, name)
137
+ if metadata.inverse_type
138
+ typed.you_must(metadata.inverse_type_setter, name)
139
+ end
140
+ end
141
+
142
+ # Bind the inverse document to the child document so that the in memory
143
+ # instances are the same.
144
+ #
145
+ # @api private
146
+ #
147
+ # @example Bind the inverse.
148
+ # binding.bind_inverse(post, person)
149
+ #
150
+ # @param [ Document ] doc The base document.
151
+ # @param [ Document ] inverse The inverse document.
152
+ #
153
+ # @since 3.0.0
154
+ def bind_inverse(doc, inverse)
155
+ if doc.respond_to?(metadata.inverse_setter)
156
+ doc.you_must(metadata.inverse_setter, inverse)
157
+ end
158
+ end
159
+
160
+ # Bind the inverse of field, when in a polymorphic relation.
161
+ #
162
+ # @api private
163
+ #
164
+ # @example Bind the inverse of field.
165
+ # binding.bind_inverse_of_field(doc)
166
+ #
167
+ # @param [ Document ] doc The document to bind.
168
+ # @param [ String ] name The name of the relation.
169
+ #
170
+ # @since 3.0.0
171
+ def bind_inverse_of_field(doc, name)
172
+ if inverse_metadata = metadata.inverse_metadata(doc)
173
+ if setter = inverse_metadata.inverse_of_field_setter
174
+ doc.you_must(setter, name)
175
+ end
176
+ end
177
+ end
178
+
179
+ # Bind the provided document with the base from the parent relation.
180
+ #
181
+ # @api private
182
+ #
183
+ # @example Bind the document with the base.
184
+ # binding.bind_from_relational_parent(doc)
185
+ #
186
+ # @param [ Document ] doc The document to bind.
187
+ #
188
+ # @since 3.0.0
189
+ def bind_from_relational_parent(doc)
190
+ check_inverse!(doc)
191
+ bind_foreign_key(doc, base.id)
192
+ bind_polymorphic_type(doc, base.class.model_name)
193
+ bind_inverse(doc, base)
194
+ bind_inverse_of_field(doc, metadata.name)
195
+ end
196
+
197
+ # Ensure that the metadata on the base is correct, for the cases
198
+ # where we have multiple belongs to definitions and were are setting
199
+ # different parents in memory in order.
200
+ #
201
+ # @api private
202
+ #
203
+ # @example Set the base metadata.
204
+ # binding.set_base_metadata
205
+ #
206
+ # @return [ true, false ] If the metadata changed.
207
+ #
208
+ # @since 2.4.4
209
+ def set_base_metadata
210
+ inverse_metadata = metadata.inverse_metadata(target)
211
+ if inverse_metadata != metadata && !inverse_metadata.nil?
212
+ base.metadata = inverse_metadata
213
+ end
214
+ end
215
+
216
+ # Bind the provided document with the base from the parent relation.
217
+ #
218
+ # @api private
219
+ #
220
+ # @example Bind the document with the base.
221
+ # unbinding.unbind_from_relational_parent(doc)
222
+ #
223
+ # @param [ Document ] doc The document to unbind.
224
+ #
225
+ # @since 3.0.0
226
+ def unbind_from_relational_parent(doc)
227
+ check_inverse!(doc)
228
+ bind_foreign_key(doc, nil)
229
+ bind_polymorphic_type(doc, nil)
230
+ bind_inverse(doc, nil)
231
+ bind_inverse_of_field(doc, nil)
232
+ end
24
233
  end
25
234
  end
26
235
  end
@@ -1,8 +1,8 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
4
- module Bindings #:nodoc:
5
- module Embedded #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
+ module Bindings
5
+ module Embedded
6
6
 
7
7
  # Binding class for embedded_in relations.
8
8
  class In < Binding
@@ -23,20 +23,17 @@ module Mongoid # :nodoc:
23
23
  # @option options [ true, false ] :binding Are we in build mode?
24
24
  #
25
25
  # @since 2.0.0.rc.1
26
- def bind
26
+ def bind_one
27
27
  base.metadata = metadata.inverse_metadata(target) unless base.metadata
28
28
  base.parentize(target)
29
- unless _binding?
30
- _binding do
31
- if base.embedded_many?
32
- target.do_or_do_not(metadata.inverse(target)).push(base)
33
- else
34
- target.do_or_do_not(metadata.inverse_setter(target), base)
35
- end
29
+ binding do
30
+ if base.embedded_many?
31
+ target.do_or_do_not(metadata.inverse(target)).push(base)
32
+ else
33
+ target.do_or_do_not(metadata.inverse_setter(target), base)
36
34
  end
37
35
  end
38
36
  end
39
- alias :bind_one :bind
40
37
 
41
38
  # Unbinds the base object and the inverse, caused by setting the
42
39
  # reference to nil.
@@ -50,18 +47,15 @@ module Mongoid # :nodoc:
50
47
  # @option options [ true, false ] :continue Do we continue unbinding?
51
48
  #
52
49
  # @since 2.0.0.rc.1
53
- def unbind
54
- unless _binding?
55
- _binding do
56
- if base.embedded_many?
57
- target.do_or_do_not(metadata.inverse(target)).delete(base)
58
- else
59
- target.do_or_do_not(metadata.inverse_setter(target), nil)
60
- end
50
+ def unbind_one
51
+ binding do
52
+ if base.embedded_many?
53
+ target.do_or_do_not(metadata.inverse(target)).delete(base)
54
+ else
55
+ target.do_or_do_not(metadata.inverse_setter(target), nil)
61
56
  end
62
57
  end
63
58
  end
64
- alias :unbind_one :unbind
65
59
  end
66
60
  end
67
61
  end
@@ -1,32 +1,12 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
4
- module Bindings #:nodoc:
5
- module Embedded #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
+ module Bindings
5
+ module Embedded
6
6
 
7
7
  # Binding class for embeds_many relations.
8
8
  class Many < Binding
9
9
 
10
- # Binds the base object to the inverse of the relation. This is so we
11
- # are referenced to the actual objects themselves on both sides.
12
- #
13
- # This case sets the metadata on the inverse object as well as the
14
- # document itself.
15
- #
16
- # @example Bind all the documents.
17
- # person.addresses.bind
18
- # person.addresses = [ Address.new ]
19
- #
20
- # @param [ Hash ] options The binding options.
21
- #
22
- # @option options [ true, false ] :continue Continue binding the inverse.
23
- # @option options [ true, false ] :binding Are we in build mode?
24
- #
25
- # @since 2.0.0.rc.1
26
- def bind
27
- target.each { |doc| bind_one(doc) }
28
- end
29
-
30
10
  # Binds a single document with the inverse relation. Used
31
11
  # specifically when appending to the proxy.
32
12
  #
@@ -42,32 +22,13 @@ module Mongoid # :nodoc:
42
22
  # @since 2.0.0.rc.1
43
23
  def bind_one(doc)
44
24
  doc.parentize(base)
45
- unless _binding?
46
- _binding do
47
- unless metadata.versioned?
48
- doc.do_or_do_not(metadata.inverse_setter(target), base)
49
- end
25
+ binding do
26
+ unless metadata.versioned?
27
+ doc.do_or_do_not(metadata.inverse_setter(target), base)
50
28
  end
51
29
  end
52
30
  end
53
31
 
54
- # Unbinds the base object and the inverse, caused by setting the
55
- # reference to nil.
56
- #
57
- # @example Unbind the documents.
58
- # person.addresses.unbind
59
- # person.addresses = nil
60
- #
61
- # @param [ Hash ] options The binding options.
62
- #
63
- # @option options [ true, false ] :continue Continue binding the inverse.
64
- # @option options [ true, false ] :binding Are we in build mode?
65
- #
66
- # @since 2.0.0.rc.1
67
- def unbind
68
- target.each { |doc| unbind_one(doc) }
69
- end
70
-
71
32
  # Unbind a single document.
72
33
  #
73
34
  # @example Unbind the document.
@@ -80,10 +41,8 @@ module Mongoid # :nodoc:
80
41
  #
81
42
  # @since 2.0.0.rc.1
82
43
  def unbind_one(doc)
83
- unless _binding?
84
- _binding do
85
- doc.do_or_do_not(metadata.inverse_setter(target), nil)
86
- end
44
+ binding do
45
+ doc.do_or_do_not(metadata.inverse_setter(target), nil)
87
46
  end
88
47
  end
89
48
  end
@@ -1,8 +1,8 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
4
- module Bindings #:nodoc:
5
- module Embedded #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
+ module Bindings
5
+ module Embedded
6
6
 
7
7
  # Binding class for embeds_one relations.
8
8
  class One < Binding
@@ -23,15 +23,12 @@ module Mongoid # :nodoc:
23
23
  # @option options [ true, false ] :binding Are we in build mode?
24
24
  #
25
25
  # @since 2.0.0.rc.1
26
- def bind
26
+ def bind_one
27
27
  target.parentize(base)
28
- unless _binding?
29
- _binding do
30
- target.do_or_do_not(metadata.inverse_setter(target), base)
31
- end
28
+ binding do
29
+ target.do_or_do_not(metadata.inverse_setter(target), base)
32
30
  end
33
31
  end
34
- alias :bind_one :bind
35
32
 
36
33
  # Unbinds the base object and the inverse, caused by setting the
37
34
  # reference to nil.
@@ -46,14 +43,11 @@ module Mongoid # :nodoc:
46
43
  # @option options [ true, false ] :binding Are we in build mode?
47
44
  #
48
45
  # @since 2.0.0.rc.1
49
- def unbind
50
- unless _binding?
51
- _binding do
52
- target.do_or_do_not(metadata.inverse_setter(target), nil)
53
- end
46
+ def unbind_one
47
+ binding do
48
+ target.do_or_do_not(metadata.inverse_setter(target), nil)
54
49
  end
55
50
  end
56
- alias :unbind_one :unbind
57
51
  end
58
52
  end
59
53
  end
@@ -1,8 +1,8 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
4
- module Bindings #:nodoc:
5
- module Referenced #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
+ module Bindings
5
+ module Referenced
6
6
 
7
7
  # Binding class for all referenced_in relations.
8
8
  class In < Binding
@@ -18,27 +18,23 @@ module Mongoid # :nodoc:
18
18
  # game.person = Person.new
19
19
  #
20
20
  # @since 2.0.0.rc.1
21
- def bind
22
- base.you_must(metadata.foreign_key_setter, target.id)
23
- if metadata.inverse_type
24
- base.you_must(metadata.inverse_type_setter, target.class.model_name)
25
- end
26
- unless _binding?
27
- _binding do
28
- inverse = metadata.inverse(target)
29
- if inverse
30
- if set_base_metadata
31
- if base.referenced_many?
32
- target.send(inverse).push(base) unless Mongoid.identity_map_enabled?
33
- else
34
- target.do_or_do_not(metadata.inverse_setter(target), base)
35
- end
21
+ def bind_one
22
+ binding do
23
+ check_inverses!(target)
24
+ bind_foreign_key(base, target.id)
25
+ bind_polymorphic_inverse_type(base, target.class.model_name)
26
+ if inverse = metadata.inverse(target)
27
+ if set_base_metadata
28
+ bind_inverse_of_field(base, base.metadata.name)
29
+ if base.referenced_many?
30
+ target.__send__(inverse).push(base) unless Mongoid.using_identity_map?
31
+ else
32
+ target.do_or_do_not(metadata.inverse_setter(target), base)
36
33
  end
37
34
  end
38
35
  end
39
36
  end
40
37
  end
41
- alias :bind_one :bind
42
38
 
43
39
  # Unbinds the base object and the inverse, caused by setting the
44
40
  # reference to nil.
@@ -48,47 +44,25 @@ module Mongoid # :nodoc:
48
44
  # game.person = nil
49
45
  #
50
46
  # @since 2.0.0.rc.1
51
- def unbind
52
- base.you_must(metadata.foreign_key_setter, nil)
53
- if metadata.inverse_type
54
- base.you_must(metadata.inverse_type_setter, nil)
55
- end
56
- unless _binding?
57
- _binding do
58
- inverse = metadata.inverse(target)
59
- if inverse
60
- set_base_metadata
61
- if base.referenced_many?
62
- target.send(inverse).delete(base)
63
- else
64
- target.send(metadata.inverse_setter(target), nil)
65
- end
47
+ def unbind_one
48
+ binding do
49
+ inverse = metadata.inverse(target)
50
+ if !inverse && metadata.inverse_of_field
51
+ inverse = base.__send__(metadata.inverse_of_field)
52
+ end
53
+ bind_foreign_key(base, nil)
54
+ bind_polymorphic_inverse_type(base, nil)
55
+ bind_inverse_of_field(base, nil)
56
+ if inverse
57
+ set_base_metadata
58
+ if base.referenced_many?
59
+ target.__send__(inverse).delete(base)
60
+ else
61
+ target.__send__("#{inverse}=", nil)
66
62
  end
67
63
  end
68
64
  end
69
65
  end
70
- alias :unbind_one :unbind
71
-
72
- private
73
-
74
- # Ensure that the metadata on the base is correct, for the cases
75
- # where we have multiple belongs to definitions and were are setting
76
- # different parents in memory in order.
77
- #
78
- # @api private
79
- #
80
- # @example Set the base metadata.
81
- # binding.set_base_metadata
82
- #
83
- # @return [ true, false ] If the metadata changed.
84
- #
85
- # @since 2.4.4
86
- def set_base_metadata
87
- inverse_metadata = metadata.inverse_metadata(target)
88
- if inverse_metadata != metadata && !inverse_metadata.nil?
89
- base.metadata = inverse_metadata
90
- end
91
- end
92
66
  end
93
67
  end
94
68
  end
@@ -1,8 +1,8 @@
1
1
  # encoding: utf-8
2
- module Mongoid # :nodoc:
3
- module Relations #:nodoc:
4
- module Bindings #:nodoc:
5
- module Referenced #:nodoc:
2
+ module Mongoid
3
+ module Relations
4
+ module Bindings
5
+ module Referenced
6
6
 
7
7
  # Binding class for references_many relations.
8
8
  class Many < Binding
@@ -17,14 +17,8 @@ module Mongoid # :nodoc:
17
17
  #
18
18
  # @since 2.0.0.rc.1
19
19
  def bind_one(doc)
20
- doc.you_must(metadata.foreign_key_setter, base.id)
21
- if metadata.type
22
- doc.you_must(metadata.type_setter, base.class.model_name)
23
- end
24
- unless _binding?
25
- _binding do
26
- doc.send(metadata.inverse_setter, base)
27
- end
20
+ binding do
21
+ bind_from_relational_parent(doc)
28
22
  end
29
23
  end
30
24
 
@@ -37,14 +31,8 @@ module Mongoid # :nodoc:
37
31
  #
38
32
  # @since 2.0.0.rc.1
39
33
  def unbind_one(doc)
40
- doc.you_must(metadata.foreign_key_setter, nil)
41
- if metadata.type
42
- doc.you_must(metadata.type_setter, nil)
43
- end
44
- unless _binding?
45
- _binding do
46
- doc.send(metadata.inverse_setter, nil)
47
- end
34
+ binding do
35
+ unbind_from_relational_parent(doc)
48
36
  end
49
37
  end
50
38
  end