mongoid-multi-db 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (276) hide show
  1. data/CHANGELOG.md +615 -0
  2. data/LICENSE +20 -0
  3. data/README.md +62 -0
  4. data/Rakefile +49 -0
  5. data/lib/config/locales/bg.yml +54 -0
  6. data/lib/config/locales/de.yml +54 -0
  7. data/lib/config/locales/en-GB.yml +55 -0
  8. data/lib/config/locales/en.yml +55 -0
  9. data/lib/config/locales/es.yml +52 -0
  10. data/lib/config/locales/fr.yml +55 -0
  11. data/lib/config/locales/hi.yml +46 -0
  12. data/lib/config/locales/hu.yml +57 -0
  13. data/lib/config/locales/id.yml +55 -0
  14. data/lib/config/locales/it.yml +52 -0
  15. data/lib/config/locales/ja.yml +50 -0
  16. data/lib/config/locales/kr.yml +47 -0
  17. data/lib/config/locales/nl.yml +52 -0
  18. data/lib/config/locales/pl.yml +52 -0
  19. data/lib/config/locales/pt-BR.yml +53 -0
  20. data/lib/config/locales/pt.yml +53 -0
  21. data/lib/config/locales/ro.yml +59 -0
  22. data/lib/config/locales/ru.yml +54 -0
  23. data/lib/config/locales/sv.yml +53 -0
  24. data/lib/config/locales/vi.yml +55 -0
  25. data/lib/config/locales/zh-CN.yml +46 -0
  26. data/lib/mongoid.rb +148 -0
  27. data/lib/mongoid/atomic.rb +230 -0
  28. data/lib/mongoid/atomic/modifiers.rb +243 -0
  29. data/lib/mongoid/atomic/paths.rb +3 -0
  30. data/lib/mongoid/atomic/paths/embedded.rb +43 -0
  31. data/lib/mongoid/atomic/paths/embedded/many.rb +44 -0
  32. data/lib/mongoid/atomic/paths/embedded/one.rb +43 -0
  33. data/lib/mongoid/atomic/paths/root.rb +40 -0
  34. data/lib/mongoid/attributes.rb +234 -0
  35. data/lib/mongoid/attributes/processing.rb +146 -0
  36. data/lib/mongoid/callbacks.rb +135 -0
  37. data/lib/mongoid/collection.rb +153 -0
  38. data/lib/mongoid/collection_proxy.rb +59 -0
  39. data/lib/mongoid/collections.rb +120 -0
  40. data/lib/mongoid/collections/master.rb +45 -0
  41. data/lib/mongoid/collections/operations.rb +44 -0
  42. data/lib/mongoid/collections/retry.rb +46 -0
  43. data/lib/mongoid/components.rb +96 -0
  44. data/lib/mongoid/config.rb +347 -0
  45. data/lib/mongoid/config/database.rb +186 -0
  46. data/lib/mongoid/config/replset_database.rb +82 -0
  47. data/lib/mongoid/connection_proxy.rb +30 -0
  48. data/lib/mongoid/contexts.rb +25 -0
  49. data/lib/mongoid/contexts/enumerable.rb +288 -0
  50. data/lib/mongoid/contexts/enumerable/sort.rb +43 -0
  51. data/lib/mongoid/contexts/mongo.rb +409 -0
  52. data/lib/mongoid/copyable.rb +48 -0
  53. data/lib/mongoid/criteria.rb +418 -0
  54. data/lib/mongoid/criterion/builder.rb +34 -0
  55. data/lib/mongoid/criterion/complex.rb +84 -0
  56. data/lib/mongoid/criterion/creational.rb +34 -0
  57. data/lib/mongoid/criterion/exclusion.rb +108 -0
  58. data/lib/mongoid/criterion/inclusion.rb +305 -0
  59. data/lib/mongoid/criterion/inspection.rb +22 -0
  60. data/lib/mongoid/criterion/optional.rb +232 -0
  61. data/lib/mongoid/criterion/selector.rb +153 -0
  62. data/lib/mongoid/cursor.rb +86 -0
  63. data/lib/mongoid/database_proxy.rb +97 -0
  64. data/lib/mongoid/default_scope.rb +36 -0
  65. data/lib/mongoid/dirty.rb +110 -0
  66. data/lib/mongoid/document.rb +280 -0
  67. data/lib/mongoid/errors.rb +17 -0
  68. data/lib/mongoid/errors/callback.rb +26 -0
  69. data/lib/mongoid/errors/document_not_found.rb +28 -0
  70. data/lib/mongoid/errors/eager_load.rb +25 -0
  71. data/lib/mongoid/errors/invalid_collection.rb +18 -0
  72. data/lib/mongoid/errors/invalid_database.rb +19 -0
  73. data/lib/mongoid/errors/invalid_field.rb +18 -0
  74. data/lib/mongoid/errors/invalid_find.rb +19 -0
  75. data/lib/mongoid/errors/invalid_options.rb +28 -0
  76. data/lib/mongoid/errors/invalid_time.rb +25 -0
  77. data/lib/mongoid/errors/invalid_type.rb +25 -0
  78. data/lib/mongoid/errors/mixed_relations.rb +37 -0
  79. data/lib/mongoid/errors/mongoid_error.rb +26 -0
  80. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +20 -0
  81. data/lib/mongoid/errors/unsaved_document.rb +23 -0
  82. data/lib/mongoid/errors/unsupported_version.rb +20 -0
  83. data/lib/mongoid/errors/validations.rb +23 -0
  84. data/lib/mongoid/extensions.rb +82 -0
  85. data/lib/mongoid/extensions/array/deletion.rb +29 -0
  86. data/lib/mongoid/extensions/false_class/equality.rb +26 -0
  87. data/lib/mongoid/extensions/hash/criteria_helpers.rb +45 -0
  88. data/lib/mongoid/extensions/hash/scoping.rb +25 -0
  89. data/lib/mongoid/extensions/integer/checks.rb +23 -0
  90. data/lib/mongoid/extensions/nil/collectionization.rb +23 -0
  91. data/lib/mongoid/extensions/object/checks.rb +29 -0
  92. data/lib/mongoid/extensions/object/reflections.rb +48 -0
  93. data/lib/mongoid/extensions/object/substitutable.rb +15 -0
  94. data/lib/mongoid/extensions/object/yoda.rb +44 -0
  95. data/lib/mongoid/extensions/object_id/conversions.rb +60 -0
  96. data/lib/mongoid/extensions/proc/scoping.rb +25 -0
  97. data/lib/mongoid/extensions/string/checks.rb +36 -0
  98. data/lib/mongoid/extensions/string/conversions.rb +22 -0
  99. data/lib/mongoid/extensions/string/inflections.rb +118 -0
  100. data/lib/mongoid/extensions/symbol/checks.rb +23 -0
  101. data/lib/mongoid/extensions/symbol/inflections.rb +66 -0
  102. data/lib/mongoid/extensions/true_class/equality.rb +26 -0
  103. data/lib/mongoid/extras.rb +31 -0
  104. data/lib/mongoid/factory.rb +46 -0
  105. data/lib/mongoid/fields.rb +332 -0
  106. data/lib/mongoid/fields/mappings.rb +41 -0
  107. data/lib/mongoid/fields/serializable.rb +201 -0
  108. data/lib/mongoid/fields/serializable/array.rb +49 -0
  109. data/lib/mongoid/fields/serializable/big_decimal.rb +42 -0
  110. data/lib/mongoid/fields/serializable/bignum.rb +10 -0
  111. data/lib/mongoid/fields/serializable/binary.rb +11 -0
  112. data/lib/mongoid/fields/serializable/boolean.rb +43 -0
  113. data/lib/mongoid/fields/serializable/date.rb +51 -0
  114. data/lib/mongoid/fields/serializable/date_time.rb +28 -0
  115. data/lib/mongoid/fields/serializable/fixnum.rb +10 -0
  116. data/lib/mongoid/fields/serializable/float.rb +32 -0
  117. data/lib/mongoid/fields/serializable/foreign_keys/array.rb +42 -0
  118. data/lib/mongoid/fields/serializable/foreign_keys/object.rb +47 -0
  119. data/lib/mongoid/fields/serializable/hash.rb +11 -0
  120. data/lib/mongoid/fields/serializable/integer.rb +44 -0
  121. data/lib/mongoid/fields/serializable/localized.rb +41 -0
  122. data/lib/mongoid/fields/serializable/nil_class.rb +38 -0
  123. data/lib/mongoid/fields/serializable/object.rb +11 -0
  124. data/lib/mongoid/fields/serializable/object_id.rb +31 -0
  125. data/lib/mongoid/fields/serializable/range.rb +42 -0
  126. data/lib/mongoid/fields/serializable/set.rb +42 -0
  127. data/lib/mongoid/fields/serializable/string.rb +27 -0
  128. data/lib/mongoid/fields/serializable/symbol.rb +27 -0
  129. data/lib/mongoid/fields/serializable/time.rb +23 -0
  130. data/lib/mongoid/fields/serializable/time_with_zone.rb +23 -0
  131. data/lib/mongoid/fields/serializable/timekeeping.rb +106 -0
  132. data/lib/mongoid/finders.rb +152 -0
  133. data/lib/mongoid/hierarchy.rb +120 -0
  134. data/lib/mongoid/identity.rb +92 -0
  135. data/lib/mongoid/identity_map.rb +119 -0
  136. data/lib/mongoid/indexes.rb +54 -0
  137. data/lib/mongoid/inspection.rb +54 -0
  138. data/lib/mongoid/javascript.rb +20 -0
  139. data/lib/mongoid/javascript/functions.yml +63 -0
  140. data/lib/mongoid/json.rb +16 -0
  141. data/lib/mongoid/keys.rb +144 -0
  142. data/lib/mongoid/logger.rb +39 -0
  143. data/lib/mongoid/matchers.rb +32 -0
  144. data/lib/mongoid/matchers/all.rb +21 -0
  145. data/lib/mongoid/matchers/and.rb +30 -0
  146. data/lib/mongoid/matchers/default.rb +70 -0
  147. data/lib/mongoid/matchers/exists.rb +23 -0
  148. data/lib/mongoid/matchers/gt.rb +21 -0
  149. data/lib/mongoid/matchers/gte.rb +21 -0
  150. data/lib/mongoid/matchers/in.rb +21 -0
  151. data/lib/mongoid/matchers/lt.rb +21 -0
  152. data/lib/mongoid/matchers/lte.rb +21 -0
  153. data/lib/mongoid/matchers/ne.rb +21 -0
  154. data/lib/mongoid/matchers/nin.rb +21 -0
  155. data/lib/mongoid/matchers/or.rb +33 -0
  156. data/lib/mongoid/matchers/size.rb +21 -0
  157. data/lib/mongoid/matchers/strategies.rb +93 -0
  158. data/lib/mongoid/multi_database.rb +31 -0
  159. data/lib/mongoid/multi_parameter_attributes.rb +106 -0
  160. data/lib/mongoid/named_scope.rb +146 -0
  161. data/lib/mongoid/nested_attributes.rb +54 -0
  162. data/lib/mongoid/observer.rb +170 -0
  163. data/lib/mongoid/paranoia.rb +158 -0
  164. data/lib/mongoid/persistence.rb +264 -0
  165. data/lib/mongoid/persistence/atomic.rb +223 -0
  166. data/lib/mongoid/persistence/atomic/add_to_set.rb +35 -0
  167. data/lib/mongoid/persistence/atomic/bit.rb +37 -0
  168. data/lib/mongoid/persistence/atomic/inc.rb +31 -0
  169. data/lib/mongoid/persistence/atomic/operation.rb +85 -0
  170. data/lib/mongoid/persistence/atomic/pop.rb +34 -0
  171. data/lib/mongoid/persistence/atomic/pull.rb +34 -0
  172. data/lib/mongoid/persistence/atomic/pull_all.rb +34 -0
  173. data/lib/mongoid/persistence/atomic/push.rb +31 -0
  174. data/lib/mongoid/persistence/atomic/push_all.rb +31 -0
  175. data/lib/mongoid/persistence/atomic/rename.rb +31 -0
  176. data/lib/mongoid/persistence/atomic/sets.rb +30 -0
  177. data/lib/mongoid/persistence/atomic/unset.rb +28 -0
  178. data/lib/mongoid/persistence/deletion.rb +32 -0
  179. data/lib/mongoid/persistence/insertion.rb +41 -0
  180. data/lib/mongoid/persistence/modification.rb +37 -0
  181. data/lib/mongoid/persistence/operations.rb +211 -0
  182. data/lib/mongoid/persistence/operations/embedded/insert.rb +42 -0
  183. data/lib/mongoid/persistence/operations/embedded/remove.rb +40 -0
  184. data/lib/mongoid/persistence/operations/insert.rb +34 -0
  185. data/lib/mongoid/persistence/operations/remove.rb +33 -0
  186. data/lib/mongoid/persistence/operations/update.rb +64 -0
  187. data/lib/mongoid/railtie.rb +126 -0
  188. data/lib/mongoid/railties/database.rake +182 -0
  189. data/lib/mongoid/railties/document.rb +12 -0
  190. data/lib/mongoid/relations.rb +144 -0
  191. data/lib/mongoid/relations/accessors.rb +138 -0
  192. data/lib/mongoid/relations/auto_save.rb +38 -0
  193. data/lib/mongoid/relations/binding.rb +26 -0
  194. data/lib/mongoid/relations/bindings.rb +9 -0
  195. data/lib/mongoid/relations/bindings/embedded/in.rb +69 -0
  196. data/lib/mongoid/relations/bindings/embedded/many.rb +93 -0
  197. data/lib/mongoid/relations/bindings/embedded/one.rb +61 -0
  198. data/lib/mongoid/relations/bindings/referenced/in.rb +76 -0
  199. data/lib/mongoid/relations/bindings/referenced/many.rb +54 -0
  200. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +51 -0
  201. data/lib/mongoid/relations/bindings/referenced/one.rb +58 -0
  202. data/lib/mongoid/relations/builder.rb +57 -0
  203. data/lib/mongoid/relations/builders.rb +83 -0
  204. data/lib/mongoid/relations/builders/embedded/in.rb +29 -0
  205. data/lib/mongoid/relations/builders/embedded/many.rb +40 -0
  206. data/lib/mongoid/relations/builders/embedded/one.rb +30 -0
  207. data/lib/mongoid/relations/builders/nested_attributes/many.rb +110 -0
  208. data/lib/mongoid/relations/builders/nested_attributes/one.rb +135 -0
  209. data/lib/mongoid/relations/builders/referenced/in.rb +26 -0
  210. data/lib/mongoid/relations/builders/referenced/many.rb +27 -0
  211. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +38 -0
  212. data/lib/mongoid/relations/builders/referenced/one.rb +26 -0
  213. data/lib/mongoid/relations/cascading.rb +56 -0
  214. data/lib/mongoid/relations/cascading/delete.rb +19 -0
  215. data/lib/mongoid/relations/cascading/destroy.rb +26 -0
  216. data/lib/mongoid/relations/cascading/nullify.rb +18 -0
  217. data/lib/mongoid/relations/cascading/strategy.rb +26 -0
  218. data/lib/mongoid/relations/constraint.rb +42 -0
  219. data/lib/mongoid/relations/conversions.rb +35 -0
  220. data/lib/mongoid/relations/cyclic.rb +103 -0
  221. data/lib/mongoid/relations/embedded/atomic.rb +89 -0
  222. data/lib/mongoid/relations/embedded/atomic/operation.rb +63 -0
  223. data/lib/mongoid/relations/embedded/atomic/pull.rb +65 -0
  224. data/lib/mongoid/relations/embedded/atomic/push_all.rb +59 -0
  225. data/lib/mongoid/relations/embedded/atomic/set.rb +61 -0
  226. data/lib/mongoid/relations/embedded/atomic/unset.rb +41 -0
  227. data/lib/mongoid/relations/embedded/in.rb +220 -0
  228. data/lib/mongoid/relations/embedded/many.rb +560 -0
  229. data/lib/mongoid/relations/embedded/one.rb +206 -0
  230. data/lib/mongoid/relations/embedded/sort.rb +31 -0
  231. data/lib/mongoid/relations/macros.rb +310 -0
  232. data/lib/mongoid/relations/many.rb +135 -0
  233. data/lib/mongoid/relations/metadata.rb +919 -0
  234. data/lib/mongoid/relations/nested_builder.rb +75 -0
  235. data/lib/mongoid/relations/one.rb +36 -0
  236. data/lib/mongoid/relations/options.rb +47 -0
  237. data/lib/mongoid/relations/polymorphic.rb +40 -0
  238. data/lib/mongoid/relations/proxy.rb +145 -0
  239. data/lib/mongoid/relations/referenced/batch.rb +72 -0
  240. data/lib/mongoid/relations/referenced/batch/insert.rb +57 -0
  241. data/lib/mongoid/relations/referenced/in.rb +262 -0
  242. data/lib/mongoid/relations/referenced/many.rb +623 -0
  243. data/lib/mongoid/relations/referenced/many_to_many.rb +396 -0
  244. data/lib/mongoid/relations/referenced/one.rb +272 -0
  245. data/lib/mongoid/relations/reflections.rb +62 -0
  246. data/lib/mongoid/relations/synchronization.rb +153 -0
  247. data/lib/mongoid/relations/targets.rb +2 -0
  248. data/lib/mongoid/relations/targets/enumerable.rb +372 -0
  249. data/lib/mongoid/reloading.rb +91 -0
  250. data/lib/mongoid/safety.rb +105 -0
  251. data/lib/mongoid/scope.rb +31 -0
  252. data/lib/mongoid/serialization.rb +134 -0
  253. data/lib/mongoid/sharding.rb +61 -0
  254. data/lib/mongoid/state.rb +97 -0
  255. data/lib/mongoid/threaded.rb +530 -0
  256. data/lib/mongoid/threaded/lifecycle.rb +192 -0
  257. data/lib/mongoid/timestamps.rb +15 -0
  258. data/lib/mongoid/timestamps/created.rb +24 -0
  259. data/lib/mongoid/timestamps/timeless.rb +50 -0
  260. data/lib/mongoid/timestamps/updated.rb +26 -0
  261. data/lib/mongoid/validations.rb +140 -0
  262. data/lib/mongoid/validations/associated.rb +46 -0
  263. data/lib/mongoid/validations/uniqueness.rb +145 -0
  264. data/lib/mongoid/version.rb +4 -0
  265. data/lib/mongoid/versioning.rb +185 -0
  266. data/lib/rack/mongoid.rb +2 -0
  267. data/lib/rack/mongoid/middleware/identity_map.rb +38 -0
  268. data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
  269. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +20 -0
  270. data/lib/rails/generators/mongoid/model/model_generator.rb +24 -0
  271. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +19 -0
  272. data/lib/rails/generators/mongoid/observer/observer_generator.rb +17 -0
  273. data/lib/rails/generators/mongoid/observer/templates/observer.rb.tt +4 -0
  274. data/lib/rails/generators/mongoid_generator.rb +70 -0
  275. data/lib/rails/mongoid.rb +91 -0
  276. metadata +465 -0
