mongoid 2.0.0.beta.20 → 2.0.0.rc.1

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 (134) hide show
  1. data/README.rdoc +8 -0
  2. data/Rakefile +51 -0
  3. data/lib/config/locales/nl.yml +39 -0
  4. data/lib/config/locales/ro.yml +1 -1
  5. data/lib/mongoid.rb +17 -17
  6. data/lib/mongoid/atomicity.rb +54 -22
  7. data/lib/mongoid/attributes.rb +145 -125
  8. data/lib/mongoid/callbacks.rb +7 -2
  9. data/lib/mongoid/collection.rb +49 -32
  10. data/lib/mongoid/collections.rb +0 -1
  11. data/lib/mongoid/components.rb +34 -29
  12. data/lib/mongoid/config.rb +207 -193
  13. data/lib/mongoid/config/database.rb +167 -0
  14. data/lib/mongoid/contexts.rb +2 -5
  15. data/lib/mongoid/contexts/enumerable.rb +30 -4
  16. data/lib/mongoid/contexts/ids.rb +2 -2
  17. data/lib/mongoid/contexts/mongo.rb +30 -5
  18. data/lib/mongoid/copyable.rb +44 -0
  19. data/lib/mongoid/criteria.rb +110 -56
  20. data/lib/mongoid/criterion/creational.rb +34 -0
  21. data/lib/mongoid/criterion/destructive.rb +37 -0
  22. data/lib/mongoid/criterion/exclusion.rb +3 -1
  23. data/lib/mongoid/criterion/inclusion.rb +59 -64
  24. data/lib/mongoid/criterion/inspection.rb +22 -0
  25. data/lib/mongoid/criterion/optional.rb +42 -54
  26. data/lib/mongoid/criterion/selector.rb +9 -0
  27. data/lib/mongoid/default_scope.rb +28 -0
  28. data/lib/mongoid/deprecation.rb +5 -5
  29. data/lib/mongoid/dirty.rb +4 -5
  30. data/lib/mongoid/document.rb +161 -114
  31. data/lib/mongoid/extensions.rb +7 -11
  32. data/lib/mongoid/extensions/array/parentization.rb +2 -2
  33. data/lib/mongoid/extensions/date/conversions.rb +1 -1
  34. data/lib/mongoid/extensions/hash/conversions.rb +0 -23
  35. data/lib/mongoid/extensions/nil/collectionization.rb +12 -0
  36. data/lib/mongoid/extensions/object/reflections.rb +17 -0
  37. data/lib/mongoid/extensions/object/yoda.rb +27 -0
  38. data/lib/mongoid/extensions/string/conversions.rb +23 -4
  39. data/lib/mongoid/extensions/time_conversions.rb +4 -4
  40. data/lib/mongoid/field.rb +30 -19
  41. data/lib/mongoid/fields.rb +15 -5
  42. data/lib/mongoid/finders.rb +19 -11
  43. data/lib/mongoid/hierarchy.rb +34 -28
  44. data/lib/mongoid/identity.rb +62 -20
  45. data/lib/mongoid/inspection.rb +58 -0
  46. data/lib/mongoid/matchers.rb +20 -0
  47. data/lib/mongoid/multi_database.rb +11 -0
  48. data/lib/mongoid/nested_attributes.rb +41 -0
  49. data/lib/mongoid/paranoia.rb +3 -4
  50. data/lib/mongoid/paths.rb +1 -1
  51. data/lib/mongoid/persistence.rb +89 -90
  52. data/lib/mongoid/persistence/command.rb +20 -4
  53. data/lib/mongoid/persistence/insert.rb +13 -11
  54. data/lib/mongoid/persistence/insert_embedded.rb +8 -6
  55. data/lib/mongoid/persistence/remove.rb +6 -4
  56. data/lib/mongoid/persistence/remove_all.rb +6 -4
  57. data/lib/mongoid/persistence/remove_embedded.rb +8 -6
  58. data/lib/mongoid/persistence/update.rb +12 -10
  59. data/lib/mongoid/railtie.rb +2 -2
  60. data/lib/mongoid/railties/database.rake +10 -9
  61. data/lib/mongoid/relations.rb +104 -0
  62. data/lib/mongoid/relations/accessors.rb +154 -0
  63. data/lib/mongoid/relations/auto_save.rb +34 -0
  64. data/lib/mongoid/relations/binding.rb +24 -0
  65. data/lib/mongoid/relations/bindings.rb +9 -0
  66. data/lib/mongoid/relations/bindings/embedded/in.rb +77 -0
  67. data/lib/mongoid/relations/bindings/embedded/many.rb +93 -0
  68. data/lib/mongoid/relations/bindings/embedded/one.rb +65 -0
  69. data/lib/mongoid/relations/bindings/referenced/in.rb +78 -0
  70. data/lib/mongoid/relations/bindings/referenced/many.rb +93 -0
  71. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +94 -0
  72. data/lib/mongoid/relations/bindings/referenced/one.rb +63 -0
  73. data/lib/mongoid/relations/builder.rb +41 -0
  74. data/lib/mongoid/relations/builders.rb +79 -0
  75. data/lib/mongoid/relations/builders/embedded/in.rb +25 -0
  76. data/lib/mongoid/relations/builders/embedded/many.rb +32 -0
  77. data/lib/mongoid/relations/builders/embedded/one.rb +26 -0
  78. data/lib/mongoid/relations/builders/nested_attributes/many.rb +116 -0
  79. data/lib/mongoid/relations/builders/nested_attributes/one.rb +135 -0
  80. data/lib/mongoid/relations/builders/referenced/in.rb +32 -0
  81. data/lib/mongoid/relations/builders/referenced/many.rb +26 -0
  82. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +29 -0
  83. data/lib/mongoid/relations/builders/referenced/one.rb +30 -0
  84. data/lib/mongoid/relations/cascading.rb +55 -0
  85. data/lib/mongoid/relations/cascading/delete.rb +19 -0
  86. data/lib/mongoid/relations/cascading/destroy.rb +19 -0
  87. data/lib/mongoid/relations/cascading/nullify.rb +18 -0
  88. data/lib/mongoid/relations/cascading/strategy.rb +26 -0
  89. data/lib/mongoid/relations/cyclic.rb +97 -0
  90. data/lib/mongoid/relations/embedded/in.rb +172 -0
  91. data/lib/mongoid/relations/embedded/many.rb +450 -0
  92. data/lib/mongoid/relations/embedded/one.rb +169 -0
  93. data/lib/mongoid/relations/macros.rb +302 -0
  94. data/lib/mongoid/relations/many.rb +185 -0
  95. data/lib/mongoid/relations/metadata.rb +529 -0
  96. data/lib/mongoid/relations/nested_builder.rb +52 -0
  97. data/lib/mongoid/relations/one.rb +29 -0
  98. data/lib/mongoid/relations/polymorphic.rb +54 -0
  99. data/lib/mongoid/relations/proxy.rb +122 -0
  100. data/lib/mongoid/relations/referenced/in.rb +214 -0
  101. data/lib/mongoid/relations/referenced/many.rb +358 -0
  102. data/lib/mongoid/relations/referenced/many_to_many.rb +379 -0
  103. data/lib/mongoid/relations/referenced/one.rb +204 -0
  104. data/lib/mongoid/relations/reflections.rb +45 -0
  105. data/lib/mongoid/safe.rb +11 -1
  106. data/lib/mongoid/safety.rb +122 -97
  107. data/lib/mongoid/scope.rb +14 -9
  108. data/lib/mongoid/state.rb +37 -3
  109. data/lib/mongoid/timestamps.rb +11 -0
  110. data/lib/mongoid/validations.rb +42 -3
  111. data/lib/mongoid/validations/associated.rb +8 -5
  112. data/lib/mongoid/validations/uniqueness.rb +23 -2
  113. data/lib/mongoid/version.rb +1 -1
  114. data/lib/mongoid/versioning.rb +25 -16
  115. data/lib/rails/generators/mongoid/model/templates/model.rb +3 -1
  116. metadata +95 -80
  117. data/lib/mongoid/associations.rb +0 -364
  118. data/lib/mongoid/associations/embedded_in.rb +0 -74
  119. data/lib/mongoid/associations/embeds_many.rb +0 -299
  120. data/lib/mongoid/associations/embeds_one.rb +0 -111
  121. data/lib/mongoid/associations/foreign_key.rb +0 -35
  122. data/lib/mongoid/associations/meta_data.rb +0 -38
  123. data/lib/mongoid/associations/options.rb +0 -78
  124. data/lib/mongoid/associations/proxy.rb +0 -60
  125. data/lib/mongoid/associations/referenced_in.rb +0 -70
  126. data/lib/mongoid/associations/references_many.rb +0 -254
  127. data/lib/mongoid/associations/references_many_as_array.rb +0 -128
  128. data/lib/mongoid/associations/references_one.rb +0 -104
  129. data/lib/mongoid/extensions/array/accessors.rb +0 -17
  130. data/lib/mongoid/extensions/array/assimilation.rb +0 -26
  131. data/lib/mongoid/extensions/hash/accessors.rb +0 -42
  132. data/lib/mongoid/extensions/hash/assimilation.rb +0 -40
  133. data/lib/mongoid/extensions/nil/assimilation.rb +0 -17
  134. data/lib/mongoid/memoization.rb +0 -33
