stonegao-mongoid 2.0.0.rc.6

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 (199) 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 +44 -0
  5. data/lib/config/locales/de.yml +44 -0
  6. data/lib/config/locales/en.yml +45 -0
  7. data/lib/config/locales/es.yml +44 -0
  8. data/lib/config/locales/fr.yml +45 -0
  9. data/lib/config/locales/hu.yml +47 -0
  10. data/lib/config/locales/it.yml +42 -0
  11. data/lib/config/locales/kr.yml +68 -0
  12. data/lib/config/locales/nl.yml +42 -0
  13. data/lib/config/locales/pl.yml +42 -0
  14. data/lib/config/locales/pt-br.yml +43 -0
  15. data/lib/config/locales/pt.yml +43 -0
  16. data/lib/config/locales/ro.yml +49 -0
  17. data/lib/config/locales/sv.yml +43 -0
  18. data/lib/config/locales/zh-CN.yml +34 -0
  19. data/lib/mongoid/atomicity.rb +111 -0
  20. data/lib/mongoid/attributes.rb +251 -0
  21. data/lib/mongoid/callbacks.rb +13 -0
  22. data/lib/mongoid/collection.rb +137 -0
  23. data/lib/mongoid/collections/cyclic_iterator.rb +34 -0
  24. data/lib/mongoid/collections/master.rb +29 -0
  25. data/lib/mongoid/collections/operations.rb +42 -0
  26. data/lib/mongoid/collections/slaves.rb +45 -0
  27. data/lib/mongoid/collections.rb +70 -0
  28. data/lib/mongoid/components.rb +45 -0
  29. data/lib/mongoid/config/database.rb +167 -0
  30. data/lib/mongoid/config/replset_database.rb +48 -0
  31. data/lib/mongoid/config.rb +343 -0
  32. data/lib/mongoid/contexts/enumerable/sort.rb +43 -0
  33. data/lib/mongoid/contexts/enumerable.rb +226 -0
  34. data/lib/mongoid/contexts/ids.rb +25 -0
  35. data/lib/mongoid/contexts/mongo.rb +345 -0
  36. data/lib/mongoid/contexts/paging.rb +50 -0
  37. data/lib/mongoid/contexts.rb +21 -0
  38. data/lib/mongoid/copyable.rb +44 -0
  39. data/lib/mongoid/criteria.rb +325 -0
  40. data/lib/mongoid/criterion/complex.rb +34 -0
  41. data/lib/mongoid/criterion/creational.rb +34 -0
  42. data/lib/mongoid/criterion/exclusion.rb +67 -0
  43. data/lib/mongoid/criterion/inclusion.rb +134 -0
  44. data/lib/mongoid/criterion/inspection.rb +20 -0
  45. data/lib/mongoid/criterion/optional.rb +213 -0
  46. data/lib/mongoid/criterion/selector.rb +74 -0
  47. data/lib/mongoid/cursor.rb +81 -0
  48. data/lib/mongoid/default_scope.rb +28 -0
  49. data/lib/mongoid/dirty.rb +251 -0
  50. data/lib/mongoid/document.rb +256 -0
  51. data/lib/mongoid/errors/document_not_found.rb +29 -0
  52. data/lib/mongoid/errors/invalid_collection.rb +19 -0
  53. data/lib/mongoid/errors/invalid_database.rb +20 -0
  54. data/lib/mongoid/errors/invalid_field.rb +19 -0
  55. data/lib/mongoid/errors/invalid_options.rb +16 -0
  56. data/lib/mongoid/errors/invalid_type.rb +26 -0
  57. data/lib/mongoid/errors/mongoid_error.rb +27 -0
  58. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +21 -0
  59. data/lib/mongoid/errors/unsaved_document.rb +23 -0
  60. data/lib/mongoid/errors/unsupported_version.rb +21 -0
  61. data/lib/mongoid/errors/validations.rb +24 -0
  62. data/lib/mongoid/errors.rb +12 -0
  63. data/lib/mongoid/extensions/array/conversions.rb +23 -0
  64. data/lib/mongoid/extensions/array/parentization.rb +13 -0
  65. data/lib/mongoid/extensions/big_decimal/conversions.rb +19 -0
  66. data/lib/mongoid/extensions/binary/conversions.rb +17 -0
  67. data/lib/mongoid/extensions/boolean/conversions.rb +27 -0
  68. data/lib/mongoid/extensions/date/conversions.rb +25 -0
  69. data/lib/mongoid/extensions/datetime/conversions.rb +12 -0
  70. data/lib/mongoid/extensions/false_class/equality.rb +13 -0
  71. data/lib/mongoid/extensions/float/conversions.rb +20 -0
  72. data/lib/mongoid/extensions/hash/conversions.rb +19 -0
  73. data/lib/mongoid/extensions/hash/criteria_helpers.rb +22 -0
  74. data/lib/mongoid/extensions/hash/scoping.rb +12 -0
  75. data/lib/mongoid/extensions/integer/conversions.rb +20 -0
  76. data/lib/mongoid/extensions/nil/collectionization.rb +12 -0
  77. data/lib/mongoid/extensions/object/conversions.rb +25 -0
  78. data/lib/mongoid/extensions/object/reflections.rb +17 -0
  79. data/lib/mongoid/extensions/object/yoda.rb +27 -0
  80. data/lib/mongoid/extensions/object_id/conversions.rb +57 -0
  81. data/lib/mongoid/extensions/proc/scoping.rb +12 -0
  82. data/lib/mongoid/extensions/set/conversions.rb +20 -0
  83. data/lib/mongoid/extensions/string/conversions.rb +34 -0
  84. data/lib/mongoid/extensions/string/inflections.rb +97 -0
  85. data/lib/mongoid/extensions/symbol/conversions.rb +21 -0
  86. data/lib/mongoid/extensions/symbol/inflections.rb +40 -0
  87. data/lib/mongoid/extensions/time_conversions.rb +38 -0
  88. data/lib/mongoid/extensions/true_class/equality.rb +13 -0
  89. data/lib/mongoid/extensions.rb +116 -0
  90. data/lib/mongoid/extras.rb +61 -0
  91. data/lib/mongoid/factory.rb +20 -0
  92. data/lib/mongoid/field.rb +95 -0
  93. data/lib/mongoid/fields.rb +138 -0
  94. data/lib/mongoid/finders.rb +173 -0
  95. data/lib/mongoid/hierarchy.rb +85 -0
  96. data/lib/mongoid/identity.rb +89 -0
  97. data/lib/mongoid/indexes.rb +38 -0
  98. data/lib/mongoid/inspection.rb +58 -0
  99. data/lib/mongoid/javascript/functions.yml +37 -0
  100. data/lib/mongoid/javascript.rb +21 -0
  101. data/lib/mongoid/json.rb +16 -0
  102. data/lib/mongoid/keys.rb +77 -0
  103. data/lib/mongoid/logger.rb +18 -0
  104. data/lib/mongoid/matchers/all.rb +11 -0
  105. data/lib/mongoid/matchers/default.rb +27 -0
  106. data/lib/mongoid/matchers/exists.rb +13 -0
  107. data/lib/mongoid/matchers/gt.rb +11 -0
  108. data/lib/mongoid/matchers/gte.rb +11 -0
  109. data/lib/mongoid/matchers/in.rb +11 -0
  110. data/lib/mongoid/matchers/lt.rb +11 -0
  111. data/lib/mongoid/matchers/lte.rb +11 -0
  112. data/lib/mongoid/matchers/ne.rb +11 -0
  113. data/lib/mongoid/matchers/nin.rb +11 -0
  114. data/lib/mongoid/matchers/size.rb +11 -0
  115. data/lib/mongoid/matchers.rb +55 -0
  116. data/lib/mongoid/modifiers/command.rb +18 -0
  117. data/lib/mongoid/modifiers/inc.rb +24 -0
  118. data/lib/mongoid/modifiers.rb +24 -0
  119. data/lib/mongoid/multi_database.rb +11 -0
  120. data/lib/mongoid/multi_parameter_attributes.rb +80 -0
  121. data/lib/mongoid/named_scope.rb +36 -0
  122. data/lib/mongoid/nested_attributes.rb +43 -0
  123. data/lib/mongoid/paranoia.rb +103 -0
  124. data/lib/mongoid/paths.rb +61 -0
  125. data/lib/mongoid/persistence/command.rb +59 -0
  126. data/lib/mongoid/persistence/insert.rb +53 -0
  127. data/lib/mongoid/persistence/insert_embedded.rb +42 -0
  128. data/lib/mongoid/persistence/remove.rb +44 -0
  129. data/lib/mongoid/persistence/remove_all.rb +40 -0
  130. data/lib/mongoid/persistence/remove_embedded.rb +48 -0
  131. data/lib/mongoid/persistence/update.rb +76 -0
  132. data/lib/mongoid/persistence.rb +237 -0
  133. data/lib/mongoid/railtie.rb +129 -0
  134. data/lib/mongoid/railties/database.rake +171 -0
  135. data/lib/mongoid/railties/document.rb +12 -0
  136. data/lib/mongoid/relations/accessors.rb +157 -0
  137. data/lib/mongoid/relations/auto_save.rb +34 -0
  138. data/lib/mongoid/relations/binding.rb +26 -0
  139. data/lib/mongoid/relations/bindings/embedded/in.rb +82 -0
  140. data/lib/mongoid/relations/bindings/embedded/many.rb +98 -0
  141. data/lib/mongoid/relations/bindings/embedded/one.rb +66 -0
  142. data/lib/mongoid/relations/bindings/referenced/in.rb +74 -0
  143. data/lib/mongoid/relations/bindings/referenced/many.rb +96 -0
  144. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +99 -0
  145. data/lib/mongoid/relations/bindings/referenced/one.rb +66 -0
  146. data/lib/mongoid/relations/bindings.rb +9 -0
  147. data/lib/mongoid/relations/builder.rb +42 -0
  148. data/lib/mongoid/relations/builders/embedded/in.rb +25 -0
  149. data/lib/mongoid/relations/builders/embedded/many.rb +32 -0
  150. data/lib/mongoid/relations/builders/embedded/one.rb +26 -0
  151. data/lib/mongoid/relations/builders/nested_attributes/many.rb +116 -0
  152. data/lib/mongoid/relations/builders/nested_attributes/one.rb +135 -0
  153. data/lib/mongoid/relations/builders/referenced/in.rb +32 -0
  154. data/lib/mongoid/relations/builders/referenced/many.rb +26 -0
  155. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +29 -0
  156. data/lib/mongoid/relations/builders/referenced/one.rb +30 -0
  157. data/lib/mongoid/relations/builders.rb +79 -0
  158. data/lib/mongoid/relations/cascading/delete.rb +19 -0
  159. data/lib/mongoid/relations/cascading/destroy.rb +19 -0
  160. data/lib/mongoid/relations/cascading/nullify.rb +18 -0
  161. data/lib/mongoid/relations/cascading/strategy.rb +26 -0
  162. data/lib/mongoid/relations/cascading.rb +55 -0
  163. data/lib/mongoid/relations/constraint.rb +45 -0
  164. data/lib/mongoid/relations/cyclic.rb +97 -0
  165. data/lib/mongoid/relations/embedded/in.rb +173 -0
  166. data/lib/mongoid/relations/embedded/many.rb +483 -0
  167. data/lib/mongoid/relations/embedded/one.rb +170 -0
  168. data/lib/mongoid/relations/macros.rb +306 -0
  169. data/lib/mongoid/relations/many.rb +171 -0
  170. data/lib/mongoid/relations/metadata.rb +533 -0
  171. data/lib/mongoid/relations/nested_builder.rb +68 -0
  172. data/lib/mongoid/relations/one.rb +47 -0
  173. data/lib/mongoid/relations/polymorphic.rb +54 -0
  174. data/lib/mongoid/relations/proxy.rb +128 -0
  175. data/lib/mongoid/relations/referenced/in.rb +216 -0
  176. data/lib/mongoid/relations/referenced/many.rb +443 -0
  177. data/lib/mongoid/relations/referenced/many_to_many.rb +344 -0
  178. data/lib/mongoid/relations/referenced/one.rb +206 -0
  179. data/lib/mongoid/relations/reflections.rb +45 -0
  180. data/lib/mongoid/relations.rb +105 -0
  181. data/lib/mongoid/safe.rb +23 -0
  182. data/lib/mongoid/safety.rb +207 -0
  183. data/lib/mongoid/scope.rb +31 -0
  184. data/lib/mongoid/serialization.rb +99 -0
  185. data/lib/mongoid/state.rb +66 -0
  186. data/lib/mongoid/timestamps.rb +38 -0
  187. data/lib/mongoid/validations/associated.rb +42 -0
  188. data/lib/mongoid/validations/uniqueness.rb +85 -0
  189. data/lib/mongoid/validations.rb +117 -0
  190. data/lib/mongoid/version.rb +4 -0
  191. data/lib/mongoid/versioning.rb +51 -0
  192. data/lib/mongoid.rb +139 -0
  193. data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
  194. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +23 -0
  195. data/lib/rails/generators/mongoid/model/model_generator.rb +24 -0
  196. data/lib/rails/generators/mongoid/model/templates/model.rb +17 -0
  197. data/lib/rails/generators/mongoid_generator.rb +61 -0
  198. data/lib/rails/mongoid.rb +57 -0
  199. metadata +380 -0