@@ -0,0 +1,75 @@
1
+ # encoding: utf-8
2
+ module Mongoid # :nodoc:
3
+ module Relations #:nodoc:
4
+
5
+ # This is the superclass for builders that are in charge of handling
6
+ # creation, deletion, and updates of documents through that ever so lovely
7
+ # #accepts_nested_attributes_for.
8
+ class NestedBuilder
9
+ attr_accessor :attributes, :existing, :metadata, :options
10
+
11
+ # Determines if destroys are allowed for this document.
12
+ #
13
+ # @example Do we allow a destroy?
14
+ # builder.allow_destroy?
15
+ #
16
+ # @return [ true, false ] True if the allow destroy option was set.
17
+ #
18
+ # @since 2.0.0.rc.1
19
+ def allow_destroy?
20
+ options[:allow_destroy] || false
21
+ end
22
+
23
+ # Returns the reject if option defined with the macro.
24
+ #
25
+ # @example Is there a reject proc?
26
+ # builder.reject?
27
+ #
28
+ # @param The parent document of the relation
29
+ # @param [ Hash ] attrs The attributes to check for rejection.
30
+ #
31
+ # @return [ true, false ] True and call proc or method if rejectable, false if not.
32
+ #
33
+ # @since 2.0.0.rc.1
34
+ def reject?(document, attrs)
35
+ case callback = options[:reject_if]
36
+ when Symbol
37
+ document.method(callback).arity == 0 ? document.send(callback) : document.send(callback, attrs)
38
+ when Proc
39
+ callback.call(attrs)
40
+ else
41
+ false
42
+ end
43
+ end
44
+
45
+ # Determines if only updates can occur. Only valid for one-to-one
46
+ # relations.
47
+ #
48
+ # @example Is this update only?
49
+ # builder.update_only?
50
+ #
51
+ # @return [ true, false ] True if the update_only option was set.
52
+ #
53
+ # @since 2.0.0.rc.1
54
+ def update_only?
55
+ options[:update_only] || false
56
+ end
57
+
58
+ # Convert an id to its appropriate type.
59
+ #
60
+ # @todo Durran: Move this into a common reusable place.
61
+ #
62
+ # @example Convert the id.
63
+ # builder.convert_id("4d371b444835d98b8b000010")
64
+ #
65
+ # @param [ String ] id The id, usually coming from the form.
66
+ #
67
+ # @return [ BSON::ObjectId, String, Object ] The converted id.
68
+ #
69
+ # @since 2.0.0.rc.6
70
+ def convert_id(id)
71
+ metadata.constraint.convert(id)
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+ module Mongoid # :nodoc:
3
+ module Relations #:nodoc:
4
+
5
+ # This is the superclass for one to one relations and defines the common
6
+ # behaviour or those proxies.
7
+ class One < Proxy
8
+
9
+ # Get all the documents in the relation that are loaded into memory.
10
+ #
11
+ # @example Get the in memory documents.
12
+ # relation.in_memory
13
+ #
14
+ # @return [ Array<Document> ] The documents in memory.
15
+ #
16
+ # @since 2.1.0
17
+ def in_memory
18
+ [ target ]
19
+ end
20
+
21
+ # Since method_missing is overridden we should override this as well.
22
+ #
23
+ # @example Does the proxy respond to the method?
24
+ # relation.respond_to?(:name)
25
+ #
26
+ # @param [ Symbol ] name The method name.
27
+ #
28
+ # @return [ true, false ] If the proxy responds to the method.
29
+ #
30
+ # @since 2.1.8
31
+ def respond_to?(name, include_private = false)
32
+ target.respond_to?(name, include_private) || super
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+ module Mongoid # :nodoc:
3
+ module Relations #:nodoc:
4
+
5
+ # This module contains the validating logic for options passed to relation
6
+ # macros.
7
+ module Options
8
+ extend self
9
+
10
+ # These options are available to all relations.
11
+ COMMON = [
12
+ :class_name,
13
+ :extend,
14
+ :inverse_class_name,
15
+ :inverse_of,
16
+ :name,
17
+ :relation,
18
+ :validate
19
+ ]
20
+
21
+ # Determine if the provided options are valid for the relation.
22
+ #
23
+ # @example Check the options.
24
+ # Options.validate!(:name => :comments)
25
+ #
26
+ # @param [ Hash ] options The options to check.
27
+ #
28
+ # @raise [ ArgumentError ] If the options are invalid.
29
+ #
30
+ # @return [ true, false ] If the options are valid.
31
+ #
32
+ # @since 2.1.0
33
+ def validate!(options)
34
+ valid_options = options[:relation].valid_options.concat(COMMON)
35
+ options.keys.each do |key|
36
+ if !valid_options.include?(key)
37
+ raise Errors::InvalidOptions.new(
38
+ options[:name],
39
+ key,
40
+ valid_options
41
+ )
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+ module Mongoid # :nodoc:
3
+ module Relations #:nodoc:
4
+
5
+ # This module contains the behaviour for handling polymorphic relational
6
+ # associations.
7
+ module Polymorphic
8
+ extend ActiveSupport::Concern
9
+
10
+ included do
11
+ class_attribute :polymorphic
12
+ end
13
+
14
+ module ClassMethods #:nodoc:
15
+
16
+ # Attempts to set up the information needed to handle a polymorphic
17
+ # relation, if the metadata checks out.
18
+ #
19
+ # @example Set up the polymorphic information.
20
+ # Movie.polymorph(metadata)
21
+ #
22
+ # @param [ Metadata ] metadata The relation metadata.
23
+ #
24
+ # @return [ Class ] The class being set up.
25
+ #
26
+ # @since 2.0.0.rc.1
27
+ def polymorph(metadata)
28
+ tap do |klass|
29
+ if metadata.polymorphic?
30
+ klass.polymorphic = true
31
+ if metadata.relation.stores_foreign_key?
32
+ field(metadata.inverse_type, :type => String)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,145 @@
1
+ # encoding: utf-8
2
+ module Mongoid # :nodoc:
3
+ module Relations #:nodoc:
4
+
5
+ # This class is the superclass for all relation proxy objects, and contains
6
+ # common behaviour for all of them.
7
+ class Proxy
8
+ include Threaded::Lifecycle
9
+
10
+ # We undefine most methods to get them sent through to the target.
11
+ instance_methods.each do |method|
12
+ undef_method(method) unless
13
+ method =~ /(^__|^send$|^object_id$|^extend$|^respond_to\?$|^tap$)/
14
+ end
15
+
16
+ attr_accessor :base, :loaded, :metadata, :target
17
+
18
+ # Backwards compatibility with Mongoid beta releases.
19
+ delegate :klass, :to => :metadata
20
+ delegate :bind_one, :unbind_one, :to => :binding
21
+
22
+ # Convenience for setting the target and the metadata properties since
23
+ # all proxies will need to do this.
24
+ #
25
+ # @example Initialize the proxy.
26
+ # proxy.init(person, name, metadata)
27
+ #
28
+ # @param [ Document ] base The base document on the proxy.
29
+ # @param [ Document, Array<Document> ] target The target of the proxy.
30
+ # @param [ Metadata ] metadata The relation's metadata.
31
+ #
32
+ # @since 2.0.0.rc.1
33
+ def init(base, target, metadata)
34
+ @base, @target, @metadata = base, target, metadata
35
+ yield(self) if block_given?
36
+ extend metadata.extension if metadata.extension?
37
+ end
38
+
39
+ # The default substitutable object for a relation proxy is the clone of
40
+ # the target.
41
+ #
42
+ # @example Get the substitutable.
43
+ # proxy.substitutable
44
+ #
45
+ # @return [ Object ] A clone of the target.
46
+ #
47
+ # @since 2.1.6
48
+ def substitutable
49
+ target
50
+ end
51
+
52
+ protected
53
+
54
+ # Get the collection from the root of the hierarchy.
55
+ #
56
+ # @example Get the collection.
57
+ # relation.collection
58
+ #
59
+ # @return [ Collection ] The root's collection.
60
+ #
61
+ # @since 2.0.0
62
+ def collection
63
+ root = base._root
64
+ root.collection unless root.embedded?
65
+ end
66
+
67
+ # Return a new document for the type of class we want to instantiate.
68
+ # If the type is provided use that, otherwise the klass from the
69
+ # metadata.
70
+ #
71
+ # @example Get an instantiated document.
72
+ # proxy.instantiated(Person)
73
+ #
74
+ # @param [ Class ] type The type of class to instantiate.
75
+ #
76
+ # @return [ Document ] The freshly created document.
77
+ #
78
+ # @since 2.0.0.rc.1
79
+ def instantiated(type = nil)
80
+ type ? type.new : metadata.klass.new
81
+ end
82
+
83
+ # Takes the supplied document and sets the metadata on it.
84
+ #
85
+ # @example Set the metadata.
86
+ # proxt.characterize_one(name)
87
+ #
88
+ # @param [ Document ] document The document to set on.
89
+ #
90
+ # @since 2.0.0.rc.4
91
+ def characterize_one(document)
92
+ document.metadata = metadata unless document.metadata
93
+ end
94
+
95
+ # Default behavior of method missing should be to delegate all calls
96
+ # to the target of the proxy. This can be overridden in special cases.
97
+ #
98
+ # @param [ String, Symbol ] name The name of the method.
99
+ # @param [ Array ] *args The arguments passed to the method.
100
+ def method_missing(name, *args, &block)
101
+ target.send(name, *args, &block)
102
+ end
103
+
104
+ # When the base document illegally references an embedded document this
105
+ # error will get raised.
106
+ #
107
+ # @example Raise the error.
108
+ # relation.raise_mixed
109
+ #
110
+ # @raise [ Errors::MixedRelations ] The error.
111
+ #
112
+ # @since 2.0.0
113
+ def raise_mixed
114
+ raise Errors::MixedRelations.new(base.class, metadata.klass)
115
+ end
116
+
117
+ # When the base is not yet saved and the user calls create or create!
118
+ # on the relation, this error will get raised.
119
+ #
120
+ # @example Raise the error.
121
+ # relation.raise_unsaved(post)
122
+ #
123
+ # @param [ Document ] doc The child document getting created.
124
+ #
125
+ # @raise [ Errors::UnsavedDocument ] The error.
126
+ #
127
+ # @since 2.0.0.rc.6
128
+ def raise_unsaved(doc)
129
+ raise Errors::UnsavedDocument.new(base, doc)
130
+ end
131
+
132
+ # Get the class of the root document in the hierarchy.
133
+ #
134
+ # @example Get the root's class.
135
+ # proxy.root_class
136
+ #
137
+ # @return [ Class ] The root class.
138
+ #
139
+ # @since 2.1.8
140
+ def root_class
141
+ @root_class ||= base._root.class
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,72 @@
1
+ # encoding: utf-8
2
+ require "mongoid/relations/referenced/batch/insert"
3
+
4
+ module Mongoid #:nodoc:
5
+ module Relations #:nodoc:
6
+ module Referenced #:nodoc:
7
+
8
+ # This module provides the ability for single insert calls to be batch
9
+ # inserted.
10
+ module Batch
11
+
12
+ private
13
+
14
+ # Executes a number of save calls in a single batch. Mongoid will
15
+ # intercept all database inserts while in this block and combine them
16
+ # into a single database call. When the block concludes the batch
17
+ # insert will occur.
18
+ #
19
+ # Since the collection is accessed through the class it would not be
20
+ # thread safe to give it state so we access the atomic updater via the
21
+ # current thread.
22
+ #
23
+ # @note This operation is not safe when attemping to do illegal updates
24
+ # for different objects or collections, since the updator is not
25
+ # scoped on the thread. This is meant for Mongoid internal use only
26
+ # to keep existing design clean.
27
+ #
28
+ # @example Batch update multiple appends.
29
+ # batched do
30
+ # person.posts << [ post_one, post_two, post_three ]
31
+ # end
32
+ #
33
+ # @todo Durran: Move executions to thread local stack.
34
+ #
35
+ # @param [ Proc ] block The block to execute.
36
+ #
37
+ # @return [ Object ] The result of the operation.
38
+ #
39
+ # @since 2.0.2, batch-relational-insert
40
+ def batched(&block)
41
+ inserter = Threaded.insert ||= Insert.new
42
+ count_executions(&block)
43
+ ensure
44
+ if @executions.zero?
45
+ Threaded.insert = nil
46
+ inserter.execute(collection)
47
+ end
48
+ end
49
+
50
+ # Execute the block, incrementing the executions before the call and
51
+ # decrementing them after in order to be able to nest blocks within
52
+ # each other.
53
+ #
54
+ # @todo Durran: Combine common code with embedded atomics.
55
+ #
56
+ # @example Execute and increment.
57
+ # execute { block.call }
58
+ #
59
+ # @param [ Proc ] block The block to call.
60
+ #
61
+ # @since 2.0.2, batch-relational-insert
62
+ def count_executions
63
+ @executions ||= 0
64
+ @executions += 1
65
+ yield
66
+ ensure
67
+ @executions -=1
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,57 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Relations #:nodoc:
4
+ module Referenced #:nodoc:
5
+ module Batch #:nodoc:
6
+
7
+ # Handles all the batch insert collection.
8
+ class Insert
9
+ attr_accessor :documents, :options
10
+
11
+ # Consumes an execution that was supposed to hit the database, but is
12
+ # now being deferred to later in favor of a single batch insert.
13
+ #
14
+ # @example Consume the operation.
15
+ # set.consume({ "field" => "value" }, { :safe => true })
16
+ #
17
+ # @param [ Hash ] document The document to collect.
18
+ # @param [ Hash ] options The persistence options.
19
+ #
20
+ # @option options [ true, false ] :safe Persist in safe mode.
21
+ #
22
+ # @since 2.0.2, batch-relational-insert
23
+ def consume(document, options = {})
24
+ @consumed, @options = true, options
25
+ (@documents ||= []).push(document)
26
+ end
27
+
28
+ # Has this operation consumed any executions?
29
+ #
30
+ # @example Is this consumed?
31
+ # insert.consumed?
32
+ #
33
+ # @return [ true, false ] If the operation has consumed anything.
34
+ #
35
+ # @since 2.0.2, batch-relational-insert
36
+ def consumed?
37
+ !!@consumed
38
+ end
39
+
40
+ # Execute the batch insert operation on the collection.
41
+ #
42
+ # @example Execute the operation.
43
+ # insert.execute(collection)
44
+ #
45
+ # @param [ Collection ] collection The root collection.
46
+ #
47
+ # @since 2.0.2, batch-relational-insert
48
+ def execute(collection)
49
+ if collection && consumed?
50
+ collection.insert(documents, options)
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end