mongoid-braxton 2.0.2

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 (226) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +50 -0
  3. data/Rakefile +51 -0
  4. data/lib/config/locales/bg.yml +41 -0
  5. data/lib/config/locales/de.yml +41 -0
  6. data/lib/config/locales/en.yml +45 -0
  7. data/lib/config/locales/es.yml +41 -0
  8. data/lib/config/locales/fr.yml +42 -0
  9. data/lib/config/locales/hu.yml +44 -0
  10. data/lib/config/locales/id.yml +46 -0
  11. data/lib/config/locales/it.yml +39 -0
  12. data/lib/config/locales/ja.yml +40 -0
  13. data/lib/config/locales/kr.yml +65 -0
  14. data/lib/config/locales/nl.yml +39 -0
  15. data/lib/config/locales/pl.yml +39 -0
  16. data/lib/config/locales/pt-BR.yml +40 -0
  17. data/lib/config/locales/pt.yml +40 -0
  18. data/lib/config/locales/ro.yml +46 -0
  19. data/lib/config/locales/ru.yml +41 -0
  20. data/lib/config/locales/sv.yml +40 -0
  21. data/lib/config/locales/vi.yml +45 -0
  22. data/lib/config/locales/zh-CN.yml +33 -0
  23. data/lib/mongoid.rb +140 -0
  24. data/lib/mongoid/atomicity.rb +111 -0
  25. data/lib/mongoid/attributes.rb +185 -0
  26. data/lib/mongoid/attributes/processing.rb +145 -0
  27. data/lib/mongoid/callbacks.rb +23 -0
  28. data/lib/mongoid/collection.rb +137 -0
  29. data/lib/mongoid/collections.rb +71 -0
  30. data/lib/mongoid/collections/master.rb +37 -0
  31. data/lib/mongoid/collections/operations.rb +42 -0
  32. data/lib/mongoid/collections/retry.rb +39 -0
  33. data/lib/mongoid/components.rb +45 -0
  34. data/lib/mongoid/config.rb +349 -0
  35. data/lib/mongoid/config/database.rb +167 -0
  36. data/lib/mongoid/config/replset_database.rb +78 -0
  37. data/lib/mongoid/contexts.rb +19 -0
  38. data/lib/mongoid/contexts/enumerable.rb +275 -0
  39. data/lib/mongoid/contexts/enumerable/sort.rb +43 -0
  40. data/lib/mongoid/contexts/mongo.rb +345 -0
  41. data/lib/mongoid/copyable.rb +46 -0
  42. data/lib/mongoid/criteria.rb +357 -0
  43. data/lib/mongoid/criterion/builder.rb +34 -0
  44. data/lib/mongoid/criterion/complex.rb +34 -0
  45. data/lib/mongoid/criterion/creational.rb +34 -0
  46. data/lib/mongoid/criterion/exclusion.rb +108 -0
  47. data/lib/mongoid/criterion/inclusion.rb +198 -0
  48. data/lib/mongoid/criterion/inspection.rb +22 -0
  49. data/lib/mongoid/criterion/optional.rb +193 -0
  50. data/lib/mongoid/criterion/selector.rb +143 -0
  51. data/lib/mongoid/criterion/unconvertable.rb +20 -0
  52. data/lib/mongoid/cursor.rb +86 -0
  53. data/lib/mongoid/default_scope.rb +36 -0
  54. data/lib/mongoid/dirty.rb +253 -0
  55. data/lib/mongoid/document.rb +284 -0
  56. data/lib/mongoid/errors.rb +13 -0
  57. data/lib/mongoid/errors/document_not_found.rb +29 -0
  58. data/lib/mongoid/errors/invalid_collection.rb +19 -0
  59. data/lib/mongoid/errors/invalid_database.rb +20 -0
  60. data/lib/mongoid/errors/invalid_field.rb +19 -0
  61. data/lib/mongoid/errors/invalid_options.rb +16 -0
  62. data/lib/mongoid/errors/invalid_type.rb +26 -0
  63. data/lib/mongoid/errors/mixed_relations.rb +37 -0
  64. data/lib/mongoid/errors/mongoid_error.rb +27 -0
  65. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +21 -0
  66. data/lib/mongoid/errors/unsaved_document.rb +23 -0
  67. data/lib/mongoid/errors/unsupported_version.rb +21 -0
  68. data/lib/mongoid/errors/validations.rb +24 -0
  69. data/lib/mongoid/extensions.rb +123 -0
  70. data/lib/mongoid/extensions/array/conversions.rb +23 -0
  71. data/lib/mongoid/extensions/array/parentization.rb +13 -0
  72. data/lib/mongoid/extensions/big_decimal/conversions.rb +19 -0
  73. data/lib/mongoid/extensions/binary/conversions.rb +17 -0
  74. data/lib/mongoid/extensions/boolean/conversions.rb +27 -0
  75. data/lib/mongoid/extensions/date/conversions.rb +25 -0
  76. data/lib/mongoid/extensions/datetime/conversions.rb +12 -0
  77. data/lib/mongoid/extensions/false_class/equality.rb +13 -0
  78. data/lib/mongoid/extensions/float/conversions.rb +20 -0
  79. data/lib/mongoid/extensions/hash/conversions.rb +19 -0
  80. data/lib/mongoid/extensions/hash/criteria_helpers.rb +22 -0
  81. data/lib/mongoid/extensions/hash/scoping.rb +12 -0
  82. data/lib/mongoid/extensions/integer/conversions.rb +20 -0
  83. data/lib/mongoid/extensions/nil/collectionization.rb +12 -0
  84. data/lib/mongoid/extensions/object/checks.rb +32 -0
  85. data/lib/mongoid/extensions/object/conversions.rb +25 -0
  86. data/lib/mongoid/extensions/object/reflections.rb +17 -0
  87. data/lib/mongoid/extensions/object/yoda.rb +27 -0
  88. data/lib/mongoid/extensions/object_id/conversions.rb +96 -0
  89. data/lib/mongoid/extensions/proc/scoping.rb +12 -0
  90. data/lib/mongoid/extensions/range/conversions.rb +25 -0
  91. data/lib/mongoid/extensions/set/conversions.rb +20 -0
  92. data/lib/mongoid/extensions/string/conversions.rb +34 -0
  93. data/lib/mongoid/extensions/string/inflections.rb +97 -0
  94. data/lib/mongoid/extensions/symbol/conversions.rb +21 -0
  95. data/lib/mongoid/extensions/symbol/inflections.rb +40 -0
  96. data/lib/mongoid/extensions/time_conversions.rb +38 -0
  97. data/lib/mongoid/extensions/true_class/equality.rb +13 -0
  98. data/lib/mongoid/extras.rb +42 -0
  99. data/lib/mongoid/factory.rb +37 -0
  100. data/lib/mongoid/field.rb +162 -0
  101. data/lib/mongoid/fields.rb +183 -0
  102. data/lib/mongoid/finders.rb +127 -0
  103. data/lib/mongoid/hierarchy.rb +85 -0
  104. data/lib/mongoid/identity.rb +92 -0
  105. data/lib/mongoid/indexes.rb +38 -0
  106. data/lib/mongoid/inspection.rb +54 -0
  107. data/lib/mongoid/javascript.rb +21 -0
  108. data/lib/mongoid/javascript/functions.yml +37 -0
  109. data/lib/mongoid/json.rb +16 -0
  110. data/lib/mongoid/keys.rb +131 -0
  111. data/lib/mongoid/logger.rb +18 -0
  112. data/lib/mongoid/matchers.rb +32 -0
  113. data/lib/mongoid/matchers/all.rb +11 -0
  114. data/lib/mongoid/matchers/default.rb +70 -0
  115. data/lib/mongoid/matchers/exists.rb +13 -0
  116. data/lib/mongoid/matchers/gt.rb +11 -0
  117. data/lib/mongoid/matchers/gte.rb +11 -0
  118. data/lib/mongoid/matchers/in.rb +11 -0
  119. data/lib/mongoid/matchers/lt.rb +11 -0
  120. data/lib/mongoid/matchers/lte.rb +11 -0
  121. data/lib/mongoid/matchers/ne.rb +11 -0
  122. data/lib/mongoid/matchers/nin.rb +11 -0
  123. data/lib/mongoid/matchers/or.rb +30 -0
  124. data/lib/mongoid/matchers/size.rb +11 -0
  125. data/lib/mongoid/matchers/strategies.rb +63 -0
  126. data/lib/mongoid/multi_database.rb +11 -0
  127. data/lib/mongoid/multi_parameter_attributes.rb +82 -0
  128. data/lib/mongoid/named_scope.rb +137 -0
  129. data/lib/mongoid/nested_attributes.rb +51 -0
  130. data/lib/mongoid/observer.rb +67 -0
  131. data/lib/mongoid/paranoia.rb +103 -0
  132. data/lib/mongoid/paths.rb +61 -0
  133. data/lib/mongoid/persistence.rb +240 -0
  134. data/lib/mongoid/persistence/atomic.rb +88 -0
  135. data/lib/mongoid/persistence/atomic/add_to_set.rb +32 -0
  136. data/lib/mongoid/persistence/atomic/inc.rb +28 -0
  137. data/lib/mongoid/persistence/atomic/operation.rb +44 -0
  138. data/lib/mongoid/persistence/atomic/pull_all.rb +33 -0
  139. data/lib/mongoid/persistence/atomic/push.rb +28 -0
  140. data/lib/mongoid/persistence/command.rb +71 -0
  141. data/lib/mongoid/persistence/insert.rb +53 -0
  142. data/lib/mongoid/persistence/insert_embedded.rb +43 -0
  143. data/lib/mongoid/persistence/remove.rb +44 -0
  144. data/lib/mongoid/persistence/remove_all.rb +40 -0
  145. data/lib/mongoid/persistence/remove_embedded.rb +48 -0
  146. data/lib/mongoid/persistence/update.rb +77 -0
  147. data/lib/mongoid/railtie.rb +139 -0
  148. data/lib/mongoid/railties/database.rake +171 -0
  149. data/lib/mongoid/railties/document.rb +12 -0
  150. data/lib/mongoid/relations.rb +107 -0
  151. data/lib/mongoid/relations/accessors.rb +175 -0
  152. data/lib/mongoid/relations/auto_save.rb +34 -0
  153. data/lib/mongoid/relations/binding.rb +26 -0
  154. data/lib/mongoid/relations/bindings.rb +9 -0
  155. data/lib/mongoid/relations/bindings/embedded/in.rb +82 -0
  156. data/lib/mongoid/relations/bindings/embedded/many.rb +98 -0
  157. data/lib/mongoid/relations/bindings/embedded/one.rb +66 -0
  158. data/lib/mongoid/relations/bindings/referenced/in.rb +74 -0
  159. data/lib/mongoid/relations/bindings/referenced/many.rb +96 -0
  160. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +103 -0
  161. data/lib/mongoid/relations/bindings/referenced/one.rb +66 -0
  162. data/lib/mongoid/relations/builder.rb +42 -0
  163. data/lib/mongoid/relations/builders.rb +79 -0
  164. data/lib/mongoid/relations/builders/embedded/in.rb +25 -0
  165. data/lib/mongoid/relations/builders/embedded/many.rb +32 -0
  166. data/lib/mongoid/relations/builders/embedded/one.rb +26 -0
  167. data/lib/mongoid/relations/builders/nested_attributes/many.rb +126 -0
  168. data/lib/mongoid/relations/builders/nested_attributes/one.rb +135 -0
  169. data/lib/mongoid/relations/builders/referenced/in.rb +29 -0
  170. data/lib/mongoid/relations/builders/referenced/many.rb +47 -0
  171. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +29 -0
  172. data/lib/mongoid/relations/builders/referenced/one.rb +27 -0
  173. data/lib/mongoid/relations/cascading.rb +55 -0
  174. data/lib/mongoid/relations/cascading/delete.rb +19 -0
  175. data/lib/mongoid/relations/cascading/destroy.rb +19 -0
  176. data/lib/mongoid/relations/cascading/nullify.rb +18 -0
  177. data/lib/mongoid/relations/cascading/strategy.rb +26 -0
  178. data/lib/mongoid/relations/constraint.rb +42 -0
  179. data/lib/mongoid/relations/cyclic.rb +103 -0
  180. data/lib/mongoid/relations/embedded/atomic.rb +86 -0
  181. data/lib/mongoid/relations/embedded/atomic/operation.rb +63 -0
  182. data/lib/mongoid/relations/embedded/atomic/pull.rb +65 -0
  183. data/lib/mongoid/relations/embedded/atomic/push_all.rb +59 -0
  184. data/lib/mongoid/relations/embedded/atomic/set.rb +61 -0
  185. data/lib/mongoid/relations/embedded/atomic/unset.rb +41 -0
  186. data/lib/mongoid/relations/embedded/in.rb +173 -0
  187. data/lib/mongoid/relations/embedded/many.rb +499 -0
  188. data/lib/mongoid/relations/embedded/one.rb +170 -0
  189. data/lib/mongoid/relations/macros.rb +310 -0
  190. data/lib/mongoid/relations/many.rb +215 -0
  191. data/lib/mongoid/relations/metadata.rb +539 -0
  192. data/lib/mongoid/relations/nested_builder.rb +68 -0
  193. data/lib/mongoid/relations/one.rb +47 -0
  194. data/lib/mongoid/relations/polymorphic.rb +54 -0
  195. data/lib/mongoid/relations/proxy.rb +143 -0
  196. data/lib/mongoid/relations/referenced/batch.rb +71 -0
  197. data/lib/mongoid/relations/referenced/batch/insert.rb +57 -0
  198. data/lib/mongoid/relations/referenced/in.rb +216 -0
  199. data/lib/mongoid/relations/referenced/many.rb +516 -0
  200. data/lib/mongoid/relations/referenced/many_to_many.rb +396 -0
  201. data/lib/mongoid/relations/referenced/one.rb +222 -0
  202. data/lib/mongoid/relations/reflections.rb +45 -0
  203. data/lib/mongoid/safe.rb +23 -0
  204. data/lib/mongoid/safety.rb +207 -0
  205. data/lib/mongoid/scope.rb +31 -0
  206. data/lib/mongoid/serialization.rb +99 -0
  207. data/lib/mongoid/sharding.rb +51 -0
  208. data/lib/mongoid/state.rb +67 -0
  209. data/lib/mongoid/timestamps.rb +14 -0
  210. data/lib/mongoid/timestamps/created.rb +31 -0
  211. data/lib/mongoid/timestamps/updated.rb +33 -0
  212. data/lib/mongoid/validations.rb +124 -0
  213. data/lib/mongoid/validations/associated.rb +44 -0
  214. data/lib/mongoid/validations/referenced.rb +58 -0
  215. data/lib/mongoid/validations/uniqueness.rb +85 -0
  216. data/lib/mongoid/version.rb +4 -0
  217. data/lib/mongoid/versioning.rb +113 -0
  218. data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
  219. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +20 -0
  220. data/lib/rails/generators/mongoid/model/model_generator.rb +24 -0
  221. data/lib/rails/generators/mongoid/model/templates/model.rb +19 -0
  222. data/lib/rails/generators/mongoid/observer/observer_generator.rb +17 -0
  223. data/lib/rails/generators/mongoid/observer/templates/observer.rb +4 -0
  224. data/lib/rails/generators/mongoid_generator.rb +70 -0
  225. data/lib/rails/mongoid.rb +58 -0
  226. metadata +406 -0