@@ -0,0 +1,169 @@
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 ] :building 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[:building]
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
+ target.parentize(base)
43
+ end
44
+ end
45
+
46
+ # Unbinds the base object to the inverse of the relation. This occurs
47
+ # when setting a side of the relation to nil.
48
+ #
49
+ # Will delete the object if necessary.
50
+ #
51
+ # @example Unbind the relation.
52
+ # person.name.unbind(name, :continue => true)
53
+ #
54
+ # @param [ Document ] old_target The previous target of the relation.
55
+ # @param [ Hash ] options The options to bind with.
56
+ #
57
+ # @option options [ true, false ] :building Are we in build mode?
58
+ # @option options [ true, false ] :continue Continue binding the
59
+ # inverse?
60
+ #
61
+ # @since 2.0.0.rc.1
62
+ def unbind(old_target, options = {})
63
+ binding(old_target).unbind(options)
64
+ old_target.delete if base.persisted? && !old_target.destroyed?
65
+ end
66
+
67
+ private
68
+
69
+ # Instantiate the binding associated with this relation.
70
+ #
71
+ # @example Get the binding.
72
+ # relation.binding([ address ])
73
+ #
74
+ # @param [ Document ] new_target The new document to bind with.
75
+ #
76
+ # @return [ Binding ] The relation's binding.
77
+ #
78
+ # @since 2.0.0.rc.1
79
+ def binding(new_target = nil)
80
+ Bindings::Embedded::One.new(base, new_target || target, metadata)
81
+ end
82
+
83
+ class << self
84
+
85
+ # Return the builder that is responsible for generating the documents
86
+ # that will be used by this relation.
87
+ #
88
+ # @example Get the builder.
89
+ # Embedded::One.builder(meta, object, person)
90
+ #
91
+ # @param [ Metadata ] meta The metadata of the relation.
92
+ # @param [ Document, Hash ] object A document or attributes to build with.
93
+ #
94
+ # @return [ Builder ] A newly instantiated builder object.
95
+ #
96
+ # @since 2.0.0.rc.1
97
+ def builder(meta, object)
98
+ Builders::Embedded::One.new(meta, object)
99
+ end
100
+
101
+ # Returns true if the relation is an embedded one. In this case
102
+ # always true.
103
+ #
104
+ # @example Is this relation embedded?
105
+ # Embedded::One.embedded?
106
+ #
107
+ # @return [ true ] true.
108
+ #
109
+ # @since 2.0.0.rc.1
110
+ def embedded?
111
+ true
112
+ end
113
+
114
+ # Returns the macro for this relation. Used mostly as a helper in
115
+ # reflection.
116
+ #
117
+ # @example Get the macro.
118
+ # Mongoid::Relations::Embedded::One.macro
119
+ #
120
+ # @return [ Symbol ] :embeds_one.
121
+ #
122
+ # @since 2.0.0.rc.1
123
+ def macro
124
+ :embeds_one
125
+ end
126
+
127
+ # Return the nested builder that is responsible for generating
128
+ # the documents that will be used by this relation.
129
+ #
130
+ # @example Get the builder.
131
+ # NestedAttributes::One.builder(attributes, options)
132
+ #
133
+ # @param [ Metadata ] metadata The relation metadata.
134
+ # @param [ Hash ] attributes The attributes to build with.
135
+ # @param [ Hash ] options The options for the builder.
136
+ #
137
+ # @option options [ true, false ] :allow_destroy Can documents be
138
+ # deleted?
139
+ # @option options [ Integer ] :limit Max number of documents to
140
+ # create at once.
141
+ # @option options [ Proc, Symbol ] :reject_if If documents match this
142
+ # option then they are ignored.
143
+ # @option options [ true, false ] :update_only Only existing documents
144
+ # can be modified.
145
+ #
146
+ # @return [ Builder ] A newly instantiated nested builder object.
147
+ #
148
+ # @since 2.0.0.rc.1
149
+ def nested_builder(metadata, attributes, options)
150
+ Builders::NestedAttributes::One.new(metadata, attributes, options)
151
+ end
152
+
153
+ # Tells the caller if this relation is one that stores the foreign
154
+ # key on its own objects.
155
+ #
156
+ # @example Does this relation store a foreign key?
157
+ # Embedded::One.stores_foreign_key?
158
+ #
159
+ # @return [ false ] false.
160
+ #
161
+ # @since 2.0.0.rc.1
162
+ def stores_foreign_key?
163
+ false
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,302 @@
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_inheritable_accessor :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
+ metadatafy(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
+ metadatafy(name, Embedded::Many, options, &block).tap do |meta|
80
+ relate(name, meta)
81
+ validate_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
+ metadatafy(name, Embedded::One, options, &block).tap do |meta|
106
+ relate(name, meta)
107
+ builder(name).creator(name)
108
+ validate_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
+ metadatafy(name, Referenced::In, options, &block).tap do |meta|
132
+ relate(name, meta)
133
+ reference(meta)
134
+ end
135
+ end
136
+ alias :belongs_to_related :referenced_in
137
+
138
+ # Adds a relational association from a parent Document to many
139
+ # Documents in another database or collection.
140
+ #
141
+ # @example Define the relation.
142
+ #
143
+ # class Person
144
+ # include Mongoid::Document
145
+ # references_many :posts
146
+ # end
147
+ #
148
+ # class Game
149
+ # include Mongoid::Document
150
+ # referenced_in :person
151
+ # end
152
+ #
153
+ # @param [ Symbol ] name The name of the relation.
154
+ # @param [ Hash ] options The relation options.
155
+ # @param [ Proc ] block Optional block for defining extensions.
156
+ def references_many(name, options = {}, &block)
157
+ check_options(options)
158
+ metadatafy(name, Referenced::Many, options, &block).tap do |meta|
159
+ relate(name, meta)
160
+ reference(meta)
161
+ autosave(meta)
162
+ validate_relation(meta)
163
+ end
164
+ end
165
+ alias :has_many_related :references_many
166
+
167
+ # Adds a relational many-to-many association between many of this
168
+ # Document and many of another Document.
169
+ #
170
+ # @example Define the relation.
171
+ #
172
+ # class Person
173
+ # include Mongoid::Document
174
+ # references_and_referenced_in_many :preferences
175
+ # end
176
+ #
177
+ # class Preference
178
+ # include Mongoid::Document
179
+ # references_and_referenced_in_many :people
180
+ # end
181
+ #
182
+ # @param [ Symbol ] name The name of the relation.
183
+ # @param [ Hash ] options The relation options.
184
+ # @param [ Proc ] block Optional block for defining extensions.
185
+ #
186
+ # @since 2.0.0.rc.1
187
+ def references_and_referenced_in_many(name, options = {}, &block)
188
+ metadatafy(name, Referenced::ManyToMany, options, &block).tap do |meta|
189
+ relate(name, meta)
190
+ reference(meta)
191
+ end
192
+ end
193
+
194
+ # Adds a relational association from the child Document to a Document in
195
+ # another database or collection.
196
+ #
197
+ # @example Define the relation.
198
+ #
199
+ # class Game
200
+ # include Mongoid::Document
201
+ # referenced_in :person
202
+ # end
203
+ #
204
+ # class Person
205
+ # include Mongoid::Document
206
+ # references_one :game
207
+ # end
208
+ #
209
+ # @param [ Symbol ] name The name of the relation.
210
+ # @param [ Hash ] options The relation options.
211
+ # @param [ Proc ] block Optional block for defining extensions.
212
+ def references_one(name, options = {}, &block)
213
+ metadatafy(name, Referenced::One, options, &block).tap do |meta|
214
+ relate(name, meta)
215
+ reference(meta)
216
+ builder(name).creator(name).autosave(meta)
217
+ validate_relation(meta)
218
+ end
219
+ end
220
+ alias :has_one_related :references_one
221
+
222
+ private
223
+
224
+ # Temporary check while people switch over to the new macro. Will be
225
+ # deleted in 2.0.0.
226
+ #
227
+ # @example Check the options.
228
+ # Person.check_options({})
229
+ #
230
+ # @param [ Hash ] options The options given to the relational many.
231
+ #
232
+ # @raise [ RuntimeError ] If :stored_as => :array is found.
233
+ #
234
+ # @since 2.0.0.rc.1
235
+ def check_options(options = {})
236
+ if options[:stored_as] == :array
237
+ raise RuntimeError.new(
238
+ "Macro: references_many :name, :stored_as => :array " <<
239
+ "Is no longer valid. Please use: references_and_referenced_in_many :name"
240
+ )
241
+ end
242
+ end
243
+
244
+ # Create the metadata for the relation.
245
+ #
246
+ # @example Create the metadata.
247
+ # Person.metadatafy(:posts, Referenced::Many, {})
248
+ #
249
+ # @param [ Symbol ] name The name of the relation.
250
+ # @param [ Object ] relation The type of relation.
251
+ # @param [ Hash ] options The relation options.
252
+ # @param [ Proc ] block Optional block for defining extensions.
253
+ #
254
+ # @return [ Metadata ] The metadata for the relation.
255
+ def metadatafy(name, relation, options, &block)
256
+ Metadata.new(
257
+ options.merge(
258
+ :relation => relation,
259
+ :extend => block,
260
+ :inverse_class_name => self.name,
261
+ :name => name
262
+ )
263
+ )
264
+ end
265
+
266
+ # Defines a field to be used as a foreign key in the relation and
267
+ # indexes it if defined.
268
+ #
269
+ # @example Set up the relational fields and indexes.
270
+ # Person.reference(metadata)
271
+ #
272
+ # @param [ Metadata ] metadata The metadata for the relation.
273
+ def reference(metadata)
274
+ polymorph(metadata).cascade(metadata)
275
+ if metadata.relation.stores_foreign_key?
276
+ key = metadata.foreign_key
277
+ field(
278
+ key,
279
+ :identity => true,
280
+ :metadata => metadata,
281
+ :default => metadata.foreign_key_default
282
+ )
283
+ index(key, :background => true) if metadata.indexed?
284
+ end
285
+ end
286
+
287
+ # Creates a relation for the given name, metadata and relation. It adds
288
+ # the metadata to the relations hash and has the accessors set up.
289
+ #
290
+ # @example Set up the relation and accessors.
291
+ # Person.relate(:addresses, Metadata)
292
+ #
293
+ # @param [ Symbol ] name The name of the relation.
294
+ # @param [ Metadata ] metadata The metadata for the relation.
295
+ def relate(name, metadata)
296
+ relations[name.to_s] = metadata
297
+ getter(name, metadata).setter(name, metadata)
298
+ end
299
+ end
300
+ end
301
+ end
302
+ end