mongoid 2.0.0.beta.5 → 2.0.0.beta.7
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/mongoid.rb +10 -2
- data/lib/mongoid/associations.rb +82 -58
- data/lib/mongoid/associations/embeds_one.rb +6 -6
- data/lib/mongoid/associations/foreign_key.rb +35 -0
- data/lib/mongoid/associations/meta_data.rb +9 -0
- data/lib/mongoid/associations/options.rb +1 -1
- data/lib/mongoid/associations/proxy.rb +9 -0
- data/lib/mongoid/associations/{belongs_to_related.rb → referenced_in.rb} +6 -5
- data/lib/mongoid/associations/{has_many_related.rb → references_many.rb} +69 -26
- data/lib/mongoid/associations/references_many_as_array.rb +78 -0
- data/lib/mongoid/associations/{has_one_related.rb → references_one.rb} +16 -2
- data/lib/mongoid/atomicity.rb +42 -0
- data/lib/mongoid/attributes.rb +148 -146
- data/lib/mongoid/callbacks.rb +5 -1
- data/lib/mongoid/collections.rb +31 -1
- data/lib/mongoid/components.rb +4 -1
- data/lib/mongoid/config.rb +2 -1
- data/lib/mongoid/criteria.rb +9 -0
- data/lib/mongoid/dirty.rb +211 -212
- data/lib/mongoid/document.rb +126 -185
- data/lib/mongoid/extensions.rb +5 -0
- data/lib/mongoid/extensions/array/conversions.rb +3 -5
- data/lib/mongoid/extensions/hash/conversions.rb +19 -22
- data/lib/mongoid/extensions/object/conversions.rb +3 -5
- data/lib/mongoid/extensions/set/conversions.rb +20 -0
- data/lib/mongoid/field.rb +11 -0
- data/lib/mongoid/finders.rb +8 -0
- data/lib/mongoid/hierarchy.rb +76 -0
- data/lib/mongoid/identity.rb +37 -29
- data/lib/mongoid/paths.rb +46 -47
- data/lib/mongoid/persistence.rb +111 -113
- data/lib/mongoid/persistence/insert.rb +1 -1
- data/lib/mongoid/persistence/insert_embedded.rb +10 -5
- data/lib/mongoid/persistence/remove_all.rb +3 -2
- data/lib/mongoid/persistence/update.rb +8 -3
- data/lib/mongoid/railtie.rb +3 -0
- data/lib/mongoid/railties/database.rake +33 -18
- data/lib/mongoid/timestamps.rb +9 -12
- data/lib/mongoid/validations/uniqueness.rb +16 -4
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid/versioning.rb +10 -11
- data/lib/rails/generators/mongoid/config/config_generator.rb +0 -16
- metadata +64 -24
data/lib/mongoid.rb
CHANGED
@@ -21,8 +21,9 @@
|
|
21
21
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
22
|
require "rubygems"
|
23
23
|
|
24
|
-
gem "activemodel", "3.0.0.
|
25
|
-
gem "
|
24
|
+
gem "activemodel", "~>3.0.0.beta"
|
25
|
+
gem "tzinfo", "~>0.3.22"
|
26
|
+
gem "will_paginate", "~>3.0.pre"
|
26
27
|
gem "mongo", "~>1.0.1"
|
27
28
|
gem "bson", "~>1.0.1"
|
28
29
|
|
@@ -48,6 +49,7 @@ require "will_paginate/collection"
|
|
48
49
|
require "mongo"
|
49
50
|
require "mongoid/observable"
|
50
51
|
require "mongoid/associations"
|
52
|
+
require "mongoid/atomicity"
|
51
53
|
require "mongoid/attributes"
|
52
54
|
require "mongoid/callbacks"
|
53
55
|
require "mongoid/collection"
|
@@ -65,6 +67,7 @@ require "mongoid/factory"
|
|
65
67
|
require "mongoid/field"
|
66
68
|
require "mongoid/fields"
|
67
69
|
require "mongoid/finders"
|
70
|
+
require "mongoid/hierarchy"
|
68
71
|
require "mongoid/identity"
|
69
72
|
require "mongoid/indexes"
|
70
73
|
require "mongoid/javascript"
|
@@ -81,6 +84,11 @@ require "mongoid/versioning"
|
|
81
84
|
require "mongoid/components"
|
82
85
|
require "mongoid/document"
|
83
86
|
|
87
|
+
# add railtie
|
88
|
+
if defined?(Rails)
|
89
|
+
require "mongoid/railtie"
|
90
|
+
end
|
91
|
+
|
84
92
|
module Mongoid #:nodoc
|
85
93
|
|
86
94
|
MONGODB_VERSION = "1.4.0"
|
data/lib/mongoid/associations.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require "mongoid/associations/proxy"
|
3
|
-
require "mongoid/associations/belongs_to_related"
|
4
3
|
require "mongoid/associations/embedded_in"
|
5
4
|
require "mongoid/associations/embeds_many"
|
6
5
|
require "mongoid/associations/embeds_one"
|
7
|
-
require "mongoid/associations/
|
8
|
-
require "mongoid/associations/
|
6
|
+
require "mongoid/associations/foreign_key"
|
7
|
+
require "mongoid/associations/references_many"
|
8
|
+
require "mongoid/associations/references_many_as_array"
|
9
|
+
require "mongoid/associations/references_one"
|
10
|
+
require "mongoid/associations/referenced_in"
|
9
11
|
require "mongoid/associations/options"
|
10
12
|
require "mongoid/associations/meta_data"
|
11
13
|
|
@@ -13,6 +15,8 @@ module Mongoid # :nodoc:
|
|
13
15
|
module Associations #:nodoc:
|
14
16
|
extend ActiveSupport::Concern
|
15
17
|
included do
|
18
|
+
include ForeignKey
|
19
|
+
|
16
20
|
cattr_accessor :embedded
|
17
21
|
self.embedded = false
|
18
22
|
|
@@ -22,57 +26,44 @@ module Mongoid # :nodoc:
|
|
22
26
|
delegate :embedded, :embedded?, :to => "self.class"
|
23
27
|
end
|
24
28
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
29
|
+
# Returns the associations for the +Document+.
|
30
|
+
def associations
|
31
|
+
self.class.associations
|
32
|
+
end
|
30
33
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
34
|
+
# are we in an embeds_many?
|
35
|
+
def embedded_many?
|
36
|
+
embedded? && _parent.associations[association_name].association == EmbedsMany
|
37
|
+
end
|
35
38
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
39
|
+
# are we in an embeds_one?
|
40
|
+
def embedded_one?
|
41
|
+
embedded? && !embedded_many?
|
42
|
+
end
|
41
43
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
44
|
+
# Update the one-to-one relational association for the name.
|
45
|
+
def update_association(name)
|
46
|
+
association = send(name)
|
47
|
+
association.save if new_record? && !association.nil?
|
48
|
+
end
|
47
49
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
end
|
50
|
+
# Updates all the one-to-many relational associations for the name.
|
51
|
+
def update_associations(name)
|
52
|
+
send(name).each { |doc| doc.save } if new_record?
|
52
53
|
end
|
53
54
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
# Example:
|
63
|
-
#
|
64
|
-
# class Game
|
65
|
-
# include Mongoid::Document
|
66
|
-
# belongs_to_related :person
|
67
|
-
# end
|
68
|
-
#
|
69
|
-
def belongs_to_related(name, options = {}, &block)
|
70
|
-
opts = optionize(name, options, fk(name, options), &block)
|
71
|
-
associate(Associations::BelongsToRelated, opts)
|
72
|
-
field(opts.foreign_key, :type => Mongoid.use_object_ids ? BSON::ObjectID : String)
|
73
|
-
index(opts.foreign_key) unless embedded?
|
55
|
+
def update_foreign_keys
|
56
|
+
associations.each do |name, association|
|
57
|
+
next unless association.macro == :referenced_in
|
58
|
+
foreign_key = association.options.foreign_key
|
59
|
+
if send(foreign_key).nil?
|
60
|
+
target = send(name)
|
61
|
+
send("#{foreign_key}=", target ? target.id : nil)
|
62
|
+
end
|
74
63
|
end
|
64
|
+
end
|
75
65
|
|
66
|
+
module ClassMethods
|
76
67
|
# Gets whether or not the document is embedded.
|
77
68
|
#
|
78
69
|
# Example:
|
@@ -135,7 +126,6 @@ module Mongoid # :nodoc:
|
|
135
126
|
# end
|
136
127
|
def embeds_many(name, options = {}, &block)
|
137
128
|
associate(Associations::EmbedsMany, optionize(name, options, nil, &block))
|
138
|
-
set_callback(:update, :after) { |document| document.update_embedded(name) } unless name == :versions
|
139
129
|
end
|
140
130
|
|
141
131
|
alias :embed_many :embeds_many
|
@@ -147,7 +137,7 @@ module Mongoid # :nodoc:
|
|
147
137
|
# Options:
|
148
138
|
#
|
149
139
|
# name: A +Symbol+ that is the plural child class name.
|
150
|
-
|
140
|
+
#
|
151
141
|
# Example:
|
152
142
|
#
|
153
143
|
# class Person
|
@@ -165,11 +155,34 @@ module Mongoid # :nodoc:
|
|
165
155
|
associate(type, opts)
|
166
156
|
add_builder(type, opts)
|
167
157
|
add_creator(type, opts)
|
168
|
-
set_callback(:update, :after) { |document| document.update_embedded(name) }
|
169
158
|
end
|
170
159
|
|
171
160
|
alias :embed_one :embeds_one
|
172
161
|
|
162
|
+
# Adds a relational association from the child Document to a Document in
|
163
|
+
# another database or collection.
|
164
|
+
#
|
165
|
+
# Options:
|
166
|
+
#
|
167
|
+
# name: A +Symbol+ that is the related class name.
|
168
|
+
#
|
169
|
+
# Example:
|
170
|
+
#
|
171
|
+
# class Game
|
172
|
+
# include Mongoid::Document
|
173
|
+
# referenced_in :person
|
174
|
+
# end
|
175
|
+
#
|
176
|
+
def referenced_in(name, options = {}, &block)
|
177
|
+
opts = optionize(name, options, constraint(name, options, :in), &block)
|
178
|
+
associate(Associations::ReferencedIn, opts)
|
179
|
+
field(opts.foreign_key, :type => Mongoid.use_object_ids ? BSON::ObjectID : String)
|
180
|
+
index(opts.foreign_key) unless embedded?
|
181
|
+
set_callback(:save, :before) { |document| document.update_foreign_keys }
|
182
|
+
end
|
183
|
+
|
184
|
+
alias :belongs_to_related :referenced_in
|
185
|
+
|
173
186
|
# Adds a relational association from the Document to many Documents in
|
174
187
|
# another database or collection.
|
175
188
|
#
|
@@ -181,16 +194,18 @@ module Mongoid # :nodoc:
|
|
181
194
|
#
|
182
195
|
# class Person
|
183
196
|
# include Mongoid::Document
|
184
|
-
#
|
197
|
+
# references_many :posts
|
185
198
|
# end
|
186
199
|
#
|
187
|
-
def
|
188
|
-
|
200
|
+
def references_many(name, options = {}, &block)
|
201
|
+
reference_many(name, options, &block)
|
189
202
|
set_callback :save, :before do |document|
|
190
203
|
document.update_associations(name)
|
191
204
|
end
|
192
205
|
end
|
193
206
|
|
207
|
+
alias :has_many_related :references_many
|
208
|
+
|
194
209
|
# Adds a relational association from the Document to one Document in
|
195
210
|
# another database or collection.
|
196
211
|
#
|
@@ -202,15 +217,18 @@ module Mongoid # :nodoc:
|
|
202
217
|
#
|
203
218
|
# class Person
|
204
219
|
# include Mongoid::Document
|
205
|
-
#
|
220
|
+
# references_one :game
|
206
221
|
# end
|
207
|
-
def
|
208
|
-
|
222
|
+
def references_one(name, options = {}, &block)
|
223
|
+
opts = optionize(name, options, constraint(name, options, :one), &block)
|
224
|
+
associate(Associations::ReferencesOne, opts)
|
209
225
|
set_callback :save, :before do |document|
|
210
226
|
document.update_association(name)
|
211
227
|
end
|
212
228
|
end
|
213
229
|
|
230
|
+
alias :has_one_related :references_one
|
231
|
+
|
214
232
|
# Returns the macro associated with the supplied association name. This
|
215
233
|
# will return embeds_on, embeds_many, embedded_in or nil.
|
216
234
|
#
|
@@ -273,9 +291,15 @@ module Mongoid # :nodoc:
|
|
273
291
|
)
|
274
292
|
end
|
275
293
|
|
276
|
-
|
277
|
-
|
278
|
-
|
294
|
+
def reference_many(name, options, &block)
|
295
|
+
if (options[:stored_as] == :array)
|
296
|
+
opts = optionize(name, options, constraint(name, options, :many_as_array), &block)
|
297
|
+
field "#{name.to_s.singularize}_ids", :type => Array, :default => []
|
298
|
+
associate(Associations::ReferencesManyAsArray, opts)
|
299
|
+
else
|
300
|
+
opts = optionize(name, options, constraint(name, options, :many), &block)
|
301
|
+
associate(Associations::ReferencesMany, opts)
|
302
|
+
end
|
279
303
|
end
|
280
304
|
end
|
281
305
|
end
|
@@ -26,9 +26,9 @@ module Mongoid #:nodoc:
|
|
26
26
|
# Returns:
|
27
27
|
#
|
28
28
|
# A new +HashOne+ association proxy.
|
29
|
-
def initialize(document, attrs, options)
|
29
|
+
def initialize(document, attrs, options, target = nil)
|
30
30
|
@parent, @options = document, options
|
31
|
-
@target = attrs.assimilate(@parent, @options, attrs.klass)
|
31
|
+
@target = target ? target : attrs.assimilate(@parent, @options, attrs.klass)
|
32
32
|
extends(options)
|
33
33
|
end
|
34
34
|
|
@@ -58,10 +58,10 @@ module Mongoid #:nodoc:
|
|
58
58
|
# Returns:
|
59
59
|
#
|
60
60
|
# A new +EmbedsOne+ association proxy.
|
61
|
-
def instantiate(document, options)
|
61
|
+
def instantiate(document, options, target = nil)
|
62
62
|
attributes = document.raw_attributes[options.name]
|
63
|
-
return nil if attributes.blank?
|
64
|
-
new(document, attributes, options)
|
63
|
+
return nil if attributes.blank? && target.nil?
|
64
|
+
new(document, attributes, options, target)
|
65
65
|
end
|
66
66
|
|
67
67
|
# Returns the macro used to create the association.
|
@@ -87,7 +87,7 @@ module Mongoid #:nodoc:
|
|
87
87
|
# A new +EmbedsOne+ association proxy.
|
88
88
|
def update(child, parent, options)
|
89
89
|
child.assimilate(parent, options)
|
90
|
-
instantiate(parent, options)
|
90
|
+
instantiate(parent, options, child.is_a?(Hash) ? nil : child)
|
91
91
|
end
|
92
92
|
end
|
93
93
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc:
|
3
|
+
module Associations #:nodoc:
|
4
|
+
module ForeignKey #:nodoc:
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
module ClassMethods #:nodoc:
|
8
|
+
# Determine the value for the foreign key constriant field in the
|
9
|
+
# database, based on the type of association or if the actual value was
|
10
|
+
# supplied as an option.
|
11
|
+
#
|
12
|
+
# Example:
|
13
|
+
#
|
14
|
+
# <tt>contraint(:posts, {}, :references_one)</tt>
|
15
|
+
#
|
16
|
+
# Returns
|
17
|
+
#
|
18
|
+
# A +String+ for the foreign key field.
|
19
|
+
def constraint(name, options, association)
|
20
|
+
key = options[:foreign_key]
|
21
|
+
|
22
|
+
# Always return the supplied foreign_key option if it was supplied -
|
23
|
+
# the user should always be ble to override.
|
24
|
+
return key.to_s if key
|
25
|
+
|
26
|
+
case association
|
27
|
+
when :one, :many then self.name.foreign_key
|
28
|
+
when :many_as_array then "#{name.to_s.singularize}_ids"
|
29
|
+
else name.to_s.foreign_key
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -13,6 +13,15 @@ module Mongoid #:nodoc:
|
|
13
13
|
define_method(name) { |*args| @options.send(name) }
|
14
14
|
end
|
15
15
|
|
16
|
+
# Return true if this meta data is for an embedded association.
|
17
|
+
#
|
18
|
+
# Example:
|
19
|
+
#
|
20
|
+
# <tt>metadata.embedded?</tt>
|
21
|
+
def embedded?
|
22
|
+
[ EmbedsOne, EmbedsMany ].include?(association)
|
23
|
+
end
|
24
|
+
|
16
25
|
# Create the new associations MetaData object, which holds the type of
|
17
26
|
# the association and its options, with convenience methods for getting
|
18
27
|
# that information.
|
@@ -19,6 +19,15 @@ module Mongoid #:nodoc
|
|
19
19
|
def extends(options)
|
20
20
|
extend Module.new(&options.extension) if options.extension?
|
21
21
|
end
|
22
|
+
|
23
|
+
# Sets up the parent, klass, foreign_key, options
|
24
|
+
def setup(document, options)
|
25
|
+
@parent = document
|
26
|
+
@klass = options.klass
|
27
|
+
@options = options
|
28
|
+
@foreign_key = options.foreign_key
|
29
|
+
extends(options)
|
30
|
+
end
|
22
31
|
end
|
23
32
|
end
|
24
33
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
module Mongoid #:nodoc:
|
3
3
|
module Associations #:nodoc:
|
4
4
|
# Represents a relational association to a "parent" object.
|
5
|
-
class
|
5
|
+
class ReferencedIn < Proxy
|
6
6
|
|
7
7
|
# Initializing a related association only requires looking up the object
|
8
8
|
# by its id.
|
@@ -18,7 +18,7 @@ module Mongoid #:nodoc:
|
|
18
18
|
end
|
19
19
|
|
20
20
|
class << self
|
21
|
-
# Instantiate a new +
|
21
|
+
# Instantiate a new +ReferencedIn+ or return nil if the foreign key is
|
22
22
|
# nil. It is preferrable to use this method over the traditional call
|
23
23
|
# to new.
|
24
24
|
#
|
@@ -28,12 +28,13 @@ module Mongoid #:nodoc:
|
|
28
28
|
# options: The association +Options+.
|
29
29
|
def instantiate(document, options, target = nil)
|
30
30
|
foreign_key = document.send(options.foreign_key)
|
31
|
-
|
31
|
+
return nil if foreign_key.blank? && target.nil?
|
32
|
+
new(document, foreign_key, options, target)
|
32
33
|
end
|
33
34
|
|
34
35
|
# Returns the macro used to create the association.
|
35
36
|
def macro
|
36
|
-
:
|
37
|
+
:referenced_in
|
37
38
|
end
|
38
39
|
|
39
40
|
# Perform an update of the relationship of the parent and child. This
|
@@ -47,7 +48,7 @@ module Mongoid #:nodoc:
|
|
47
48
|
#
|
48
49
|
# Example:
|
49
50
|
#
|
50
|
-
# <tt>
|
51
|
+
# <tt>ReferencedIn.update(person, game, options)</tt>
|
51
52
|
def update(target, document, options)
|
52
53
|
document.send("#{options.foreign_key}=", target ? target.id : nil)
|
53
54
|
instantiate(document, options, target)
|
@@ -3,7 +3,7 @@ module Mongoid #:nodoc:
|
|
3
3
|
module Associations #:nodoc:
|
4
4
|
# Represents an relational one-to-many association with an object in a
|
5
5
|
# separate collection or database.
|
6
|
-
class
|
6
|
+
class ReferencesMany < Proxy
|
7
7
|
|
8
8
|
# Appends the object to the +Array+, setting its parent in
|
9
9
|
# the process.
|
@@ -16,24 +16,22 @@ module Mongoid #:nodoc:
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
+
alias :concat :<<
|
20
|
+
alias :push :<<
|
21
|
+
|
19
22
|
# Builds a new Document and adds it to the association collection. The
|
20
23
|
# document created will be of the same class as the others in the
|
21
24
|
# association, and the attributes will be passed into the constructor.
|
22
25
|
#
|
23
26
|
# Returns the newly created object.
|
24
|
-
def build(attributes =
|
27
|
+
def build(attributes = nil)
|
25
28
|
load_target
|
26
29
|
name = @parent.class.to_s.underscore
|
27
|
-
object = @klass.instantiate(attributes.merge(name => @parent))
|
30
|
+
object = @klass.instantiate((attributes || {}).merge(name => @parent))
|
28
31
|
@target << object
|
29
32
|
object
|
30
33
|
end
|
31
34
|
|
32
|
-
# Delegates to <<
|
33
|
-
def concat(*objects)
|
34
|
-
self << objects
|
35
|
-
end
|
36
|
-
|
37
35
|
# Creates a new Document and adds it to the association collection. The
|
38
36
|
# document created will be of the same class as the others in the
|
39
37
|
# association, and the attributes will be passed into the constructor and
|
@@ -80,9 +78,10 @@ module Mongoid #:nodoc:
|
|
80
78
|
|
81
79
|
# Finds a document in this association.
|
82
80
|
# If an id is passed, will return the document for that id.
|
83
|
-
def find(
|
84
|
-
|
85
|
-
@
|
81
|
+
def find(id_or_type, options = {})
|
82
|
+
return self.id_criteria(id_or_type) unless id_or_type.is_a?(Symbol)
|
83
|
+
options[:conditions] = (options[:conditions] || {}).merge(@foreign_key.to_sym => @parent.id)
|
84
|
+
@klass.find(id_or_type, options)
|
86
85
|
end
|
87
86
|
|
88
87
|
# Initializing a related association only requires looking up the objects
|
@@ -93,11 +92,8 @@ module Mongoid #:nodoc:
|
|
93
92
|
# document: The +Document+ that contains the relationship.
|
94
93
|
# options: The association +Options+.
|
95
94
|
def initialize(document, options, target = nil)
|
96
|
-
|
97
|
-
@
|
98
|
-
@base = lambda { @klass.all(:conditions => { @foreign_key => document.id }) }
|
99
|
-
@target = target || @base.call
|
100
|
-
extends(options)
|
95
|
+
setup(document, options)
|
96
|
+
@target = target || query.call
|
101
97
|
end
|
102
98
|
|
103
99
|
# Override the default behavior to allow the criteria to get reset on
|
@@ -112,21 +108,60 @@ module Mongoid #:nodoc:
|
|
112
108
|
#
|
113
109
|
# A Criteria object or Array.
|
114
110
|
def method_missing(name, *args, &block)
|
115
|
-
@target =
|
111
|
+
@target = query.call unless @target.is_a?(Array)
|
116
112
|
@target.send(name, *args, &block)
|
117
113
|
end
|
118
114
|
|
119
|
-
#
|
120
|
-
|
121
|
-
|
115
|
+
# Used for setting associations via a nested attributes setter from the
|
116
|
+
# parent +Document+.
|
117
|
+
#
|
118
|
+
# Options:
|
119
|
+
#
|
120
|
+
# attributes: A +Hash+ of integer keys and +Hash+ values.
|
121
|
+
#
|
122
|
+
# Returns:
|
123
|
+
#
|
124
|
+
# The newly build target Document.
|
125
|
+
def nested_build(attributes, options = {})
|
126
|
+
attributes.each do |index, attrs|
|
127
|
+
begin
|
128
|
+
document = find(index.to_i)
|
129
|
+
if options && options[:allow_destroy] && attrs['_destroy']
|
130
|
+
@target.delete(document)
|
131
|
+
document.destroy
|
132
|
+
else
|
133
|
+
document.write_attributes(attrs)
|
134
|
+
end
|
135
|
+
rescue Errors::DocumentNotFound
|
136
|
+
build(attrs)
|
137
|
+
end
|
138
|
+
end
|
122
139
|
end
|
123
140
|
|
124
141
|
protected
|
125
|
-
# Load the target entries if the document is new.
|
142
|
+
# Load the target entries if the parent document is new.
|
126
143
|
def load_target
|
127
144
|
@target = @target.entries if @parent.new_record?
|
128
145
|
end
|
129
146
|
|
147
|
+
# The default query used for retrieving the documents from the database.
|
148
|
+
# In this case we use the common API between Mongoid, ActiveRecord, and
|
149
|
+
# DataMapper so we can do one-to-many relationships with data in other
|
150
|
+
# databases.
|
151
|
+
#
|
152
|
+
# Example:
|
153
|
+
#
|
154
|
+
# <tt>association.query</tt>
|
155
|
+
#
|
156
|
+
# Returns:
|
157
|
+
#
|
158
|
+
# A +Criteria+ if a Mongoid association.
|
159
|
+
# An +Array+ of objects if an ActiveRecord association
|
160
|
+
# A +Collection+ if a DataMapper association.
|
161
|
+
def query
|
162
|
+
@query ||= lambda { @klass.all(:conditions => { @foreign_key => @parent.id }) }
|
163
|
+
end
|
164
|
+
|
130
165
|
# Remove the objects based on conditions.
|
131
166
|
def remove(method, conditions)
|
132
167
|
selector = { @foreign_key => @parent.id }.merge(conditions || {})
|
@@ -134,13 +169,22 @@ module Mongoid #:nodoc:
|
|
134
169
|
reset; removed
|
135
170
|
end
|
136
171
|
|
137
|
-
# Reset the memoized association on the parent.
|
172
|
+
# Reset the memoized association on the parent. This will execute the
|
173
|
+
# database query again.
|
174
|
+
#
|
175
|
+
# Example:
|
176
|
+
#
|
177
|
+
# <tt>association.reset</tt>
|
178
|
+
#
|
179
|
+
# Returns:
|
180
|
+
#
|
181
|
+
# See #query rdoc for return values.
|
138
182
|
def reset
|
139
|
-
@parent.send(:reset, @options.name) {
|
183
|
+
@parent.send(:reset, @options.name) { query.call }
|
140
184
|
end
|
141
185
|
|
142
186
|
class << self
|
143
|
-
# Preferred method for creating the new +
|
187
|
+
# Preferred method for creating the new +ReferencesMany+ association.
|
144
188
|
#
|
145
189
|
# Options:
|
146
190
|
#
|
@@ -152,7 +196,7 @@ module Mongoid #:nodoc:
|
|
152
196
|
|
153
197
|
# Returns the macro used to create the association.
|
154
198
|
def macro
|
155
|
-
:
|
199
|
+
:references_many
|
156
200
|
end
|
157
201
|
|
158
202
|
# Perform an update of the relationship of the parent and child. This
|
@@ -173,7 +217,6 @@ module Mongoid #:nodoc:
|
|
173
217
|
instantiate(document, options, target)
|
174
218
|
end
|
175
219
|
end
|
176
|
-
|
177
220
|
end
|
178
221
|
end
|
179
222
|
end
|