@@ -0,0 +1,68 @@
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 [ Hash ] attrs The attributes to check for rejection.
29
+ #
30
+ # @return [ true, false ] True and call proc if rejectable, false if not.
31
+ #
32
+ # @since 2.0.0.rc.1
33
+ def reject?(attrs)
34
+ criteria = options[:reject_if]
35
+ criteria ? criteria.call(attrs) : false
36
+ end
37
+
38
+ # Determines if only updates can occur. Only valid for one-to-one
39
+ # relations.
40
+ #
41
+ # @example Is this update only?
42
+ # builder.update_only?
43
+ #
44
+ # @return [ true, false ] True if the update_only option was set.
45
+ #
46
+ # @since 2.0.0.rc.1
47
+ def update_only?
48
+ options[:update_only] || false
49
+ end
50
+
51
+ # Convert an id to its appropriate type.
52
+ #
53
+ # @todo Durran: Move this into a common reusable place.
54
+ #
55
+ # @example Convert the id.
56
+ # builder.convert_id("4d371b444835d98b8b000010")
57
+ #
58
+ # @param [ String ] id The id, usually coming from the form.
59
+ #
60
+ # @return [ BSON::ObjectId, String, Object ] The converted id.
61
+ #
62
+ # @since 2.0.0.rc.6
63
+ def convert_id(id)
64
+ metadata.constraint.convert(id)
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,47 @@
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
+ # Will load the target into an array if the target had not already been
10
+ # loaded.
11
+ #
12
+ # @example Load the relation into memory.
13
+ # relation.load!
14
+ #
15
+ # @return [ One ] The relation.
16
+ #
17
+ # @since 2.0.0.rc.5
18
+ def load!(options = {})
19
+ tap do |relation|
20
+ unless relation.loaded?
21
+ relation.bind(options)
22
+ relation.loaded = true
23
+ end
24
+ end
25
+ end
26
+
27
+ # Substitutes the supplied target documents for the existing document
28
+ # in the relation.
29
+ #
30
+ # @example Substitute the new document.
31
+ # person.name.substitute(new_name)
32
+ #
33
+ # @param [ Document ] other A document to replace the target.
34
+ #
35
+ # @return [ Document, nil ] The relation or nil.
36
+ #
37
+ # @since 2.0.0.rc.1
38
+ def substitute(new_target, options = {})
39
+ old_target = target
40
+ tap do |relation|
41
+ relation.target = new_target
42
+ new_target ? bind(options) : (unbind(old_target, options) and return nil)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,54 @@
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
+ delegate :polymorphic?, :to => "self.class"
13
+ end
14
+
15
+ module ClassMethods #:nodoc:
16
+
17
+ # Attempts to set up the information needed to handle a polymorphic
18
+ # relation, if the metadata checks out.
19
+ #
20
+ # @example Set up the polymorphic information.
21
+ # Movie.polymorph(metadata)
22
+ #
23
+ # @param [ Metadata ] metadata The relation metadata.
24
+ #
25
+ # @return [ Class ] The class being set up.
26
+ #
27
+ # @since 2.0.0.rc.1
28
+ def polymorph(metadata)
29
+ tap do |klass|
30
+ if metadata.polymorphic?
31
+ klass.polymorphic = true
32
+ if metadata.relation.stores_foreign_key?
33
+ field(metadata.inverse_type, :type => String)
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ # Determines if the class is in a polymorphic relations, and thus must
40
+ # store the _type field in the database.
41
+ #
42
+ # @example Check if the class is polymorphic.
43
+ # Movie.polymorphic?
44
+ #
45
+ # @return [ true, false ] True if polymorphic, false if not.
46
+ #
47
+ # @since 2.0.0.rc.1
48
+ def polymorphic?
49
+ !!polymorphic
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,143 @@
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
+
9
+ # We undefine most methods to get them sent through to the target.
10
+ instance_methods.each do |method|
11
+ undef_method(method) unless
12
+ method =~ /(^__|^send$|^object_id$|^extend$|^tap$)/
13
+ end
14
+
15
+ attr_accessor :base, :loaded, :metadata, :target
16
+
17
+ # Backwards compatibility with Mongoid beta releases.
18
+ delegate :klass, :to => :metadata
19
+
20
+ # Convenience for setting the target and the metadata properties since
21
+ # all proxies will need to do this.
22
+ #
23
+ # @example Initialize the proxy.
24
+ # proxy.init(person, name, metadata)
25
+ #
26
+ # @param [ Document ] base The base document on the proxy.
27
+ # @param [ Document, Array<Document> ] target The target of the proxy.
28
+ # @param [ Metadata ] metadata The relation's metadata.
29
+ #
30
+ # @since 2.0.0.rc.1
31
+ def init(base, target, metadata, &block)
32
+ @base, @target, @metadata = base, target, metadata
33
+ block.call if block
34
+ extend Module.new(&metadata.extension) if metadata.extension?
35
+ end
36
+
37
+ protected
38
+
39
+ # Get the collection from the root of the hierarchy.
40
+ #
41
+ # @example Get the collection.
42
+ # relation.collection
43
+ #
44
+ # @return [ Collection ] The root's collection.
45
+ #
46
+ # @since 2.0.0
47
+ def collection
48
+ root = base._root
49
+ root.collection unless root.embedded?
50
+ end
51
+
52
+ # Return a new document for the type of class we want to instantiate.
53
+ # If the type is provided use that, otherwise the klass from the
54
+ # metadata.
55
+ #
56
+ # @example Get an instantiated document.
57
+ # proxy.instantiated(Person)
58
+ #
59
+ # @param [ Class ] type The type of class to instantiate.
60
+ #
61
+ # @return [ Document ] The freshly created document.
62
+ #
63
+ # @since 2.0.0.rc.1
64
+ def instantiated(type = nil)
65
+ type ? type.new : metadata.klass.new
66
+ end
67
+
68
+ # Determines if the target been loaded into memory or not.
69
+ #
70
+ # @example Is the proxy loaded?
71
+ # proxy.loaded?
72
+ #
73
+ # @return [ true, false ] True if loaded, false if not.
74
+ #
75
+ # @since 2.0.0.rc.1
76
+ def loaded?
77
+ !!@loaded
78
+ end
79
+
80
+ # Takes the supplied documents and sets the metadata on them. Used when
81
+ # creating new documents and adding them to the relation.
82
+ #
83
+ # @example Set the metadata.
84
+ # proxy.characterize(addresses)
85
+ #
86
+ # @param [ Array<Document> ] documents The documents to set metadata on.
87
+ #
88
+ # @since 2.0.0.rc.4
89
+ def characterize(documents)
90
+ documents.each { |doc| characterize_one(doc) }
91
+ end
92
+
93
+ # Takes the supplied document and sets the metadata on it.
94
+ #
95
+ # @example Set the metadata.
96
+ # proxt.characterize_one(name)
97
+ #
98
+ # @param [ Document ] document The document to set on.
99
+ #
100
+ # @since 2.0.0.rc.4
101
+ def characterize_one(document)
102
+ document.metadata = metadata unless document.metadata
103
+ end
104
+
105
+ # Default behavior of method missing should be to delegate all calls
106
+ # to the target of the proxy. This can be overridden in special cases.
107
+ #
108
+ # @param [ String, Symbol ] name The name of the method.
109
+ # @param [ Array ] *args The arguments passed to the method.
110
+ def method_missing(name, *args, &block)
111
+ target.send(name, *args, &block)
112
+ end
113
+
114
+ # When the base document illegally references an embedded document this
115
+ # error will get raised.
116
+ #
117
+ # @example Raise the error.
118
+ # relation.raise_mixed
119
+ #
120
+ # @raise [ Errors::MixedRelations ] The error.
121
+ #
122
+ # @since 2.0.0
123
+ def raise_mixed
124
+ raise Errors::MixedRelations.new(base.class, metadata.klass)
125
+ end
126
+
127
+ # When the base is not yet saved and the user calls create or create!
128
+ # on the relation, this error will get raised.
129
+ #
130
+ # @example Raise the error.
131
+ # relation.raise_unsaved(post)
132
+ #
133
+ # @param [ Document ] doc The child document getting created.
134
+ #
135
+ # @raise [ Errors::UnsavedDocument ] The error.
136
+ #
137
+ # @since 2.0.0.rc.6
138
+ def raise_unsaved(doc)
139
+ raise Errors::UnsavedDocument.new(base, doc)
140
+ end
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,71 @@
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
+ # @param [ Proc ] block The block to execute.
34
+ #
35
+ # @return [ Object ] The result of the operation.
36
+ #
37
+ # @since 2.0.2, batch-relational-insert
38
+ def batched(&block)
39
+ inserter = Thread.current[:mongoid_batch_insert] ||= Insert.new
40
+ count_executions(&block)
41
+ ensure
42
+ if @executions.zero?
43
+ Thread.current[:mongoid_batch_insert] = nil
44
+ raise_mixed if embedded?
45
+ inserter.execute(collection)
46
+ end
47
+ end
48
+
49
+ # Execute the block, incrementing the executions before the call and
50
+ # decrementing them after in order to be able to nest blocks within
51
+ # each other.
52
+ #
53
+ # @todo Durran: Combine common code with embedded atomics.
54
+ #
55
+ # @example Execute and increment.
56
+ # execute { block.call }
57
+ #
58
+ # @param [ Proc ] block The block to call.
59
+ #
60
+ # @since 2.0.2, batch-relational-insert
61
+ def count_executions
62
+ @executions ||= 0
63
+ @executions += 1
64
+ yield
65
+ ensure
66
+ @executions -=1
67
+ end
68
+ end
69
+ end
70
+ end
71
+ 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