@@ -0,0 +1,443 @@
1
+ # encoding: utf-8
2
+ module Mongoid #:nodoc:
3
+ module Relations #:nodoc:
4
+ module Referenced #:nodoc:
5
+
6
+ # This class defines the behaviour for all relations that are a
7
+ # one-to-many between documents in different collections.
8
+ class Many < Relations::Many
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.posts.bind
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.map(&:save) if base.persisted? && !options[:binding]
30
+ end
31
+
32
+ # Clear the relation. Will delete the documents from the db if they are
33
+ # already persisted.
34
+ #
35
+ # @example Clear the relation.
36
+ # person.posts.clear
37
+ #
38
+ # @return [ Many ] The relation emptied.
39
+ def clear
40
+ load! and tap do |relation|
41
+ relation.unbind(default_options)
42
+ target.clear
43
+ end
44
+ end
45
+
46
+ # Returns a count of the number of documents in the association that have
47
+ # actually been persisted to the database.
48
+ #
49
+ # Use #size if you want the total number of documents in memory.
50
+ #
51
+ # @example Get the count of persisted documents.
52
+ # person.posts.count
53
+ #
54
+ # @return [ Integer ] The total number of persisted documents.
55
+ def count
56
+ criteria.count
57
+ end
58
+
59
+ # Creates a new document on the references many relation. This will
60
+ # save the document if the parent has been persisted.
61
+ #
62
+ # @example Create and save the new document.
63
+ # person.posts.create(:text => "Testing")
64
+ #
65
+ # @param [ Hash ] attributes The attributes to create with.
66
+ # @param [ Class ] type The optional type of document to create.
67
+ #
68
+ # @return [ Document ] The newly created document.
69
+ def create(attributes = nil, type = nil)
70
+ build(attributes, type).tap do |doc|
71
+ base.persisted? ? doc.save : raise_unsaved(doc)
72
+ end
73
+ end
74
+
75
+ # Creates a new document on the references many relation. This will
76
+ # save the document if the parent has been persisted and will raise an
77
+ # error if validation fails.
78
+ #
79
+ # @example Create and save the new document.
80
+ # person.posts.create!(:text => "Testing")
81
+ #
82
+ # @param [ Hash ] attributes The attributes to create with.
83
+ # @param [ Class ] type The optional type of document to create.
84
+ #
85
+ # @raise [ Errors::Validations ] If validation failed.
86
+ #
87
+ # @return [ Document ] The newly created document.
88
+ def create!(attributes = nil, type = nil)
89
+ build(attributes, type).tap do |doc|
90
+ base.persisted? ? doc.save! : raise_unsaved(doc)
91
+ end
92
+ end
93
+
94
+ # Deletes all related documents from the database given the supplied
95
+ # conditions.
96
+ #
97
+ # @example Delete all documents in the relation.
98
+ # person.posts.delete_all
99
+ #
100
+ # @example Conditonally delete all documents in the relation.
101
+ # person.posts.delete_all(:conditions => { :title => "Testing" })
102
+ #
103
+ # @param [ Hash ] conditions Optional conditions to delete with.
104
+ #
105
+ # @return [ Integer ] The number of documents deleted.
106
+ def delete_all(conditions = nil)
107
+ selector = (conditions || {})[:conditions] || {}
108
+ target.delete_if { |doc| doc.matches?(selector) }
109
+ metadata.klass.delete_all(
110
+ :conditions => selector.merge(metadata.foreign_key => base.id)
111
+ )
112
+ end
113
+
114
+ # Destroys all related documents from the database given the supplied
115
+ # conditions.
116
+ #
117
+ # @example Destroy all documents in the relation.
118
+ # person.posts.destroy_all
119
+ #
120
+ # @example Conditonally destroy all documents in the relation.
121
+ # person.posts.destroy_all(:conditions => { :title => "Testing" })
122
+ #
123
+ # @param [ Hash ] conditions Optional conditions to destroy with.
124
+ #
125
+ # @return [ Integer ] The number of documents destroyd.
126
+ def destroy_all(conditions = nil)
127
+ selector = (conditions || {})[:conditions] || {}
128
+ target.delete_if { |doc| doc.matches?(selector) }
129
+ metadata.klass.destroy_all(
130
+ :conditions => selector.merge(metadata.foreign_key => base.id)
131
+ )
132
+ end
133
+
134
+ # Find the matchind document on the association, either based on id or
135
+ # conditions.
136
+ #
137
+ # @example Find by an id.
138
+ # person.posts.find(BSON::ObjectId.new)
139
+ #
140
+ # @example Find by multiple ids.
141
+ # person.posts.find([ BSON::ObjectId.new, BSON::ObjectId.new ])
142
+ #
143
+ # @example Conditionally find all matching documents.
144
+ # person.posts.find(:all, :conditions => { :title => "Sir" })
145
+ #
146
+ # @example Conditionally find the first document.
147
+ # person.posts.find(:first, :conditions => { :title => "Sir" })
148
+ #
149
+ # @example Conditionally find the last document.
150
+ # person.posts.find(:last, :conditions => { :title => "Sir" })
151
+ #
152
+ # @param [ Symbol, BSON::ObjectId, Array<BSON::ObjectId> ] arg The
153
+ # argument to search with.
154
+ # @param [ Hash ] options The options to search with.
155
+ #
156
+ # @return [ Document, Criteria ] The matching document(s).
157
+ def find(arg, options = {})
158
+ klass = metadata.klass
159
+ return klass.criteria.id_criteria(arg) unless arg.is_a?(Symbol)
160
+ selector = (options[:conditions] || {}).merge(
161
+ metadata.foreign_key => base.id
162
+ )
163
+ klass.find(arg, :conditions => selector)
164
+ end
165
+
166
+ # Instantiate a new references_many relation. Will set the foreign key
167
+ # and the base on the inverse object.
168
+ #
169
+ # @example Create the new relation.
170
+ # Referenced::Many.new(base, target, metadata)
171
+ #
172
+ # @param [ Document ] base The document this relation hangs off of.
173
+ # @param [ Array<Document> ] target The target of the relation.
174
+ # @param [ Metadata ] metadata The relation's metadata.
175
+ def initialize(base, target, metadata)
176
+ init(base, target, metadata)
177
+ end
178
+
179
+ # Will load the target into an array if the target had not already been
180
+ # loaded.
181
+ #
182
+ # @example Load the relation into memory.
183
+ # relation.load!
184
+ #
185
+ # @return [ Many ] The relation.
186
+ #
187
+ # @since 2.0.0.rc.5
188
+ def load!(options = {})
189
+ tap do |relation|
190
+ unless relation.loaded?
191
+ relation.target = target.entries
192
+ relation.bind(options)
193
+ relation.loaded = true
194
+ end
195
+ end
196
+ end
197
+
198
+ # Removes all associations between the base document and the target
199
+ # documents by deleting the foreign keys and the references, orphaning
200
+ # the target documents in the process.
201
+ #
202
+ # @example Nullify the relation.
203
+ # person.posts.nullify
204
+ #
205
+ # @since 2.0.0.rc.1
206
+ def nullify
207
+ load! and target.each do |doc|
208
+ doc.send(metadata.foreign_key_setter, nil)
209
+ doc.send(
210
+ :remove_instance_variable, "@#{metadata.inverse(doc)}"
211
+ )
212
+ doc.save
213
+ end
214
+ end
215
+ alias :nullify_all :nullify
216
+
217
+ # Substitutes the supplied target documents for the existing documents
218
+ # in the relation. If the new target is nil, perform the necessary
219
+ # deletion.
220
+ #
221
+ # @example Replace the relation.
222
+ # person.posts.substitute(new_name)
223
+ #
224
+ # @param [ Array<Document> ] target The replacement target.
225
+ # @param [ Hash ] options The options to bind with.
226
+ #
227
+ # @option options [ true, false ] :binding Are we in build mode?
228
+ # @option options [ true, false ] :continue Continue binding the
229
+ # inverse?
230
+ #
231
+ # @return [ Many ] The relation.
232
+ #
233
+ # @since 2.0.0.rc.1
234
+ def substitute(target, options = {})
235
+ tap { target ? (@target = target.to_a; bind(options)) : (@target = unbind(options)) }
236
+ end
237
+
238
+ # Unbinds the base object to the inverse of the relation. This occurs
239
+ # when setting a side of the relation to nil.
240
+ #
241
+ # Will delete the object if necessary.
242
+ #
243
+ # @example Unbind the target.
244
+ # person.posts.unbind
245
+ #
246
+ # @param [ Hash ] options The options to bind with.
247
+ #
248
+ # @option options [ true, false ] :binding Are we in build mode?
249
+ # @option options [ true, false ] :continue Continue binding the
250
+ # inverse?
251
+ #
252
+ # @since 2.0.0.rc.1
253
+ def unbind(options = {})
254
+ binding.unbind(options)
255
+ target.each(&:delete) if base.persisted?
256
+ []
257
+ end
258
+
259
+ private
260
+
261
+ # Appends the document to the target array, updating the index on the
262
+ # document at the same time.
263
+ #
264
+ # @example Append the document to the relation.
265
+ # relation.append(document)
266
+ #
267
+ # @param [ Document ] document The document to append to the target.
268
+ #
269
+ # @since 2.0.0.rc.1
270
+ def append(document, options = {})
271
+ load!(options) and target.push(document)
272
+ characterize_one(document)
273
+ binding.bind_one(document, options)
274
+ end
275
+
276
+ # Instantiate the binding associated with this relation.
277
+ #
278
+ # @example Get the binding.
279
+ # relation.binding([ address ])
280
+ #
281
+ # @param [ Array<Document> ] new_target The new documents to bind with.
282
+ #
283
+ # @return [ Binding ] The binding.
284
+ #
285
+ # @since 2.0.0.rc.1
286
+ def binding(new_target = nil)
287
+ Bindings::Referenced::Many.new(base, new_target || target, metadata)
288
+ end
289
+
290
+ # Returns the criteria object for the target class with its documents set
291
+ # to target.
292
+ #
293
+ # @example Get a criteria for the relation.
294
+ # relation.criteria
295
+ #
296
+ # @return [ Criteria ] A new criteria.
297
+ def criteria
298
+ metadata.klass.where(metadata.foreign_key => base.id)
299
+ end
300
+
301
+ # If the target array does not respond to the supplied method then try to
302
+ # find a named scope or criteria on the class and send the call there.
303
+ #
304
+ # If the method exists on the array, use the default proxy behavior.
305
+ #
306
+ # @param [ Symbol, String ] name The name of the method.
307
+ # @param [ Array ] args The method args
308
+ # @param [ Proc ] block Optional block to pass.
309
+ #
310
+ # @return [ Criteria, Object ] A Criteria or return value from the target.
311
+ def method_missing(name, *args, &block)
312
+ load!(:binding => true) and return super if [].respond_to?(name)
313
+ klass = metadata.klass
314
+ klass.send(:with_scope, criteria) do
315
+ criteria.send(name, *args)
316
+ end
317
+ end
318
+
319
+ # When the base is not yet saved and the user calls create or create!
320
+ # on the relation, this error will get raised.
321
+ #
322
+ # @example Raise the error.
323
+ # relation.raise_unsaved(post)
324
+ #
325
+ # @param [ Document ] doc The child document getting created.
326
+ #
327
+ # @raise [ Errors::UnsavedDocument ] The error.
328
+ #
329
+ # @since 2.0.0.rc.6
330
+ def raise_unsaved(doc)
331
+ raise Errors::UnsavedDocument.new(base, doc)
332
+ end
333
+
334
+ class << self
335
+
336
+ # Return the builder that is responsible for generating the documents
337
+ # that will be used by this relation.
338
+ #
339
+ # @example Get the builder.
340
+ # Referenced::Many.builder(meta, object)
341
+ #
342
+ # @param [ Metadata ] meta The metadata of the relation.
343
+ # @param [ Document, Hash ] object A document or attributes to build
344
+ # with.
345
+ #
346
+ # @return [ Builder ] A new builder object.
347
+ #
348
+ # @since 2.0.0.rc.1
349
+ def builder(meta, object)
350
+ Builders::Referenced::Many.new(meta, object)
351
+ end
352
+
353
+ # Returns true if the relation is an embedded one. In this case
354
+ # always false.
355
+ #
356
+ # @example Is this relation embedded?
357
+ # Referenced::Many.embedded?
358
+ #
359
+ # @return [ false ] Always false.
360
+ #
361
+ # @since 2.0.0.rc.1
362
+ def embedded?
363
+ false
364
+ end
365
+
366
+ # Get the default value for the foreign key.
367
+ #
368
+ # @example Get the default.
369
+ # Referenced::Many.foreign_key_default
370
+ #
371
+ # @return [ nil ] Always nil.
372
+ #
373
+ # @since 2.0.0.rc.1
374
+ def foreign_key_default
375
+ nil
376
+ end
377
+
378
+ # Returns the suffix of the foreign key field, either "_id" or "_ids".
379
+ #
380
+ # @example Get the suffix for the foreign key.
381
+ # Referenced::Many.foreign_key_suffix
382
+ #
383
+ # @return [ String ] "_id"
384
+ #
385
+ # @since 2.0.0.rc.1
386
+ def foreign_key_suffix
387
+ "_id"
388
+ end
389
+
390
+ # Returns the macro for this relation. Used mostly as a helper in
391
+ # reflection.
392
+ #
393
+ # @example Get the macro.
394
+ # Referenced::Many.macro
395
+ #
396
+ # @return [ Symbol ] :references_many
397
+ def macro
398
+ :references_many
399
+ end
400
+
401
+ # Return the nested builder that is responsible for generating the documents
402
+ # that will be used by this relation.
403
+ #
404
+ # @example Get the nested builder.
405
+ # Referenced::Many.builder(attributes, options)
406
+ #
407
+ # @param [ Metadata ] metadata The relation metadata.
408
+ # @param [ Hash ] attributes The attributes to build with.
409
+ # @param [ Hash ] options The options for the builder.
410
+ #
411
+ # @option options [ true, false ] :allow_destroy Can documents be
412
+ # deleted?
413
+ # @option options [ Integer ] :limit Max number of documents to
414
+ # create at once.
415
+ # @option options [ Proc, Symbol ] :reject_if If documents match this
416
+ # option then they are ignored.
417
+ # @option options [ true, false ] :update_only Only existing documents
418
+ # can be modified.
419
+ #
420
+ # @return [ NestedBuilder ] A newly instantiated nested builder object.
421
+ #
422
+ # @since 2.0.0.rc.1
423
+ def nested_builder(metadata, attributes, options)
424
+ Builders::NestedAttributes::Many.new(metadata, attributes, options)
425
+ end
426
+
427
+ # Tells the caller if this relation is one that stores the foreign
428
+ # key on its own objects.
429
+ #
430
+ # @example Does this relation store a foreign key?
431
+ # Referenced::Many.stores_foreign_key?
432
+ #
433
+ # @return [ false ] Always false.
434
+ #
435
+ # @since 2.0.0.rc.1
436
+ def stores_foreign_key?
437
+ false
438
+ end
439
+ end
440
+ end
441
+ end
442
+ end
443
+ end