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.
- data/LICENSE +20 -0
- data/README.rdoc +50 -0
- data/Rakefile +51 -0
- data/lib/config/locales/bg.yml +44 -0
- data/lib/config/locales/de.yml +44 -0
- data/lib/config/locales/en.yml +45 -0
- data/lib/config/locales/es.yml +44 -0
- data/lib/config/locales/fr.yml +45 -0
- data/lib/config/locales/hu.yml +47 -0
- data/lib/config/locales/it.yml +42 -0
- data/lib/config/locales/kr.yml +68 -0
- data/lib/config/locales/nl.yml +42 -0
- data/lib/config/locales/pl.yml +42 -0
- data/lib/config/locales/pt-br.yml +43 -0
- data/lib/config/locales/pt.yml +43 -0
- data/lib/config/locales/ro.yml +49 -0
- data/lib/config/locales/sv.yml +43 -0
- data/lib/config/locales/zh-CN.yml +34 -0
- data/lib/mongoid/atomicity.rb +111 -0
- data/lib/mongoid/attributes.rb +251 -0
- data/lib/mongoid/callbacks.rb +13 -0
- data/lib/mongoid/collection.rb +137 -0
- data/lib/mongoid/collections/cyclic_iterator.rb +34 -0
- data/lib/mongoid/collections/master.rb +29 -0
- data/lib/mongoid/collections/operations.rb +42 -0
- data/lib/mongoid/collections/slaves.rb +45 -0
- data/lib/mongoid/collections.rb +70 -0
- data/lib/mongoid/components.rb +45 -0
- data/lib/mongoid/config/database.rb +167 -0
- data/lib/mongoid/config/replset_database.rb +48 -0
- data/lib/mongoid/config.rb +343 -0
- data/lib/mongoid/contexts/enumerable/sort.rb +43 -0
- data/lib/mongoid/contexts/enumerable.rb +226 -0
- data/lib/mongoid/contexts/ids.rb +25 -0
- data/lib/mongoid/contexts/mongo.rb +345 -0
- data/lib/mongoid/contexts/paging.rb +50 -0
- data/lib/mongoid/contexts.rb +21 -0
- data/lib/mongoid/copyable.rb +44 -0
- data/lib/mongoid/criteria.rb +325 -0
- data/lib/mongoid/criterion/complex.rb +34 -0
- data/lib/mongoid/criterion/creational.rb +34 -0
- data/lib/mongoid/criterion/exclusion.rb +67 -0
- data/lib/mongoid/criterion/inclusion.rb +134 -0
- data/lib/mongoid/criterion/inspection.rb +20 -0
- data/lib/mongoid/criterion/optional.rb +213 -0
- data/lib/mongoid/criterion/selector.rb +74 -0
- data/lib/mongoid/cursor.rb +81 -0
- data/lib/mongoid/default_scope.rb +28 -0
- data/lib/mongoid/dirty.rb +251 -0
- data/lib/mongoid/document.rb +256 -0
- data/lib/mongoid/errors/document_not_found.rb +29 -0
- data/lib/mongoid/errors/invalid_collection.rb +19 -0
- data/lib/mongoid/errors/invalid_database.rb +20 -0
- data/lib/mongoid/errors/invalid_field.rb +19 -0
- data/lib/mongoid/errors/invalid_options.rb +16 -0
- data/lib/mongoid/errors/invalid_type.rb +26 -0
- data/lib/mongoid/errors/mongoid_error.rb +27 -0
- data/lib/mongoid/errors/too_many_nested_attribute_records.rb +21 -0
- data/lib/mongoid/errors/unsaved_document.rb +23 -0
- data/lib/mongoid/errors/unsupported_version.rb +21 -0
- data/lib/mongoid/errors/validations.rb +24 -0
- data/lib/mongoid/errors.rb +12 -0
- data/lib/mongoid/extensions/array/conversions.rb +23 -0
- data/lib/mongoid/extensions/array/parentization.rb +13 -0
- data/lib/mongoid/extensions/big_decimal/conversions.rb +19 -0
- data/lib/mongoid/extensions/binary/conversions.rb +17 -0
- data/lib/mongoid/extensions/boolean/conversions.rb +27 -0
- data/lib/mongoid/extensions/date/conversions.rb +25 -0
- data/lib/mongoid/extensions/datetime/conversions.rb +12 -0
- data/lib/mongoid/extensions/false_class/equality.rb +13 -0
- data/lib/mongoid/extensions/float/conversions.rb +20 -0
- data/lib/mongoid/extensions/hash/conversions.rb +19 -0
- data/lib/mongoid/extensions/hash/criteria_helpers.rb +22 -0
- data/lib/mongoid/extensions/hash/scoping.rb +12 -0
- data/lib/mongoid/extensions/integer/conversions.rb +20 -0
- data/lib/mongoid/extensions/nil/collectionization.rb +12 -0
- data/lib/mongoid/extensions/object/conversions.rb +25 -0
- data/lib/mongoid/extensions/object/reflections.rb +17 -0
- data/lib/mongoid/extensions/object/yoda.rb +27 -0
- data/lib/mongoid/extensions/object_id/conversions.rb +57 -0
- data/lib/mongoid/extensions/proc/scoping.rb +12 -0
- data/lib/mongoid/extensions/set/conversions.rb +20 -0
- data/lib/mongoid/extensions/string/conversions.rb +34 -0
- data/lib/mongoid/extensions/string/inflections.rb +97 -0
- data/lib/mongoid/extensions/symbol/conversions.rb +21 -0
- data/lib/mongoid/extensions/symbol/inflections.rb +40 -0
- data/lib/mongoid/extensions/time_conversions.rb +38 -0
- data/lib/mongoid/extensions/true_class/equality.rb +13 -0
- data/lib/mongoid/extensions.rb +116 -0
- data/lib/mongoid/extras.rb +61 -0
- data/lib/mongoid/factory.rb +20 -0
- data/lib/mongoid/field.rb +95 -0
- data/lib/mongoid/fields.rb +138 -0
- data/lib/mongoid/finders.rb +173 -0
- data/lib/mongoid/hierarchy.rb +85 -0
- data/lib/mongoid/identity.rb +89 -0
- data/lib/mongoid/indexes.rb +38 -0
- data/lib/mongoid/inspection.rb +58 -0
- data/lib/mongoid/javascript/functions.yml +37 -0
- data/lib/mongoid/javascript.rb +21 -0
- data/lib/mongoid/json.rb +16 -0
- data/lib/mongoid/keys.rb +77 -0
- data/lib/mongoid/logger.rb +18 -0
- data/lib/mongoid/matchers/all.rb +11 -0
- data/lib/mongoid/matchers/default.rb +27 -0
- data/lib/mongoid/matchers/exists.rb +13 -0
- data/lib/mongoid/matchers/gt.rb +11 -0
- data/lib/mongoid/matchers/gte.rb +11 -0
- data/lib/mongoid/matchers/in.rb +11 -0
- data/lib/mongoid/matchers/lt.rb +11 -0
- data/lib/mongoid/matchers/lte.rb +11 -0
- data/lib/mongoid/matchers/ne.rb +11 -0
- data/lib/mongoid/matchers/nin.rb +11 -0
- data/lib/mongoid/matchers/size.rb +11 -0
- data/lib/mongoid/matchers.rb +55 -0
- data/lib/mongoid/modifiers/command.rb +18 -0
- data/lib/mongoid/modifiers/inc.rb +24 -0
- data/lib/mongoid/modifiers.rb +24 -0
- data/lib/mongoid/multi_database.rb +11 -0
- data/lib/mongoid/multi_parameter_attributes.rb +80 -0
- data/lib/mongoid/named_scope.rb +36 -0
- data/lib/mongoid/nested_attributes.rb +43 -0
- data/lib/mongoid/paranoia.rb +103 -0
- data/lib/mongoid/paths.rb +61 -0
- data/lib/mongoid/persistence/command.rb +59 -0
- data/lib/mongoid/persistence/insert.rb +53 -0
- data/lib/mongoid/persistence/insert_embedded.rb +42 -0
- data/lib/mongoid/persistence/remove.rb +44 -0
- data/lib/mongoid/persistence/remove_all.rb +40 -0
- data/lib/mongoid/persistence/remove_embedded.rb +48 -0
- data/lib/mongoid/persistence/update.rb +76 -0
- data/lib/mongoid/persistence.rb +237 -0
- data/lib/mongoid/railtie.rb +129 -0
- data/lib/mongoid/railties/database.rake +171 -0
- data/lib/mongoid/railties/document.rb +12 -0
- data/lib/mongoid/relations/accessors.rb +157 -0
- data/lib/mongoid/relations/auto_save.rb +34 -0
- data/lib/mongoid/relations/binding.rb +26 -0
- data/lib/mongoid/relations/bindings/embedded/in.rb +82 -0
- data/lib/mongoid/relations/bindings/embedded/many.rb +98 -0
- data/lib/mongoid/relations/bindings/embedded/one.rb +66 -0
- data/lib/mongoid/relations/bindings/referenced/in.rb +74 -0
- data/lib/mongoid/relations/bindings/referenced/many.rb +96 -0
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +99 -0
- data/lib/mongoid/relations/bindings/referenced/one.rb +66 -0
- data/lib/mongoid/relations/bindings.rb +9 -0
- data/lib/mongoid/relations/builder.rb +42 -0
- data/lib/mongoid/relations/builders/embedded/in.rb +25 -0
- data/lib/mongoid/relations/builders/embedded/many.rb +32 -0
- data/lib/mongoid/relations/builders/embedded/one.rb +26 -0
- data/lib/mongoid/relations/builders/nested_attributes/many.rb +116 -0
- data/lib/mongoid/relations/builders/nested_attributes/one.rb +135 -0
- data/lib/mongoid/relations/builders/referenced/in.rb +32 -0
- data/lib/mongoid/relations/builders/referenced/many.rb +26 -0
- data/lib/mongoid/relations/builders/referenced/many_to_many.rb +29 -0
- data/lib/mongoid/relations/builders/referenced/one.rb +30 -0
- data/lib/mongoid/relations/builders.rb +79 -0
- data/lib/mongoid/relations/cascading/delete.rb +19 -0
- data/lib/mongoid/relations/cascading/destroy.rb +19 -0
- data/lib/mongoid/relations/cascading/nullify.rb +18 -0
- data/lib/mongoid/relations/cascading/strategy.rb +26 -0
- data/lib/mongoid/relations/cascading.rb +55 -0
- data/lib/mongoid/relations/constraint.rb +45 -0
- data/lib/mongoid/relations/cyclic.rb +97 -0
- data/lib/mongoid/relations/embedded/in.rb +173 -0
- data/lib/mongoid/relations/embedded/many.rb +483 -0
- data/lib/mongoid/relations/embedded/one.rb +170 -0
- data/lib/mongoid/relations/macros.rb +306 -0
- data/lib/mongoid/relations/many.rb +171 -0
- data/lib/mongoid/relations/metadata.rb +533 -0
- data/lib/mongoid/relations/nested_builder.rb +68 -0
- data/lib/mongoid/relations/one.rb +47 -0
- data/lib/mongoid/relations/polymorphic.rb +54 -0
- data/lib/mongoid/relations/proxy.rb +128 -0
- data/lib/mongoid/relations/referenced/in.rb +216 -0
- data/lib/mongoid/relations/referenced/many.rb +443 -0
- data/lib/mongoid/relations/referenced/many_to_many.rb +344 -0
- data/lib/mongoid/relations/referenced/one.rb +206 -0
- data/lib/mongoid/relations/reflections.rb +45 -0
- data/lib/mongoid/relations.rb +105 -0
- data/lib/mongoid/safe.rb +23 -0
- data/lib/mongoid/safety.rb +207 -0
- data/lib/mongoid/scope.rb +31 -0
- data/lib/mongoid/serialization.rb +99 -0
- data/lib/mongoid/state.rb +66 -0
- data/lib/mongoid/timestamps.rb +38 -0
- data/lib/mongoid/validations/associated.rb +42 -0
- data/lib/mongoid/validations/uniqueness.rb +85 -0
- data/lib/mongoid/validations.rb +117 -0
- data/lib/mongoid/version.rb +4 -0
- data/lib/mongoid/versioning.rb +51 -0
- data/lib/mongoid.rb +139 -0
- data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +23 -0
- data/lib/rails/generators/mongoid/model/model_generator.rb +24 -0
- data/lib/rails/generators/mongoid/model/templates/model.rb +17 -0
- data/lib/rails/generators/mongoid_generator.rb +61 -0
- data/lib/rails/mongoid.rb +57 -0
- metadata +380 -0
|
@@ -0,0 +1,306 @@
|
|
|
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
|
+
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
|
+
characterize(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
|
+
characterize(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
|
+
alias :belongs_to :referenced_in
|
|
138
|
+
|
|
139
|
+
# Adds a relational association from a parent Document to many
|
|
140
|
+
# Documents in another database or collection.
|
|
141
|
+
#
|
|
142
|
+
# @example Define the relation.
|
|
143
|
+
#
|
|
144
|
+
# class Person
|
|
145
|
+
# include Mongoid::Document
|
|
146
|
+
# references_many :posts
|
|
147
|
+
# end
|
|
148
|
+
#
|
|
149
|
+
# class Game
|
|
150
|
+
# include Mongoid::Document
|
|
151
|
+
# referenced_in :person
|
|
152
|
+
# end
|
|
153
|
+
#
|
|
154
|
+
# @param [ Symbol ] name The name of the relation.
|
|
155
|
+
# @param [ Hash ] options The relation options.
|
|
156
|
+
# @param [ Proc ] block Optional block for defining extensions.
|
|
157
|
+
def references_many(name, options = {}, &block)
|
|
158
|
+
check_options(options)
|
|
159
|
+
characterize(name, Referenced::Many, options, &block).tap do |meta|
|
|
160
|
+
relate(name, meta)
|
|
161
|
+
reference(meta)
|
|
162
|
+
autosave(meta)
|
|
163
|
+
validate_relation(meta)
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
alias :has_many_related :references_many
|
|
167
|
+
alias :has_many :references_many
|
|
168
|
+
|
|
169
|
+
# Adds a relational many-to-many association between many of this
|
|
170
|
+
# Document and many of another Document.
|
|
171
|
+
#
|
|
172
|
+
# @example Define the relation.
|
|
173
|
+
#
|
|
174
|
+
# class Person
|
|
175
|
+
# include Mongoid::Document
|
|
176
|
+
# references_and_referenced_in_many :preferences
|
|
177
|
+
# end
|
|
178
|
+
#
|
|
179
|
+
# class Preference
|
|
180
|
+
# include Mongoid::Document
|
|
181
|
+
# references_and_referenced_in_many :people
|
|
182
|
+
# end
|
|
183
|
+
#
|
|
184
|
+
# @param [ Symbol ] name The name of the relation.
|
|
185
|
+
# @param [ Hash ] options The relation options.
|
|
186
|
+
# @param [ Proc ] block Optional block for defining extensions.
|
|
187
|
+
#
|
|
188
|
+
# @since 2.0.0.rc.1
|
|
189
|
+
def references_and_referenced_in_many(name, options = {}, &block)
|
|
190
|
+
characterize(name, Referenced::ManyToMany, options, &block).tap do |meta|
|
|
191
|
+
relate(name, meta)
|
|
192
|
+
reference(meta)
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
alias :has_and_belongs_to_many :references_and_referenced_in_many
|
|
196
|
+
|
|
197
|
+
# Adds a relational association from the child Document to a Document in
|
|
198
|
+
# another database or collection.
|
|
199
|
+
#
|
|
200
|
+
# @example Define the relation.
|
|
201
|
+
#
|
|
202
|
+
# class Game
|
|
203
|
+
# include Mongoid::Document
|
|
204
|
+
# referenced_in :person
|
|
205
|
+
# end
|
|
206
|
+
#
|
|
207
|
+
# class Person
|
|
208
|
+
# include Mongoid::Document
|
|
209
|
+
# references_one :game
|
|
210
|
+
# end
|
|
211
|
+
#
|
|
212
|
+
# @param [ Symbol ] name The name of the relation.
|
|
213
|
+
# @param [ Hash ] options The relation options.
|
|
214
|
+
# @param [ Proc ] block Optional block for defining extensions.
|
|
215
|
+
def references_one(name, options = {}, &block)
|
|
216
|
+
characterize(name, Referenced::One, options, &block).tap do |meta|
|
|
217
|
+
relate(name, meta)
|
|
218
|
+
reference(meta)
|
|
219
|
+
builder(name).creator(name).autosave(meta)
|
|
220
|
+
validate_relation(meta)
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
alias :has_one_related :references_one
|
|
224
|
+
alias :has_one :references_one
|
|
225
|
+
|
|
226
|
+
private
|
|
227
|
+
|
|
228
|
+
# Temporary check while people switch over to the new macro. Will be
|
|
229
|
+
# deleted in 2.0.0.
|
|
230
|
+
#
|
|
231
|
+
# @example Check the options.
|
|
232
|
+
# Person.check_options({})
|
|
233
|
+
#
|
|
234
|
+
# @param [ Hash ] options The options given to the relational many.
|
|
235
|
+
#
|
|
236
|
+
# @raise [ RuntimeError ] If :stored_as => :array is found.
|
|
237
|
+
#
|
|
238
|
+
# @since 2.0.0.rc.1
|
|
239
|
+
def check_options(options = {})
|
|
240
|
+
if options[:stored_as] == :array
|
|
241
|
+
raise RuntimeError.new(
|
|
242
|
+
"Macro: references_many :name, :stored_as => :array " <<
|
|
243
|
+
"Is no longer valid. Please use: references_and_referenced_in_many :name"
|
|
244
|
+
)
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# Create the metadata for the relation.
|
|
249
|
+
#
|
|
250
|
+
# @example Create the metadata.
|
|
251
|
+
# Person.characterize(:posts, Referenced::Many, {})
|
|
252
|
+
#
|
|
253
|
+
# @param [ Symbol ] name The name of the relation.
|
|
254
|
+
# @param [ Object ] relation The type of relation.
|
|
255
|
+
# @param [ Hash ] options The relation options.
|
|
256
|
+
# @param [ Proc ] block Optional block for defining extensions.
|
|
257
|
+
#
|
|
258
|
+
# @return [ Metadata ] The metadata for the relation.
|
|
259
|
+
def characterize(name, relation, options, &block)
|
|
260
|
+
Metadata.new(
|
|
261
|
+
options.merge(
|
|
262
|
+
:relation => relation,
|
|
263
|
+
:extend => block,
|
|
264
|
+
:inverse_class_name => self.name,
|
|
265
|
+
:name => name
|
|
266
|
+
)
|
|
267
|
+
)
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
# Defines a field to be used as a foreign key in the relation and
|
|
271
|
+
# indexes it if defined.
|
|
272
|
+
#
|
|
273
|
+
# @example Set up the relational fields and indexes.
|
|
274
|
+
# Person.reference(metadata)
|
|
275
|
+
#
|
|
276
|
+
# @param [ Metadata ] metadata The metadata for the relation.
|
|
277
|
+
def reference(metadata)
|
|
278
|
+
polymorph(metadata).cascade(metadata)
|
|
279
|
+
if metadata.relation.stores_foreign_key?
|
|
280
|
+
key = metadata.foreign_key
|
|
281
|
+
field(
|
|
282
|
+
key,
|
|
283
|
+
:identity => true,
|
|
284
|
+
:metadata => metadata,
|
|
285
|
+
:default => metadata.foreign_key_default
|
|
286
|
+
)
|
|
287
|
+
index(key, :background => true) if metadata.indexed?
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
# Creates a relation for the given name, metadata and relation. It adds
|
|
292
|
+
# the metadata to the relations hash and has the accessors set up.
|
|
293
|
+
#
|
|
294
|
+
# @example Set up the relation and accessors.
|
|
295
|
+
# Person.relate(:addresses, Metadata)
|
|
296
|
+
#
|
|
297
|
+
# @param [ Symbol ] name The name of the relation.
|
|
298
|
+
# @param [ Metadata ] metadata The metadata for the relation.
|
|
299
|
+
def relate(name, metadata)
|
|
300
|
+
relations[name.to_s] = metadata
|
|
301
|
+
getter(name, metadata).setter(name, metadata)
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
end
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid #:nodoc:
|
|
3
|
+
module Relations #:nodoc:
|
|
4
|
+
|
|
5
|
+
# This is the superclass for all many to one and many to many relation
|
|
6
|
+
# proxies.
|
|
7
|
+
class Many < Proxy
|
|
8
|
+
|
|
9
|
+
# Appends a document or array of documents to the relation. Will set
|
|
10
|
+
# the parent and update the index in the process.
|
|
11
|
+
#
|
|
12
|
+
# @example Append a document.
|
|
13
|
+
# person.addresses << address
|
|
14
|
+
#
|
|
15
|
+
# @example Push a document.
|
|
16
|
+
# person.addresses.push(address)
|
|
17
|
+
#
|
|
18
|
+
# @example Concat with other documents.
|
|
19
|
+
# perosn.addresses.concat([ address_one, address_two ])
|
|
20
|
+
#
|
|
21
|
+
# @param [ Document, Array<Document> ] *args Any number of documents.
|
|
22
|
+
def <<(*args)
|
|
23
|
+
options = default_options(args)
|
|
24
|
+
args.flatten.each do |doc|
|
|
25
|
+
append(doc, options)
|
|
26
|
+
doc.save if base.persisted? && !options[:binding]
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
alias :concat :<<
|
|
30
|
+
alias :push :<<
|
|
31
|
+
|
|
32
|
+
# Builds a new document in the relation and appends it to the target.
|
|
33
|
+
# Takes an optional type if you want to specify a subclass.
|
|
34
|
+
#
|
|
35
|
+
# @example Build a new document on the relation.
|
|
36
|
+
# person.people.build(:name => "Bozo")
|
|
37
|
+
#
|
|
38
|
+
# @param [ Hash ] attributes The attributes to build the document with.
|
|
39
|
+
# @param [ Class ] type Optional class to build the document with.
|
|
40
|
+
#
|
|
41
|
+
# @return [ Document ] The new document.
|
|
42
|
+
def build(attributes = {}, type = nil)
|
|
43
|
+
instantiated(type).tap do |doc|
|
|
44
|
+
append(doc, default_options(:binding => true))
|
|
45
|
+
doc.write_attributes(attributes)
|
|
46
|
+
doc.identify
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
alias :new :build
|
|
50
|
+
|
|
51
|
+
# Creates a new document on the references many relation. This will
|
|
52
|
+
# save the document if the parent has been persisted.
|
|
53
|
+
#
|
|
54
|
+
# @example Create and save the new document.
|
|
55
|
+
# person.posts.create(:text => "Testing")
|
|
56
|
+
#
|
|
57
|
+
# @param [ Hash ] attributes The attributes to create with.
|
|
58
|
+
# @param [ Class ] type The optional type of document to create.
|
|
59
|
+
#
|
|
60
|
+
# @return [ Document ] The newly created document.
|
|
61
|
+
def create(attributes = nil, type = nil)
|
|
62
|
+
build(attributes, type).tap do |doc|
|
|
63
|
+
doc.save if base.persisted?
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Creates a new document on the references many relation. This will
|
|
68
|
+
# save the document if the parent has been persisted and will raise an
|
|
69
|
+
# error if validation fails.
|
|
70
|
+
#
|
|
71
|
+
# @example Create and save the new document.
|
|
72
|
+
# person.posts.create!(:text => "Testing")
|
|
73
|
+
#
|
|
74
|
+
# @param [ Hash ] attributes The attributes to create with.
|
|
75
|
+
# @param [ Class ] type The optional type of document to create.
|
|
76
|
+
#
|
|
77
|
+
# @raise [ Errors::Validations ] If validation failed.
|
|
78
|
+
#
|
|
79
|
+
# @return [ Document ] The newly created document.
|
|
80
|
+
def create!(attributes = nil, type = nil)
|
|
81
|
+
build(attributes, type).tap do |doc|
|
|
82
|
+
doc.save! if base.persisted?
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Determine if any documents in this relation exist in the database.
|
|
87
|
+
#
|
|
88
|
+
# @example Are there persisted documents?
|
|
89
|
+
# person.posts.exists?
|
|
90
|
+
#
|
|
91
|
+
# @return [ true, false ] True is persisted documents exist, false if not.
|
|
92
|
+
def exists?
|
|
93
|
+
count > 0
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Find the first document given the conditions, or creates a new document
|
|
97
|
+
# with the conditions that were supplied.
|
|
98
|
+
#
|
|
99
|
+
# @example Find or create.
|
|
100
|
+
# person.posts.find_or_create_by(:title => "Testing")
|
|
101
|
+
#
|
|
102
|
+
# @param [ Hash ] attrs The attributes to search or create with.
|
|
103
|
+
#
|
|
104
|
+
# @return [ Document ] An existing document or newly created one.
|
|
105
|
+
def find_or_create_by(attrs = {})
|
|
106
|
+
find_or(:create, attrs)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Find the first +Document+ given the conditions, or instantiates a new document
|
|
110
|
+
# with the conditions that were supplied
|
|
111
|
+
#
|
|
112
|
+
# @example Find or initialize.
|
|
113
|
+
# person.posts.find_or_initialize_by(:title => "Test")
|
|
114
|
+
#
|
|
115
|
+
# @param [ Hash ] attrs The attributes to search or initialize with.
|
|
116
|
+
#
|
|
117
|
+
# @return [ Document ] An existing document or newly instantiated one.
|
|
118
|
+
def find_or_initialize_by(attrs = {})
|
|
119
|
+
find_or(:build, attrs)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Gets the document as a serializable hash, used by ActiveModel's JSON and
|
|
123
|
+
# XML serializers. This override is just to be able to pass the :include
|
|
124
|
+
# and :except options to get associations in the hash.
|
|
125
|
+
#
|
|
126
|
+
# @example Get the serializable hash.
|
|
127
|
+
# relation.serializable_hash
|
|
128
|
+
#
|
|
129
|
+
# @param [ Hash ] options The options to pass.
|
|
130
|
+
#
|
|
131
|
+
# @option options [ Symbol ] :include What relations to include
|
|
132
|
+
# @option options [ Symbol ] :only Limit the fields to only these.
|
|
133
|
+
# @option options [ Symbol ] :except Dont include these fields.
|
|
134
|
+
#
|
|
135
|
+
# @return [ Hash ] The documents, ready to be serialized.
|
|
136
|
+
#
|
|
137
|
+
# @since 2.0.0.rc.6
|
|
138
|
+
def serializable_hash(options = {})
|
|
139
|
+
target.map { |document| document.serializable_hash(options) }
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
private
|
|
143
|
+
|
|
144
|
+
# Get the default options used in binding functions.
|
|
145
|
+
#
|
|
146
|
+
# @example Get the default options.
|
|
147
|
+
# relation.default_options(:continue => true)
|
|
148
|
+
#
|
|
149
|
+
# @param [ Hash, Array ] args The arguments to parse from.
|
|
150
|
+
#
|
|
151
|
+
# @return [ Hash ] The options merged with the actuals.
|
|
152
|
+
def default_options(args = {})
|
|
153
|
+
options = args.is_a?(Hash) ? args : args.extract_options!
|
|
154
|
+
Mongoid.binding_defaults.merge(options)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Find the first object given the supplied attributes or create/initialize it.
|
|
158
|
+
#
|
|
159
|
+
# @example Find or create|initialize.
|
|
160
|
+
# person.addresses.find_or(:create, :street => "Bond")
|
|
161
|
+
#
|
|
162
|
+
# @param [ Symbol ] method The method name, create or new.
|
|
163
|
+
# @param [ Hash ] attrs The attributes to build with.
|
|
164
|
+
#
|
|
165
|
+
# @return [ Document ] A matching document or a new/created one.
|
|
166
|
+
def find_or(method, attrs = {})
|
|
167
|
+
find(:first, :conditions => attrs) || send(method, attrs)
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|