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,170 @@
1
+ # encoding: utf-8
2
+ module Mongoid # :nodoc:
3
+ module Relations #:nodoc:
4
+ module Embedded #:nodoc:
5
+
6
+ # This class defines the behaviour needed for embedded one to one
7
+ # relations.
8
+ class One < Relations::One
9
+
10
+ # Binds the base object to the inverse of the relation. This is so we
11
+ # are referenced to the actual objects themselves and dont hit the
12
+ # database twice when setting the relations up.
13
+ #
14
+ # This is called after first creating the relation, or if a new object
15
+ # is set on the relation.
16
+ #
17
+ # @example Bind the relation.
18
+ # person.name.bind(:continue => false)
19
+ #
20
+ # @param [ Hash ] options The options to bind with.
21
+ #
22
+ # @option options [ true, false ] :binding Are we in build mode?
23
+ # @option options [ true, false ] :continue Continue binding the
24
+ # inverse?
25
+ #
26
+ # @since 2.0.0.rc.1
27
+ def bind(options = {})
28
+ binding.bind(options)
29
+ target.save if base.persisted? && !options[:binding]
30
+ end
31
+
32
+ # Instantiate a new embeds_one relation.
33
+ #
34
+ # @example Create the new proxy.
35
+ # One.new(person, name, metadata)
36
+ #
37
+ # @param [ Document ] base The document this relation hangs off of.
38
+ # @param [ Document ] target The child document in the relation.
39
+ # @param [ Metadata ] metadata The relation's metadata
40
+ def initialize(base, target, metadata)
41
+ init(base, target, metadata) do
42
+ characterize_one(target)
43
+ target.parentize(base)
44
+ end
45
+ end
46
+
47
+ # Unbinds the base object to the inverse of the relation. This occurs
48
+ # when setting a side of the relation to nil.
49
+ #
50
+ # Will delete the object if necessary.
51
+ #
52
+ # @example Unbind the relation.
53
+ # person.name.unbind(name, :continue => true)
54
+ #
55
+ # @param [ Document ] old_target The previous target of the relation.
56
+ # @param [ Hash ] options The options to bind with.
57
+ #
58
+ # @option options [ true, false ] :binding Are we in build mode?
59
+ # @option options [ true, false ] :continue Continue binding the
60
+ # inverse?
61
+ #
62
+ # @since 2.0.0.rc.1
63
+ def unbind(old_target, options = {})
64
+ binding(old_target).unbind(options)
65
+ old_target.delete if base.persisted? && !old_target.destroyed?
66
+ end
67
+
68
+ private
69
+
70
+ # Instantiate the binding associated with this relation.
71
+ #
72
+ # @example Get the binding.
73
+ # relation.binding([ address ])
74
+ #
75
+ # @param [ Document ] new_target The new document to bind with.
76
+ #
77
+ # @return [ Binding ] The relation's binding.
78
+ #
79
+ # @since 2.0.0.rc.1
80
+ def binding(new_target = nil)
81
+ Bindings::Embedded::One.new(base, new_target || target, metadata)
82
+ end
83
+
84
+ class << self
85
+
86
+ # Return the builder that is responsible for generating the documents
87
+ # that will be used by this relation.
88
+ #
89
+ # @example Get the builder.
90
+ # Embedded::One.builder(meta, object, person)
91
+ #
92
+ # @param [ Metadata ] meta The metadata of the relation.
93
+ # @param [ Document, Hash ] object A document or attributes to build with.
94
+ #
95
+ # @return [ Builder ] A newly instantiated builder object.
96
+ #
97
+ # @since 2.0.0.rc.1
98
+ def builder(meta, object)
99
+ Builders::Embedded::One.new(meta, object)
100
+ end
101
+
102
+ # Returns true if the relation is an embedded one. In this case
103
+ # always true.
104
+ #
105
+ # @example Is this relation embedded?
106
+ # Embedded::One.embedded?
107
+ #
108
+ # @return [ true ] true.
109
+ #
110
+ # @since 2.0.0.rc.1
111
+ def embedded?
112
+ true
113
+ end
114
+
115
+ # Returns the macro for this relation. Used mostly as a helper in
116
+ # reflection.
117
+ #
118
+ # @example Get the macro.
119
+ # Mongoid::Relations::Embedded::One.macro
120
+ #
121
+ # @return [ Symbol ] :embeds_one.
122
+ #
123
+ # @since 2.0.0.rc.1
124
+ def macro
125
+ :embeds_one
126
+ end
127
+
128
+ # Return the nested builder that is responsible for generating
129
+ # the documents that will be used by this relation.
130
+ #
131
+ # @example Get the builder.
132
+ # NestedAttributes::One.builder(attributes, options)
133
+ #
134
+ # @param [ Metadata ] metadata The relation metadata.
135
+ # @param [ Hash ] attributes The attributes to build with.
136
+ # @param [ Hash ] options The options for the builder.
137
+ #
138
+ # @option options [ true, false ] :allow_destroy Can documents be
139
+ # deleted?
140
+ # @option options [ Integer ] :limit Max number of documents to
141
+ # create at once.
142
+ # @option options [ Proc, Symbol ] :reject_if If documents match this
143
+ # option then they are ignored.
144
+ # @option options [ true, false ] :update_only Only existing documents
145
+ # can be modified.
146
+ #
147
+ # @return [ Builder ] A newly instantiated nested builder object.
148
+ #
149
+ # @since 2.0.0.rc.1
150
+ def nested_builder(metadata, attributes, options)
151
+ Builders::NestedAttributes::One.new(metadata, attributes, options)
152
+ end
153
+
154
+ # Tells the caller if this relation is one that stores the foreign
155
+ # key on its own objects.
156
+ #
157
+ # @example Does this relation store a foreign key?
158
+ # Embedded::One.stores_foreign_key?
159
+ #
160
+ # @return [ false ] false.
161
+ #
162
+ # @since 2.0.0.rc.1
163
+ def stores_foreign_key?
164
+ false
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,310 @@
1
+ # encoding: utf-8
2
+ module Mongoid # :nodoc:
3
+ module Relations #:nodoc:
4
+
5
+ # This module contains the core macros for defining relations between
6
+ # documents. They can be either embedded or referenced (relational).
7
+ module Macros
8
+ extend ActiveSupport::Concern
9
+
10
+ included do
11
+ cattr_accessor :embedded
12
+ class_attribute :relations
13
+ self.embedded = false
14
+ self.relations = {}
15
+
16
+ # For backwards compatibility, alias the class method for associations
17
+ # and embedding as well. Fix in related gems.
18
+ #
19
+ # @todo Affected libraries: Machinist
20
+ class << self
21
+ alias :associations :relations
22
+ alias :embedded? :embedded
23
+ end
24
+
25
+ # Convenience methods for the instance to know about attributes that
26
+ # are located at the class level.
27
+ delegate :associations, :relations, :to => "self.class"
28
+ end
29
+
30
+ module ClassMethods #:nodoc:
31
+
32
+ # Adds the relation back to the parent document. This macro is
33
+ # necessary to set the references from the child back to the parent
34
+ # document. If a child does not define this relation calling
35
+ # persistence methods on the child object will cause a save to fail.
36
+ #
37
+ # @example Define the relation.
38
+ #
39
+ # class Person
40
+ # include Mongoid::Document
41
+ # embeds_many :addresses
42
+ # end
43
+ #
44
+ # class Address
45
+ # include Mongoid::Document
46
+ # embedded_in :person
47
+ # end
48
+ #
49
+ # @param [ Symbol ] name The name of the relation.
50
+ # @param [ Hash ] options The relation options.
51
+ # @param [ Proc ] block Optional block for defining extensions.
52
+ def embedded_in(name, options = {}, &block)
53
+ characterize(name, Embedded::In, options, &block).tap do |meta|
54
+ self.embedded = true
55
+ relate(name, meta)
56
+ end
57
+ end
58
+
59
+ # Adds the relation from a parent document to its children. The name
60
+ # of the relation needs to be a pluralized form of the child class
61
+ # name.
62
+ #
63
+ # @example Define the relation.
64
+ #
65
+ # class Person
66
+ # include Mongoid::Document
67
+ # embeds_many :addresses
68
+ # end
69
+ #
70
+ # class Address
71
+ # include Mongoid::Document
72
+ # embedded_in :person
73
+ # end
74
+ #
75
+ # @param [ Symbol ] name The name of the relation.
76
+ # @param [ Hash ] options The relation options.
77
+ # @param [ Proc ] block Optional block for defining extensions.
78
+ def embeds_many(name, options = {}, &block)
79
+ characterize(name, Embedded::Many, options, &block).tap do |meta|
80
+ relate(name, meta)
81
+ validates_relation(meta)
82
+ end
83
+ end
84
+
85
+ # Adds the relation from a parent document to its child. The name
86
+ # of the relation needs to be a singular form of the child class
87
+ # name.
88
+ #
89
+ # @example Define the relation.
90
+ #
91
+ # class Person
92
+ # include Mongoid::Document
93
+ # embeds_one :name
94
+ # end
95
+ #
96
+ # class Name
97
+ # include Mongoid::Document
98
+ # embedded_in :person
99
+ # end
100
+ #
101
+ # @param [ Symbol ] name The name of the relation.
102
+ # @param [ Hash ] options The relation options.
103
+ # @param [ Proc ] block Optional block for defining extensions.
104
+ def embeds_one(name, options = {}, &block)
105
+ characterize(name, Embedded::One, options, &block).tap do |meta|
106
+ relate(name, meta)
107
+ builder(name, meta).creator(name)
108
+ validates_relation(meta)
109
+ end
110
+ end
111
+
112
+ # Adds a relational association from the child Document to a Document in
113
+ # another database or collection.
114
+ #
115
+ # @example Define the relation.
116
+ #
117
+ # class Game
118
+ # include Mongoid::Document
119
+ # referenced_in :person
120
+ # end
121
+ #
122
+ # class Person
123
+ # include Mongoid::Document
124
+ # references_one :game
125
+ # end
126
+ #
127
+ # @param [ Symbol ] name The name of the relation.
128
+ # @param [ Hash ] options The relation options.
129
+ # @param [ Proc ] block Optional block for defining extensions.
130
+ def referenced_in(name, options = {}, &block)
131
+ characterize(name, Referenced::In, options, &block).tap do |meta|
132
+ relate(name, meta)
133
+ reference(meta)
134
+ autosave(meta)
135
+ validates_relation(meta)
136
+ end
137
+ end
138
+ alias :belongs_to_related :referenced_in
139
+ alias :belongs_to :referenced_in
140
+
141
+ # Adds a relational association from a parent Document to many
142
+ # Documents in another database or collection.
143
+ #
144
+ # @example Define the relation.
145
+ #
146
+ # class Person
147
+ # include Mongoid::Document
148
+ # references_many :posts
149
+ # end
150
+ #
151
+ # class Game
152
+ # include Mongoid::Document
153
+ # referenced_in :person
154
+ # end
155
+ #
156
+ # @param [ Symbol ] name The name of the relation.
157
+ # @param [ Hash ] options The relation options.
158
+ # @param [ Proc ] block Optional block for defining extensions.
159
+ def references_many(name, options = {}, &block)
160
+ check_options(options)
161
+ characterize(name, Referenced::Many, options, &block).tap do |meta|
162
+ relate(name, meta)
163
+ reference(meta)
164
+ autosave(meta)
165
+ validates_relation(meta)
166
+ end
167
+ end
168
+ alias :has_many_related :references_many
169
+ alias :has_many :references_many
170
+
171
+ # Adds a relational many-to-many association between many of this
172
+ # Document and many of another Document.
173
+ #
174
+ # @example Define the relation.
175
+ #
176
+ # class Person
177
+ # include Mongoid::Document
178
+ # references_and_referenced_in_many :preferences
179
+ # end
180
+ #
181
+ # class Preference
182
+ # include Mongoid::Document
183
+ # references_and_referenced_in_many :people
184
+ # end
185
+ #
186
+ # @param [ Symbol ] name The name of the relation.
187
+ # @param [ Hash ] options The relation options.
188
+ # @param [ Proc ] block Optional block for defining extensions.
189
+ #
190
+ # @since 2.0.0.rc.1
191
+ def references_and_referenced_in_many(name, options = {}, &block)
192
+ characterize(name, Referenced::ManyToMany, options, &block).tap do |meta|
193
+ relate(name, meta)
194
+ reference(meta)
195
+ autosave(meta)
196
+ validates_relation(meta)
197
+ end
198
+ end
199
+ alias :has_and_belongs_to_many :references_and_referenced_in_many
200
+
201
+ # Adds a relational association from the child Document to a Document in
202
+ # another database or collection.
203
+ #
204
+ # @example Define the relation.
205
+ #
206
+ # class Game
207
+ # include Mongoid::Document
208
+ # referenced_in :person
209
+ # end
210
+ #
211
+ # class Person
212
+ # include Mongoid::Document
213
+ # references_one :game
214
+ # end
215
+ #
216
+ # @param [ Symbol ] name The name of the relation.
217
+ # @param [ Hash ] options The relation options.
218
+ # @param [ Proc ] block Optional block for defining extensions.
219
+ def references_one(name, options = {}, &block)
220
+ characterize(name, Referenced::One, options, &block).tap do |meta|
221
+ relate(name, meta)
222
+ reference(meta)
223
+ builder(name, meta).creator(name).autosave(meta)
224
+ validates_relation(meta)
225
+ end
226
+ end
227
+ alias :has_one_related :references_one
228
+ alias :has_one :references_one
229
+
230
+ private
231
+
232
+ # Temporary check while people switch over to the new macro. Will be
233
+ # deleted in 2.0.0.
234
+ #
235
+ # @example Check the options.
236
+ # Person.check_options({})
237
+ #
238
+ # @param [ Hash ] options The options given to the relational many.
239
+ #
240
+ # @raise [ RuntimeError ] If :stored_as => :array is found.
241
+ #
242
+ # @since 2.0.0.rc.1
243
+ def check_options(options = {})
244
+ if options[:stored_as] == :array
245
+ raise RuntimeError.new(
246
+ "Macro: references_many :name, :stored_as => :array " <<
247
+ "Is no longer valid. Please use: references_and_referenced_in_many :name"
248
+ )
249
+ end
250
+ end
251
+
252
+ # Create the metadata for the relation.
253
+ #
254
+ # @example Create the metadata.
255
+ # Person.characterize(:posts, Referenced::Many, {})
256
+ #
257
+ # @param [ Symbol ] name The name of the relation.
258
+ # @param [ Object ] relation The type of relation.
259
+ # @param [ Hash ] options The relation options.
260
+ # @param [ Proc ] block Optional block for defining extensions.
261
+ #
262
+ # @return [ Metadata ] The metadata for the relation.
263
+ def characterize(name, relation, options, &block)
264
+ Metadata.new(
265
+ options.merge(
266
+ :relation => relation,
267
+ :extend => block,
268
+ :inverse_class_name => self.name,
269
+ :name => name
270
+ )
271
+ )
272
+ end
273
+
274
+ # Defines a field to be used as a foreign key in the relation and
275
+ # indexes it if defined.
276
+ #
277
+ # @example Set up the relational fields and indexes.
278
+ # Person.reference(metadata)
279
+ #
280
+ # @param [ Metadata ] metadata The metadata for the relation.
281
+ def reference(metadata)
282
+ polymorph(metadata).cascade(metadata)
283
+ if metadata.relation.stores_foreign_key?
284
+ key = metadata.foreign_key
285
+ field(
286
+ key,
287
+ :identity => true,
288
+ :metadata => metadata,
289
+ :default => metadata.foreign_key_default
290
+ )
291
+ index(key, :background => true) if metadata.indexed?
292
+ end
293
+ end
294
+
295
+ # Creates a relation for the given name, metadata and relation. It adds
296
+ # the metadata to the relations hash and has the accessors set up.
297
+ #
298
+ # @example Set up the relation and accessors.
299
+ # Person.relate(:addresses, Metadata)
300
+ #
301
+ # @param [ Symbol ] name The name of the relation.
302
+ # @param [ Metadata ] metadata The metadata for the relation.
303
+ def relate(name, metadata)
304
+ self.relations = relations.merge(name.to_s => metadata)
305
+ getter(name, metadata).setter(name, metadata)
306
+ end
307
+ end
308
+ end
309
+ end
310
+ end