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,103 @@
1
+ # encoding: utf-8
2
+ module Mongoid # :nodoc:
3
+ module Relations #:nodoc:
4
+ module Bindings #:nodoc:
5
+ module Referenced #:nodoc:
6
+
7
+ # Binding class for all references_and_referenced_in_many relations.
8
+ class ManyToMany < Binding
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.preferences.bind
18
+ # person.preferences = [ Preference.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(options = {})
27
+ target.each { |doc| bind_one(doc, options) }
28
+ end
29
+
30
+ # Binds a single document with the inverse relation. Used
31
+ # specifically when appending to the proxy.
32
+ #
33
+ # @example Bind one document.
34
+ # person.preferences.bind_one(preference)
35
+ #
36
+ # @param [ Document ] doc The single document to bind.
37
+ # @param [ Hash ] options The binding options.
38
+ #
39
+ # @option options [ true, false ] :continue Continue binding the inverse.
40
+ # @option options [ true, false ] :binding Are we in build mode?
41
+ #
42
+ # @since 2.0.0.rc.1
43
+ def bind_one(doc, options = {})
44
+ if options[:continue]
45
+ inverse = metadata.inverse(target)
46
+ if inverse
47
+ doc.do_or_do_not(
48
+ inverse,
49
+ false,
50
+ OPTIONS
51
+ ).push(base, :binding => true, :continue => false)
52
+ end
53
+ end
54
+ end
55
+
56
+ # Unbinds the base object and the inverse, caused by setting the
57
+ # reference to nil.
58
+ #
59
+ # @example Unbind the documents.
60
+ # person.preferences.unbind
61
+ # person.preferences = nil
62
+ #
63
+ # @param [ Hash ] options The binding options.
64
+ #
65
+ # @option options [ true, false ] :continue Continue binding the inverse.
66
+ # @option options [ true, false ] :binding Are we in build mode?
67
+ #
68
+ # @since 2.0.0.rc.1
69
+ def unbind(options = {})
70
+ target.each { |doc| unbind_one(doc, options) }
71
+ end
72
+
73
+ # Unbind a single document.
74
+ #
75
+ # @example Unbind the document.
76
+ # person.preferences.unbind_one(document)
77
+ #
78
+ # @todo Durran: Get rid of persistence operation in this method.
79
+ #
80
+ # @param [ Hash ] options The binding options.
81
+ #
82
+ # @option options [ true, false ] :continue Continue binding the inverse.
83
+ # @option options [ true, false ] :binding Are we in build mode?
84
+ #
85
+ # @since 2.0.0.rc.1
86
+ def unbind_one(doc, options = {})
87
+ base.do_or_do_not(metadata.foreign_key).delete(doc.id)
88
+ if options[:continue]
89
+ inverse = metadata.inverse(target)
90
+ if inverse
91
+ doc.do_or_do_not(
92
+ inverse, false, OPTIONS
93
+ ).delete(base, :binding => true, :continue => false)
94
+ end
95
+ else
96
+ base.save if base.persisted?
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+ module Mongoid # :nodoc:
3
+ module Relations #:nodoc:
4
+ module Bindings #:nodoc:
5
+ module Referenced #:nodoc:
6
+
7
+ # Binding class for references_one relations.
8
+ class One < Binding
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 the document.
17
+ # person.game.bind(:continue => true)
18
+ # person.game = Game.new
19
+ #
20
+ # @param [ Hash ] options The options to pass through.
21
+ #
22
+ # @option options [ true, false ] :continue Do we continue binding?
23
+ # @option options [ true, false ] :binding Are we in build mode?
24
+ #
25
+ # @since 2.0.0.rc.1
26
+ def bind(options = {})
27
+ if options[:continue]
28
+ target.do_or_do_not(metadata.foreign_key_setter, base.id)
29
+ target.do_or_do_not(
30
+ metadata.inverse_setter,
31
+ base,
32
+ OPTIONS
33
+ )
34
+ end
35
+ end
36
+ alias :bind_one :bind
37
+
38
+ # Unbinds the base object and the inverse, caused by setting the
39
+ # reference to nil.
40
+ #
41
+ # @example Unbind the document.
42
+ # person.game.unbind(:continue => true)
43
+ # person.game = nil
44
+ #
45
+ # @param [ Hash ] options The options to pass through.
46
+ #
47
+ # @option options [ true, false ] :continue Do we continue unbinding?
48
+ # @option options [ true, false ] :binding Are we in build mode?
49
+ #
50
+ # @since 2.0.0.rc.1
51
+ def unbind(options = {})
52
+ if options[:continue]
53
+ target.do_or_do_not(metadata.foreign_key_setter, nil)
54
+ target.do_or_do_not(
55
+ metadata.inverse_setter,
56
+ nil,
57
+ OPTIONS
58
+ )
59
+ end
60
+ end
61
+ alias :unbind_one :unbind
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+ module Mongoid # :nodoc:
3
+ module Relations #:nodoc:
4
+
5
+ # Superclass for all builder objects. Builders are responsible for either
6
+ # looking up a relation's target from the database, or creating them from a
7
+ # supplied attributes hash.
8
+ class Builder
9
+
10
+ attr_reader :metadata, :object
11
+ # Instantiate the new builder for a relation.
12
+ #
13
+ # @example Create the builder.
14
+ # Builder.new(metadata, { :field => "value })
15
+ #
16
+ # @param [ Metdata ] metadata The metadata for the relation.
17
+ # @param [ Hash, BSON::ObjectId ] object The attributes to build from or
18
+ # id to query with.
19
+ #
20
+ # @since 2.0.0.rc.1
21
+ def initialize(metadata, object)
22
+ @metadata, @object = metadata, object
23
+ end
24
+
25
+ protected
26
+ # Do we need to perform a database query? It will be so if the object we
27
+ # have is not a document.
28
+ #
29
+ # @example Should we query the database?
30
+ # builder.query?
31
+ #
32
+ # @return [ true, false ] Whether a database query should happen.
33
+ #
34
+ # @since 2.0.0.rc.1
35
+ def query?
36
+ return true unless object.respond_to?(:to_a)
37
+ obj = object.to_a.first
38
+ !obj.respond_to?(:attributes) && !obj.nil?
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,79 @@
1
+ # encoding: utf-8
2
+ require "mongoid/relations/builder"
3
+ require "mongoid/relations/nested_builder"
4
+ require "mongoid/relations/builders/embedded/in"
5
+ require "mongoid/relations/builders/embedded/many"
6
+ require "mongoid/relations/builders/embedded/one"
7
+ require "mongoid/relations/builders/nested_attributes/one"
8
+ require "mongoid/relations/builders/nested_attributes/many"
9
+ require "mongoid/relations/builders/referenced/in"
10
+ require "mongoid/relations/builders/referenced/many"
11
+ require "mongoid/relations/builders/referenced/many_to_many"
12
+ require "mongoid/relations/builders/referenced/one"
13
+
14
+ module Mongoid # :nodoc:
15
+ module Relations #:nodoc:
16
+
17
+ # This module is responsible for defining the build and create methods used
18
+ # in one to one relations.
19
+ #
20
+ # @example Methods that get created.
21
+ #
22
+ # class Person
23
+ # include Mongoid::Document
24
+ # embeds_one :name
25
+ # end
26
+ #
27
+ # # The following methods get created:
28
+ # person.build_name({ :first_name => "Durran" })
29
+ # person.create_name({ :first_name => "Durran" })
30
+ #
31
+ # @since 2.0.0.rc.1
32
+ module Builders
33
+ extend ActiveSupport::Concern
34
+
35
+ module ClassMethods #:nodoc:
36
+
37
+ # Defines a builder method for an embeds_one relation. This is
38
+ # defined as #build_name.
39
+ #
40
+ # @example
41
+ # Person.builder("name")
42
+ #
43
+ # @param [ String, Symbol ] name The name of the relation.
44
+ #
45
+ # @return [ Class ] The class being set up.
46
+ #
47
+ # @since 2.0.0.rc.1
48
+ def builder(name, metadata)
49
+ tap do
50
+ define_method("build_#{name}") do |*args|
51
+ document = Factory.build(metadata.klass, args.first || {})
52
+ send("#{name}=", document, :binding => true)
53
+ end
54
+ end
55
+ end
56
+
57
+ # Defines a creator method for an embeds_one relation. This is
58
+ # defined as #create_name. After the object is built it will
59
+ # immediately save.
60
+ #
61
+ # @example
62
+ # Person.creator("name")
63
+ #
64
+ # @param [ String, Symbol ] name The name of the relation.
65
+ #
66
+ # @return [ Class ] The class being set up.
67
+ #
68
+ # @since 2.0.0.rc.1
69
+ def creator(name)
70
+ tap do
71
+ define_method("create_#{name}") do |*args|
72
+ send("build_#{name}", *args).tap(&:save)
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ module Mongoid # :nodoc:
3
+ module Relations #:nodoc:
4
+ module Builders #:nodoc:
5
+ module Embedded #:nodoc:
6
+ class In < Builder #:nodoc:
7
+
8
+ # This builder doesn't actually build anything, just returns the
9
+ # parent since it should already be instantiated.
10
+ #
11
+ # @example Build the document.
12
+ # Builder.new(meta, attrs).build
13
+ #
14
+ # @param [ String ] type Not used in this context.
15
+ #
16
+ # @return [ Document ] A single document.
17
+ def build(type = nil)
18
+ return object unless object.is_a?(Hash)
19
+ Mongoid::Factory.from_db(metadata.klass, object)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+ module Mongoid # :nodoc:
3
+ module Relations #:nodoc:
4
+ module Builders #:nodoc:
5
+ module Embedded #:nodoc:
6
+ class Many < Builder #:nodoc:
7
+
8
+ # Builds the document out of the attributes using the provided
9
+ # metadata on the relation. Instantiates through the factory in order
10
+ # to make sure subclasses and allocation are used if fitting. This
11
+ # case will return many documents.
12
+ #
13
+ # @example Build the documents.
14
+ # Builder.new(meta, attrs).build
15
+ #
16
+ # @param [ String ] type Not used in this context.
17
+ #
18
+ # @return [ Array<Document ] The documents.
19
+ def build(type = nil)
20
+ return [] if object.blank?
21
+ return object if object.first.is_a?(Document)
22
+ object.inject([]) do |documents, attrs|
23
+ documents.tap do |docs|
24
+ docs << Mongoid::Factory.from_db(metadata.klass, attrs)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+ module Mongoid # :nodoc:
3
+ module Relations #:nodoc:
4
+ module Builders #:nodoc:
5
+ module Embedded #:nodoc:
6
+ class One < Builder #:nodoc:
7
+
8
+ # Builds the document out of the attributes using the provided
9
+ # metadata on the relation. Instantiates through the factory in order
10
+ # to make sure subclasses and allocation are used if fitting.
11
+ #
12
+ # @example Build the document.
13
+ # Builder.new(meta, attrs).build
14
+ #
15
+ # @param [ String ] type Not used in this context.
16
+ #
17
+ # @return [ Document ] A single document.
18
+ def build(type = nil)
19
+ return object unless object.is_a?(Hash)
20
+ Mongoid::Factory.from_db(metadata.klass, object)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,126 @@
1
+ # encoding: utf-8
2
+ module Mongoid # :nodoc:
3
+ module Relations #:nodoc:
4
+ module Builders #:nodoc:
5
+ module NestedAttributes #:nodoc:
6
+ class Many < NestedBuilder
7
+
8
+ # Builds the relation depending on the attributes and the options
9
+ # passed to the macro.
10
+ #
11
+ # This attempts to perform 3 operations, either one of an update of
12
+ # the existing relation, a replacement of the relation with a new
13
+ # document, or a removal of the relation.
14
+ #
15
+ # Example:
16
+ #
17
+ # <tt>many.build(person)</tt>
18
+ #
19
+ # Options:
20
+ #
21
+ # parent: The parent document of the relation.
22
+ def build(parent)
23
+ @existing = parent.send(metadata.name)
24
+ if over_limit?(attributes)
25
+ raise Errors::TooManyNestedAttributeRecords.new(existing, options[:limit])
26
+ end
27
+ attributes.each do |attrs|
28
+ if attrs.respond_to?(:with_indifferent_access)
29
+ process(attrs)
30
+ else
31
+ process(attrs[1])
32
+ end
33
+ end
34
+ end
35
+
36
+ # Create the new builder for nested attributes on one-to-many
37
+ # relations.
38
+ #
39
+ # Example:
40
+ #
41
+ # <tt>One.new(metadata, attributes, options)</tt>
42
+ #
43
+ # Options:
44
+ #
45
+ # metadata: The relation metadata
46
+ # attributes: The attributes hash to attempt to set.
47
+ # options: The options defined.
48
+ #
49
+ # Returns:
50
+ #
51
+ # A new builder.
52
+ def initialize(metadata, attributes, options = {})
53
+ if attributes.respond_to?(:with_indifferent_access)
54
+ @attributes = attributes.with_indifferent_access.sort do |a, b|
55
+ a[0].to_i <=> b[0].to_i
56
+ end
57
+ else
58
+ @attributes = attributes
59
+ end
60
+ @metadata = metadata
61
+ @options = options
62
+ end
63
+
64
+ private
65
+
66
+ # Can the existing relation potentially be deleted?
67
+ #
68
+ # Example:
69
+ #
70
+ # <tt>destroyable?({ :_destroy => "1" })</tt>
71
+ #
72
+ # Options:
73
+ #
74
+ # attributes: The attributes to pull the flag from.
75
+ #
76
+ # Returns:
77
+ #
78
+ # True if the relation can potentially be deleted.
79
+ def destroyable?(attributes)
80
+ destroy = attributes.delete(:_destroy)
81
+ [ 1, "1", true, "true" ].include?(destroy) && allow_destroy?
82
+ end
83
+
84
+ # Are the supplied attributes of greater number than the supplied
85
+ # limit?
86
+ #
87
+ # Example:
88
+ #
89
+ # <tt>builder.over_limit?({ "street" => "Bond" })</tt>
90
+ #
91
+ # Options:
92
+ #
93
+ # attributes: The attributes being set.
94
+ #
95
+ # Returns:
96
+ #
97
+ # True if a limit supplied and the attributes are of greater number.
98
+ def over_limit?(attributes)
99
+ limit = options[:limit]
100
+ limit ? attributes.size > limit : false
101
+ end
102
+
103
+ # Process each set of attributes one at a time for each potential
104
+ # new, existing, or ignored document.
105
+ #
106
+ # Example:
107
+ #
108
+ # <tt>builder.process({ "id" => 1, "street" => "Bond" })
109
+ #
110
+ # Options:
111
+ #
112
+ # attrs: The single document attributes to process.
113
+ def process(attrs)
114
+ return if reject?(attrs)
115
+ if id = attrs[:id] || attrs["id"] || attrs["_id"]
116
+ document = existing.find(convert_id(id))
117
+ destroyable?(attrs) ? document.destroy : document.update_attributes(attrs)
118
+ else
119
+ existing.push(metadata.klass.new(attrs)) unless destroyable?(attrs)
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end