mongoid 1.2.14 → 1.9.0
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/lib/mongoid.rb +10 -3
- data/lib/mongoid/associations.rb +133 -97
- data/lib/mongoid/associations/belongs_to_related.rb +2 -3
- data/lib/mongoid/associations/{belongs_to.rb → embedded_in.rb} +14 -6
- data/lib/mongoid/associations/{has_many.rb → embeds_many.rb} +89 -31
- data/lib/mongoid/associations/{has_one.rb → embeds_one.rb} +8 -7
- data/lib/mongoid/associations/has_many_related.rb +52 -7
- data/lib/mongoid/associations/has_one_related.rb +8 -4
- data/lib/mongoid/associations/meta_data.rb +2 -1
- data/lib/mongoid/associations/options.rb +6 -1
- data/lib/mongoid/associations/proxy.rb +14 -21
- data/lib/mongoid/attributes.rb +27 -12
- data/lib/mongoid/collection.rb +4 -3
- data/lib/mongoid/collections.rb +41 -0
- data/lib/mongoid/collections/master.rb +3 -2
- data/lib/mongoid/collections/slaves.rb +3 -2
- data/lib/mongoid/components.rb +21 -19
- data/lib/mongoid/concern.rb +31 -0
- data/lib/mongoid/config.rb +117 -12
- data/lib/mongoid/contexts.rb +1 -1
- data/lib/mongoid/contexts/enumerable.rb +1 -1
- data/lib/mongoid/contexts/mongo.rb +1 -1
- data/lib/mongoid/contexts/paging.rb +10 -2
- data/lib/mongoid/criterion/inclusion.rb +17 -0
- data/lib/mongoid/criterion/optional.rb +1 -1
- data/lib/mongoid/dirty.rb +253 -0
- data/lib/mongoid/document.rb +81 -52
- data/lib/mongoid/errors.rb +32 -1
- data/lib/mongoid/extensions.rb +11 -9
- data/lib/mongoid/extensions/big_decimal/conversions.rb +2 -2
- data/lib/mongoid/extensions/boolean/conversions.rb +8 -2
- data/lib/mongoid/extensions/date/conversions.rb +13 -4
- data/lib/mongoid/extensions/datetime/conversions.rb +1 -6
- data/lib/mongoid/extensions/float/conversions.rb +5 -1
- data/lib/mongoid/extensions/hash/assimilation.rb +12 -3
- data/lib/mongoid/extensions/hash/conversions.rb +34 -4
- data/lib/mongoid/extensions/integer/conversions.rb +5 -1
- data/lib/mongoid/extensions/nil/assimilation.rb +4 -0
- data/lib/mongoid/extensions/object/conversions.rb +1 -1
- data/lib/mongoid/extensions/string/conversions.rb +1 -1
- data/lib/mongoid/extensions/symbol/inflections.rb +1 -1
- data/lib/mongoid/extensions/time_conversions.rb +35 -0
- data/lib/mongoid/extras.rb +6 -9
- data/lib/mongoid/factory.rb +2 -1
- data/lib/mongoid/field.rb +9 -2
- data/lib/mongoid/fields.rb +1 -0
- data/lib/mongoid/identity.rb +3 -3
- data/lib/mongoid/indexes.rb +3 -3
- data/lib/mongoid/memoization.rb +8 -2
- data/lib/mongoid/named_scope.rb +0 -3
- data/lib/mongoid/observable.rb +30 -0
- data/lib/mongoid/paths.rb +62 -0
- data/lib/mongoid/persistence.rb +222 -0
- data/lib/mongoid/persistence/command.rb +39 -0
- data/lib/mongoid/persistence/insert.rb +50 -0
- data/lib/mongoid/persistence/insert_embedded.rb +38 -0
- data/lib/mongoid/persistence/remove.rb +39 -0
- data/lib/mongoid/persistence/remove_all.rb +37 -0
- data/lib/mongoid/persistence/remove_embedded.rb +50 -0
- data/lib/mongoid/persistence/update.rb +63 -0
- data/lib/mongoid/state.rb +28 -21
- data/lib/mongoid/timestamps.rb +5 -8
- data/lib/mongoid/version.rb +4 -0
- data/lib/mongoid/versioning.rb +6 -7
- metadata +81 -300
- data/.gitignore +0 -6
- data/.watchr +0 -29
- data/Rakefile +0 -53
- data/VERSION +0 -1
- data/caliper.yml +0 -4
- data/lib/mongoid/collections/mimic.rb +0 -46
- data/lib/mongoid/commands.rb +0 -174
- data/lib/mongoid/commands/create.rb +0 -21
- data/lib/mongoid/commands/delete.rb +0 -16
- data/lib/mongoid/commands/delete_all.rb +0 -23
- data/lib/mongoid/commands/deletion.rb +0 -18
- data/lib/mongoid/commands/destroy.rb +0 -19
- data/lib/mongoid/commands/destroy_all.rb +0 -23
- data/lib/mongoid/commands/save.rb +0 -27
- data/lib/mongoid/extensions/time/conversions.rb +0 -18
- data/mongoid.gemspec +0 -395
- data/perf/benchmark.rb +0 -77
- data/spec/integration/mongoid/associations_spec.rb +0 -340
- data/spec/integration/mongoid/attributes_spec.rb +0 -22
- data/spec/integration/mongoid/commands_spec.rb +0 -218
- data/spec/integration/mongoid/contexts/enumerable_spec.rb +0 -33
- data/spec/integration/mongoid/criteria_spec.rb +0 -272
- data/spec/integration/mongoid/document_spec.rb +0 -593
- data/spec/integration/mongoid/extensions_spec.rb +0 -26
- data/spec/integration/mongoid/finders_spec.rb +0 -119
- data/spec/integration/mongoid/inheritance_spec.rb +0 -137
- data/spec/integration/mongoid/named_scope_spec.rb +0 -46
- data/spec/models/address.rb +0 -39
- data/spec/models/animal.rb +0 -6
- data/spec/models/callbacks.rb +0 -18
- data/spec/models/comment.rb +0 -8
- data/spec/models/country_code.rb +0 -6
- data/spec/models/employer.rb +0 -5
- data/spec/models/game.rb +0 -7
- data/spec/models/inheritance.rb +0 -56
- data/spec/models/location.rb +0 -5
- data/spec/models/mixed_drink.rb +0 -4
- data/spec/models/name.rb +0 -13
- data/spec/models/namespacing.rb +0 -11
- data/spec/models/patient.rb +0 -4
- data/spec/models/person.rb +0 -99
- data/spec/models/pet.rb +0 -7
- data/spec/models/pet_owner.rb +0 -6
- data/spec/models/phone.rb +0 -7
- data/spec/models/post.rb +0 -15
- data/spec/models/translation.rb +0 -5
- data/spec/models/vet_visit.rb +0 -5
- data/spec/spec.opts +0 -3
- data/spec/spec_helper.rb +0 -31
- data/spec/unit/mongoid/associations/belongs_to_related_spec.rb +0 -145
- data/spec/unit/mongoid/associations/belongs_to_spec.rb +0 -193
- data/spec/unit/mongoid/associations/has_many_related_spec.rb +0 -420
- data/spec/unit/mongoid/associations/has_many_spec.rb +0 -519
- data/spec/unit/mongoid/associations/has_one_related_spec.rb +0 -179
- data/spec/unit/mongoid/associations/has_one_spec.rb +0 -282
- data/spec/unit/mongoid/associations/meta_data_spec.rb +0 -88
- data/spec/unit/mongoid/associations/options_spec.rb +0 -192
- data/spec/unit/mongoid/associations_spec.rb +0 -595
- data/spec/unit/mongoid/attributes_spec.rb +0 -507
- data/spec/unit/mongoid/callbacks_spec.rb +0 -55
- data/spec/unit/mongoid/collection_spec.rb +0 -187
- data/spec/unit/mongoid/collections/cyclic_iterator_spec.rb +0 -75
- data/spec/unit/mongoid/collections/master_spec.rb +0 -41
- data/spec/unit/mongoid/collections/mimic_spec.rb +0 -43
- data/spec/unit/mongoid/collections/slaves_spec.rb +0 -81
- data/spec/unit/mongoid/commands/create_spec.rb +0 -30
- data/spec/unit/mongoid/commands/delete_all_spec.rb +0 -58
- data/spec/unit/mongoid/commands/delete_spec.rb +0 -38
- data/spec/unit/mongoid/commands/destroy_all_spec.rb +0 -23
- data/spec/unit/mongoid/commands/destroy_spec.rb +0 -50
- data/spec/unit/mongoid/commands/save_spec.rb +0 -105
- data/spec/unit/mongoid/commands_spec.rb +0 -275
- data/spec/unit/mongoid/config_spec.rb +0 -172
- data/spec/unit/mongoid/contexts/enumerable_spec.rb +0 -421
- data/spec/unit/mongoid/contexts/mongo_spec.rb +0 -682
- data/spec/unit/mongoid/contexts_spec.rb +0 -25
- data/spec/unit/mongoid/criteria_spec.rb +0 -824
- data/spec/unit/mongoid/criterion/complex_spec.rb +0 -19
- data/spec/unit/mongoid/criterion/exclusion_spec.rb +0 -91
- data/spec/unit/mongoid/criterion/inclusion_spec.rb +0 -219
- data/spec/unit/mongoid/criterion/optional_spec.rb +0 -319
- data/spec/unit/mongoid/cursor_spec.rb +0 -74
- data/spec/unit/mongoid/deprecation_spec.rb +0 -24
- data/spec/unit/mongoid/document_spec.rb +0 -952
- data/spec/unit/mongoid/errors_spec.rb +0 -103
- data/spec/unit/mongoid/extensions/array/accessors_spec.rb +0 -50
- data/spec/unit/mongoid/extensions/array/assimilation_spec.rb +0 -24
- data/spec/unit/mongoid/extensions/array/conversions_spec.rb +0 -35
- data/spec/unit/mongoid/extensions/array/parentization_spec.rb +0 -20
- data/spec/unit/mongoid/extensions/big_decimal/conversions_spec.rb +0 -22
- data/spec/unit/mongoid/extensions/binary/conversions_spec.rb +0 -22
- data/spec/unit/mongoid/extensions/boolean/conversions_spec.rb +0 -49
- data/spec/unit/mongoid/extensions/date/conversions_spec.rb +0 -102
- data/spec/unit/mongoid/extensions/datetime/conversions_spec.rb +0 -70
- data/spec/unit/mongoid/extensions/float/conversions_spec.rb +0 -61
- data/spec/unit/mongoid/extensions/hash/accessors_spec.rb +0 -184
- data/spec/unit/mongoid/extensions/hash/assimilation_spec.rb +0 -46
- data/spec/unit/mongoid/extensions/hash/conversions_spec.rb +0 -21
- data/spec/unit/mongoid/extensions/hash/criteria_helpers_spec.rb +0 -17
- data/spec/unit/mongoid/extensions/hash/scoping_spec.rb +0 -14
- data/spec/unit/mongoid/extensions/integer/conversions_spec.rb +0 -61
- data/spec/unit/mongoid/extensions/nil/assimilation_spec.rb +0 -24
- data/spec/unit/mongoid/extensions/object/conversions_spec.rb +0 -57
- data/spec/unit/mongoid/extensions/proc/scoping_spec.rb +0 -34
- data/spec/unit/mongoid/extensions/string/conversions_spec.rb +0 -17
- data/spec/unit/mongoid/extensions/string/inflections_spec.rb +0 -208
- data/spec/unit/mongoid/extensions/symbol/inflections_spec.rb +0 -91
- data/spec/unit/mongoid/extensions/time/conversions_spec.rb +0 -70
- data/spec/unit/mongoid/extras_spec.rb +0 -102
- data/spec/unit/mongoid/factory_spec.rb +0 -31
- data/spec/unit/mongoid/field_spec.rb +0 -143
- data/spec/unit/mongoid/fields_spec.rb +0 -181
- data/spec/unit/mongoid/finders_spec.rb +0 -404
- data/spec/unit/mongoid/identity_spec.rb +0 -109
- data/spec/unit/mongoid/indexes_spec.rb +0 -93
- data/spec/unit/mongoid/javascript_spec.rb +0 -48
- data/spec/unit/mongoid/matchers/all_spec.rb +0 -27
- data/spec/unit/mongoid/matchers/default_spec.rb +0 -27
- data/spec/unit/mongoid/matchers/exists_spec.rb +0 -56
- data/spec/unit/mongoid/matchers/gt_spec.rb +0 -39
- data/spec/unit/mongoid/matchers/gte_spec.rb +0 -49
- data/spec/unit/mongoid/matchers/in_spec.rb +0 -27
- data/spec/unit/mongoid/matchers/lt_spec.rb +0 -39
- data/spec/unit/mongoid/matchers/lte_spec.rb +0 -49
- data/spec/unit/mongoid/matchers/ne_spec.rb +0 -27
- data/spec/unit/mongoid/matchers/nin_spec.rb +0 -27
- data/spec/unit/mongoid/matchers/size_spec.rb +0 -27
- data/spec/unit/mongoid/matchers_spec.rb +0 -329
- data/spec/unit/mongoid/memoization_spec.rb +0 -75
- data/spec/unit/mongoid/named_scope_spec.rb +0 -123
- data/spec/unit/mongoid/scope_spec.rb +0 -240
- data/spec/unit/mongoid/state_spec.rb +0 -83
- data/spec/unit/mongoid/timestamps_spec.rb +0 -25
- data/spec/unit/mongoid/versioning_spec.rb +0 -41
- data/spec/unit/mongoid_spec.rb +0 -46
@@ -1,8 +1,9 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Mongoid #:nodoc:
|
3
3
|
module Associations #:nodoc:
|
4
|
-
|
5
|
-
|
4
|
+
# Represents embedding many documents within a parent document, which will
|
5
|
+
# be an array as the underlying storage mechanism.
|
6
|
+
class EmbedsMany < Proxy
|
6
7
|
|
7
8
|
attr_accessor :association_name, :klass
|
8
9
|
|
@@ -12,6 +13,7 @@ module Mongoid #:nodoc:
|
|
12
13
|
documents.flatten.each do |doc|
|
13
14
|
doc.parentize(@parent, @association_name)
|
14
15
|
@target << doc
|
16
|
+
doc._index = @target.size - 1
|
15
17
|
doc.notify
|
16
18
|
end
|
17
19
|
end
|
@@ -19,16 +21,6 @@ module Mongoid #:nodoc:
|
|
19
21
|
alias :concat :<<
|
20
22
|
alias :push :<<
|
21
23
|
|
22
|
-
# Clears the association, and notifies the parents of the removal.
|
23
|
-
def clear
|
24
|
-
unless @target.empty?
|
25
|
-
document = @target.first
|
26
|
-
document.changed(true)
|
27
|
-
document.notify_observers(document, true)
|
28
|
-
@target.clear
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
24
|
# Builds a new Document and adds it to the association collection. The
|
33
25
|
# document created will be of the same class as the others in the
|
34
26
|
# association, and the attributes will be passed into the constructor.
|
@@ -41,9 +33,19 @@ module Mongoid #:nodoc:
|
|
41
33
|
document.parentize(@parent, @association_name)
|
42
34
|
document.write_attributes(attrs)
|
43
35
|
@target << document
|
36
|
+
document._index = @target.size - 1
|
44
37
|
document
|
45
38
|
end
|
46
39
|
|
40
|
+
# Clears the association, and notifies the parents of the removal.
|
41
|
+
def clear
|
42
|
+
unless @target.empty?
|
43
|
+
document = @target.first
|
44
|
+
document.notify_observers(document, true)
|
45
|
+
@target.clear
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
47
49
|
# Creates a new Document and adds it to the association collection. The
|
48
50
|
# document created will be of the same class as the others in the
|
49
51
|
# association, and the attributes will be passed into the constructor and
|
@@ -54,9 +56,7 @@ module Mongoid #:nodoc:
|
|
54
56
|
# The newly created Document.
|
55
57
|
def create(attrs = {}, type = nil)
|
56
58
|
document = build(attrs, type)
|
57
|
-
document.
|
58
|
-
document.run_callbacks(:after_create) if document.save
|
59
|
-
document
|
59
|
+
document.save; document
|
60
60
|
end
|
61
61
|
|
62
62
|
# Creates a new Document and adds it to the association collection. The
|
@@ -75,6 +75,32 @@ module Mongoid #:nodoc:
|
|
75
75
|
document
|
76
76
|
end
|
77
77
|
|
78
|
+
# Delete all the documents in the association without running callbacks.
|
79
|
+
#
|
80
|
+
# Example:
|
81
|
+
#
|
82
|
+
# <tt>addresses.delete_all</tt>
|
83
|
+
#
|
84
|
+
# Returns:
|
85
|
+
#
|
86
|
+
# The number of documents deleted.
|
87
|
+
def delete_all(conditions = {})
|
88
|
+
remove(:delete, conditions)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Delete all the documents in the association and run destroy callbacks.
|
92
|
+
#
|
93
|
+
# Example:
|
94
|
+
#
|
95
|
+
# <tt>addresses.destroy_all</tt>
|
96
|
+
#
|
97
|
+
# Returns:
|
98
|
+
#
|
99
|
+
# The number of documents destroyed.
|
100
|
+
def destroy_all(conditions = {})
|
101
|
+
remove(:destroy, conditions)
|
102
|
+
end
|
103
|
+
|
78
104
|
# Finds a document in this association.
|
79
105
|
#
|
80
106
|
# If :all is passed, returns all the documents
|
@@ -101,13 +127,19 @@ module Mongoid #:nodoc:
|
|
101
127
|
#
|
102
128
|
# parent: The parent document to the association.
|
103
129
|
# options: The association options.
|
104
|
-
def initialize(parent, options)
|
130
|
+
def initialize(parent, options, target_array = nil)
|
105
131
|
@parent, @association_name = parent, options.name
|
106
132
|
@klass, @options = options.klass, options
|
107
|
-
|
133
|
+
if target_array
|
134
|
+
build_children_from_target_array(target_array)
|
135
|
+
else
|
136
|
+
build_children_from_attributes(parent.raw_attributes[@association_name])
|
137
|
+
end
|
108
138
|
extends(options)
|
109
139
|
end
|
110
140
|
|
141
|
+
|
142
|
+
|
111
143
|
# If the target array does not respond to the supplied method then try to
|
112
144
|
# find a named scope or criteria on the class and send the call there.
|
113
145
|
#
|
@@ -150,45 +182,71 @@ module Mongoid #:nodoc:
|
|
150
182
|
def paginate(options)
|
151
183
|
criteria = Mongoid::Criteria.translate(@klass, options)
|
152
184
|
criteria.documents = @target
|
153
|
-
criteria.paginate
|
185
|
+
criteria.paginate(options)
|
154
186
|
end
|
155
187
|
|
156
188
|
protected
|
157
189
|
# Initializes each of the attributes in the hash.
|
158
|
-
def
|
159
|
-
@target =
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
190
|
+
def build_children_from_attributes(attributes)
|
191
|
+
@target = []
|
192
|
+
if attributes
|
193
|
+
attributes.each_with_index do |attrs, index|
|
194
|
+
klass = attrs.klass
|
195
|
+
child = klass ? klass.instantiate(attrs) : @klass.instantiate(attrs)
|
196
|
+
child.parentize(@parent, @association_name)
|
197
|
+
child._index = index
|
198
|
+
@target << child
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
# Initializes the target array from an existing array of documents.
|
204
|
+
def build_children_from_target_array(target_array)
|
205
|
+
@target = target_array
|
206
|
+
@target.each_with_index do |child, index|
|
207
|
+
child._index = index
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
# Removes documents based on a method.
|
212
|
+
def remove(method, conditions)
|
213
|
+
criteria = @klass.find(conditions || {})
|
214
|
+
criteria.documents = @target
|
215
|
+
count = criteria.size
|
216
|
+
criteria.each do |doc|
|
217
|
+
@target.delete(doc); doc.send(method)
|
218
|
+
end; count
|
165
219
|
end
|
166
220
|
|
167
221
|
class << self
|
168
222
|
|
169
|
-
# Preferred method of creating a new +
|
223
|
+
# Preferred method of creating a new +EmbedsMany+ association. It will
|
170
224
|
# delegate to new.
|
171
225
|
#
|
172
226
|
# Options:
|
173
227
|
#
|
174
228
|
# document: The parent +Document+
|
175
229
|
# options: The association options
|
176
|
-
def instantiate(document, options)
|
177
|
-
new(document, options)
|
230
|
+
def instantiate(document, options, target_array = nil)
|
231
|
+
new(document, options, target_array)
|
178
232
|
end
|
179
233
|
|
180
234
|
# Returns the macro used to create the association.
|
181
235
|
def macro
|
182
|
-
:
|
236
|
+
:embeds_many
|
183
237
|
end
|
184
238
|
|
185
239
|
# Perform an update of the relationship of the parent and child. This
|
186
240
|
# is initialized by setting the has_many to the supplied +Enumerable+
|
187
241
|
# and setting up the parentization.
|
188
242
|
def update(children, parent, options)
|
189
|
-
parent.
|
243
|
+
parent.raw_attributes.delete(options.name)
|
190
244
|
children.assimilate(parent, options)
|
191
|
-
|
245
|
+
if children && children.first.is_a?(Mongoid::Document)
|
246
|
+
instantiate(parent, options, children)
|
247
|
+
else
|
248
|
+
instantiate(parent, options)
|
249
|
+
end
|
192
250
|
end
|
193
251
|
end
|
194
252
|
end
|
@@ -1,8 +1,9 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Mongoid #:nodoc:
|
3
3
|
module Associations #:nodoc:
|
4
|
-
|
5
|
-
|
4
|
+
# Represents an association that is embedded in a parent document as a
|
5
|
+
# one-to-one relationship.
|
6
|
+
class EmbedsOne < Proxy
|
6
7
|
|
7
8
|
# Build a new object for the association.
|
8
9
|
def build(attrs = {}, type = nil)
|
@@ -46,7 +47,7 @@ module Mongoid #:nodoc:
|
|
46
47
|
end
|
47
48
|
|
48
49
|
class << self
|
49
|
-
# Preferred method of instantiating a new +
|
50
|
+
# Preferred method of instantiating a new +EmbedsOne+, since nil values
|
50
51
|
# will be handled properly.
|
51
52
|
#
|
52
53
|
# Options:
|
@@ -56,7 +57,7 @@ module Mongoid #:nodoc:
|
|
56
57
|
#
|
57
58
|
# Returns:
|
58
59
|
#
|
59
|
-
# A new +
|
60
|
+
# A new +EmbedsOne+ association proxy.
|
60
61
|
def instantiate(document, options)
|
61
62
|
attributes = document.raw_attributes[options.name]
|
62
63
|
return nil if attributes.blank?
|
@@ -65,7 +66,7 @@ module Mongoid #:nodoc:
|
|
65
66
|
|
66
67
|
# Returns the macro used to create the association.
|
67
68
|
def macro
|
68
|
-
:
|
69
|
+
:embeds_one
|
69
70
|
end
|
70
71
|
|
71
72
|
# Perform an update of the relationship of the parent and child. This
|
@@ -79,11 +80,11 @@ module Mongoid #:nodoc:
|
|
79
80
|
#
|
80
81
|
# Example:
|
81
82
|
#
|
82
|
-
# <tt>
|
83
|
+
# <tt>EmbedsOne.update({:first_name => "Hank"}, person, options)</tt>
|
83
84
|
#
|
84
85
|
# Returns:
|
85
86
|
#
|
86
|
-
# A new +
|
87
|
+
# A new +EmbedsOne+ association proxy.
|
87
88
|
def update(child, parent, options)
|
88
89
|
child.assimilate(parent, options)
|
89
90
|
instantiate(parent, options)
|
@@ -1,8 +1,9 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Mongoid #:nodoc:
|
3
3
|
module Associations #:nodoc:
|
4
|
-
|
5
|
-
|
4
|
+
# Represents an relational one-to-many association with an object in a
|
5
|
+
# separate collection or database.
|
6
|
+
class HasManyRelated < Proxy
|
6
7
|
|
7
8
|
# Appends the object to the +Array+, setting its parent in
|
8
9
|
# the process.
|
@@ -41,10 +42,42 @@ module Mongoid #:nodoc:
|
|
41
42
|
# Returns the newly created object.
|
42
43
|
def create(attributes)
|
43
44
|
object = build(attributes)
|
44
|
-
object.
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
object.save; object
|
46
|
+
end
|
47
|
+
|
48
|
+
# Creates a new Document and adds it to the association collection. If
|
49
|
+
# validation fails an error is raised.
|
50
|
+
#
|
51
|
+
# Returns the newly created object.
|
52
|
+
def create!(attributes)
|
53
|
+
object = build(attributes)
|
54
|
+
object.save!; object
|
55
|
+
end
|
56
|
+
|
57
|
+
# Delete all the associated objects.
|
58
|
+
#
|
59
|
+
# Example:
|
60
|
+
#
|
61
|
+
# <tt>person.posts.delete_all</tt>
|
62
|
+
#
|
63
|
+
# Returns:
|
64
|
+
#
|
65
|
+
# The number of objects deleted.
|
66
|
+
def delete_all(conditions = {})
|
67
|
+
remove(:delete_all, conditions[:conditions])
|
68
|
+
end
|
69
|
+
|
70
|
+
# Destroy all the associated objects.
|
71
|
+
#
|
72
|
+
# Example:
|
73
|
+
#
|
74
|
+
# <tt>person.posts.destroy_all</tt>
|
75
|
+
#
|
76
|
+
# Returns:
|
77
|
+
#
|
78
|
+
# The number of objects destroyed.
|
79
|
+
def destroy_all(conditions = {})
|
80
|
+
remove(:destroy_all, conditions[:conditions])
|
48
81
|
end
|
49
82
|
|
50
83
|
# Finds a document in this association.
|
@@ -62,7 +95,7 @@ module Mongoid #:nodoc:
|
|
62
95
|
# document: The +Document+ that contains the relationship.
|
63
96
|
# options: The association +Options+.
|
64
97
|
def initialize(document, options, target = nil)
|
65
|
-
@parent, @klass = document, options.klass
|
98
|
+
@parent, @klass, @options = document, options.klass, options
|
66
99
|
@foreign_key = options.foreign_key
|
67
100
|
@base = lambda { @klass.all(:conditions => { @foreign_key => document.id }) }
|
68
101
|
@target = target || @base.call
|
@@ -96,6 +129,18 @@ module Mongoid #:nodoc:
|
|
96
129
|
@target = @target.entries if @parent.new_record?
|
97
130
|
end
|
98
131
|
|
132
|
+
# Remove the objects based on conditions.
|
133
|
+
def remove(method, conditions)
|
134
|
+
selector = { @foreign_key => @parent.id }.merge(conditions || {})
|
135
|
+
removed = @klass.send(method, :conditions => selector)
|
136
|
+
reset; removed
|
137
|
+
end
|
138
|
+
|
139
|
+
# Reset the memoized association on the parent.
|
140
|
+
def reset
|
141
|
+
@parent.send(:reset, @options.name) { @base.call }
|
142
|
+
end
|
143
|
+
|
99
144
|
class << self
|
100
145
|
# Preferred method for creating the new +HasManyRelated+ association.
|
101
146
|
#
|
@@ -1,8 +1,9 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Mongoid #:nodoc:
|
3
3
|
module Associations #:nodoc:
|
4
|
-
|
5
|
-
|
4
|
+
# Represents an relational one-to-one association with an object in a
|
5
|
+
# separate collection or database.
|
6
|
+
class HasOneRelated < Proxy
|
6
7
|
|
7
8
|
delegate :nil?, :to => :target
|
8
9
|
|
@@ -11,7 +12,10 @@ module Mongoid #:nodoc:
|
|
11
12
|
# Returns the newly created object.
|
12
13
|
def build(attributes = {})
|
13
14
|
@target = @klass.instantiate(attributes)
|
14
|
-
|
15
|
+
inverse = @target.associations.values.detect do |metadata|
|
16
|
+
metadata.options.klass == @parent.class
|
17
|
+
end
|
18
|
+
name = inverse.name
|
15
19
|
@target.send("#{name}=", @parent)
|
16
20
|
@target
|
17
21
|
end
|
@@ -33,7 +37,7 @@ module Mongoid #:nodoc:
|
|
33
37
|
# options: The association +Options+.
|
34
38
|
def initialize(document, options, target = nil)
|
35
39
|
@parent, @klass = document, options.klass
|
36
|
-
@foreign_key =
|
40
|
+
@foreign_key = options.foreign_key
|
37
41
|
@target = target || @klass.first(:conditions => { @foreign_key => @parent.id })
|
38
42
|
extends(options)
|
39
43
|
end
|
@@ -21,7 +21,8 @@ module Mongoid #:nodoc:
|
|
21
21
|
|
22
22
|
# Return the foreign key based off the association name.
|
23
23
|
def foreign_key
|
24
|
-
@attributes[:foreign_key] || klass.name.to_s.foreign_key
|
24
|
+
key = @attributes[:foreign_key] || klass.name.to_s.foreign_key
|
25
|
+
key.to_s
|
25
26
|
end
|
26
27
|
|
27
28
|
# Returns the name of the inverse_of association
|
@@ -47,6 +48,10 @@ module Mongoid #:nodoc:
|
|
47
48
|
@attributes[:polymorphic] == true
|
48
49
|
end
|
49
50
|
|
51
|
+
# Used with has_many_related to save as array of ids.
|
52
|
+
def stored_as
|
53
|
+
@attributes[:stored_as]
|
54
|
+
end
|
50
55
|
end
|
51
56
|
end
|
52
57
|
end
|
@@ -1,30 +1,23 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Mongoid #:nodoc
|
3
3
|
module Associations #:nodoc
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
instance_methods.each do |method|
|
8
|
-
undef_method(method) unless method =~ /(^__|^nil\?$|^send$|^object_id$|^extend$)/
|
9
|
-
end
|
10
|
-
include InstanceMethods
|
11
|
-
end
|
4
|
+
class Proxy #:nodoc
|
5
|
+
instance_methods.each do |method|
|
6
|
+
undef_method(method) unless method =~ /(^__|^nil\?$|^send$|^object_id$|^extend$)/
|
12
7
|
end
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
:target
|
8
|
+
attr_reader \
|
9
|
+
:options,
|
10
|
+
:target
|
17
11
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
12
|
+
# Default behavior of method missing should be to delegate all calls
|
13
|
+
# to the target of the proxy. This can be overridden in special cases.
|
14
|
+
def method_missing(name, *args, &block)
|
15
|
+
@target.send(name, *args, &block)
|
16
|
+
end
|
23
17
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
18
|
+
# If anonymous extensions are added this will take care of them.
|
19
|
+
def extends(options)
|
20
|
+
extend Module.new(&options.extension) if options.extension?
|
28
21
|
end
|
29
22
|
end
|
30
23
|
end
|