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.
Files changed (200) hide show
  1. data/lib/mongoid.rb +10 -3
  2. data/lib/mongoid/associations.rb +133 -97
  3. data/lib/mongoid/associations/belongs_to_related.rb +2 -3
  4. data/lib/mongoid/associations/{belongs_to.rb → embedded_in.rb} +14 -6
  5. data/lib/mongoid/associations/{has_many.rb → embeds_many.rb} +89 -31
  6. data/lib/mongoid/associations/{has_one.rb → embeds_one.rb} +8 -7
  7. data/lib/mongoid/associations/has_many_related.rb +52 -7
  8. data/lib/mongoid/associations/has_one_related.rb +8 -4
  9. data/lib/mongoid/associations/meta_data.rb +2 -1
  10. data/lib/mongoid/associations/options.rb +6 -1
  11. data/lib/mongoid/associations/proxy.rb +14 -21
  12. data/lib/mongoid/attributes.rb +27 -12
  13. data/lib/mongoid/collection.rb +4 -3
  14. data/lib/mongoid/collections.rb +41 -0
  15. data/lib/mongoid/collections/master.rb +3 -2
  16. data/lib/mongoid/collections/slaves.rb +3 -2
  17. data/lib/mongoid/components.rb +21 -19
  18. data/lib/mongoid/concern.rb +31 -0
  19. data/lib/mongoid/config.rb +117 -12
  20. data/lib/mongoid/contexts.rb +1 -1
  21. data/lib/mongoid/contexts/enumerable.rb +1 -1
  22. data/lib/mongoid/contexts/mongo.rb +1 -1
  23. data/lib/mongoid/contexts/paging.rb +10 -2
  24. data/lib/mongoid/criterion/inclusion.rb +17 -0
  25. data/lib/mongoid/criterion/optional.rb +1 -1
  26. data/lib/mongoid/dirty.rb +253 -0
  27. data/lib/mongoid/document.rb +81 -52
  28. data/lib/mongoid/errors.rb +32 -1
  29. data/lib/mongoid/extensions.rb +11 -9
  30. data/lib/mongoid/extensions/big_decimal/conversions.rb +2 -2
  31. data/lib/mongoid/extensions/boolean/conversions.rb +8 -2
  32. data/lib/mongoid/extensions/date/conversions.rb +13 -4
  33. data/lib/mongoid/extensions/datetime/conversions.rb +1 -6
  34. data/lib/mongoid/extensions/float/conversions.rb +5 -1
  35. data/lib/mongoid/extensions/hash/assimilation.rb +12 -3
  36. data/lib/mongoid/extensions/hash/conversions.rb +34 -4
  37. data/lib/mongoid/extensions/integer/conversions.rb +5 -1
  38. data/lib/mongoid/extensions/nil/assimilation.rb +4 -0
  39. data/lib/mongoid/extensions/object/conversions.rb +1 -1
  40. data/lib/mongoid/extensions/string/conversions.rb +1 -1
  41. data/lib/mongoid/extensions/symbol/inflections.rb +1 -1
  42. data/lib/mongoid/extensions/time_conversions.rb +35 -0
  43. data/lib/mongoid/extras.rb +6 -9
  44. data/lib/mongoid/factory.rb +2 -1
  45. data/lib/mongoid/field.rb +9 -2
  46. data/lib/mongoid/fields.rb +1 -0
  47. data/lib/mongoid/identity.rb +3 -3
  48. data/lib/mongoid/indexes.rb +3 -3
  49. data/lib/mongoid/memoization.rb +8 -2
  50. data/lib/mongoid/named_scope.rb +0 -3
  51. data/lib/mongoid/observable.rb +30 -0
  52. data/lib/mongoid/paths.rb +62 -0
  53. data/lib/mongoid/persistence.rb +222 -0
  54. data/lib/mongoid/persistence/command.rb +39 -0
  55. data/lib/mongoid/persistence/insert.rb +50 -0
  56. data/lib/mongoid/persistence/insert_embedded.rb +38 -0
  57. data/lib/mongoid/persistence/remove.rb +39 -0
  58. data/lib/mongoid/persistence/remove_all.rb +37 -0
  59. data/lib/mongoid/persistence/remove_embedded.rb +50 -0
  60. data/lib/mongoid/persistence/update.rb +63 -0
  61. data/lib/mongoid/state.rb +28 -21
  62. data/lib/mongoid/timestamps.rb +5 -8
  63. data/lib/mongoid/version.rb +4 -0
  64. data/lib/mongoid/versioning.rb +6 -7
  65. metadata +81 -300
  66. data/.gitignore +0 -6
  67. data/.watchr +0 -29
  68. data/Rakefile +0 -53
  69. data/VERSION +0 -1
  70. data/caliper.yml +0 -4
  71. data/lib/mongoid/collections/mimic.rb +0 -46
  72. data/lib/mongoid/commands.rb +0 -174
  73. data/lib/mongoid/commands/create.rb +0 -21
  74. data/lib/mongoid/commands/delete.rb +0 -16
  75. data/lib/mongoid/commands/delete_all.rb +0 -23
  76. data/lib/mongoid/commands/deletion.rb +0 -18
  77. data/lib/mongoid/commands/destroy.rb +0 -19
  78. data/lib/mongoid/commands/destroy_all.rb +0 -23
  79. data/lib/mongoid/commands/save.rb +0 -27
  80. data/lib/mongoid/extensions/time/conversions.rb +0 -18
  81. data/mongoid.gemspec +0 -395
  82. data/perf/benchmark.rb +0 -77
  83. data/spec/integration/mongoid/associations_spec.rb +0 -340
  84. data/spec/integration/mongoid/attributes_spec.rb +0 -22
  85. data/spec/integration/mongoid/commands_spec.rb +0 -218
  86. data/spec/integration/mongoid/contexts/enumerable_spec.rb +0 -33
  87. data/spec/integration/mongoid/criteria_spec.rb +0 -272
  88. data/spec/integration/mongoid/document_spec.rb +0 -593
  89. data/spec/integration/mongoid/extensions_spec.rb +0 -26
  90. data/spec/integration/mongoid/finders_spec.rb +0 -119
  91. data/spec/integration/mongoid/inheritance_spec.rb +0 -137
  92. data/spec/integration/mongoid/named_scope_spec.rb +0 -46
  93. data/spec/models/address.rb +0 -39
  94. data/spec/models/animal.rb +0 -6
  95. data/spec/models/callbacks.rb +0 -18
  96. data/spec/models/comment.rb +0 -8
  97. data/spec/models/country_code.rb +0 -6
  98. data/spec/models/employer.rb +0 -5
  99. data/spec/models/game.rb +0 -7
  100. data/spec/models/inheritance.rb +0 -56
  101. data/spec/models/location.rb +0 -5
  102. data/spec/models/mixed_drink.rb +0 -4
  103. data/spec/models/name.rb +0 -13
  104. data/spec/models/namespacing.rb +0 -11
  105. data/spec/models/patient.rb +0 -4
  106. data/spec/models/person.rb +0 -99
  107. data/spec/models/pet.rb +0 -7
  108. data/spec/models/pet_owner.rb +0 -6
  109. data/spec/models/phone.rb +0 -7
  110. data/spec/models/post.rb +0 -15
  111. data/spec/models/translation.rb +0 -5
  112. data/spec/models/vet_visit.rb +0 -5
  113. data/spec/spec.opts +0 -3
  114. data/spec/spec_helper.rb +0 -31
  115. data/spec/unit/mongoid/associations/belongs_to_related_spec.rb +0 -145
  116. data/spec/unit/mongoid/associations/belongs_to_spec.rb +0 -193
  117. data/spec/unit/mongoid/associations/has_many_related_spec.rb +0 -420
  118. data/spec/unit/mongoid/associations/has_many_spec.rb +0 -519
  119. data/spec/unit/mongoid/associations/has_one_related_spec.rb +0 -179
  120. data/spec/unit/mongoid/associations/has_one_spec.rb +0 -282
  121. data/spec/unit/mongoid/associations/meta_data_spec.rb +0 -88
  122. data/spec/unit/mongoid/associations/options_spec.rb +0 -192
  123. data/spec/unit/mongoid/associations_spec.rb +0 -595
  124. data/spec/unit/mongoid/attributes_spec.rb +0 -507
  125. data/spec/unit/mongoid/callbacks_spec.rb +0 -55
  126. data/spec/unit/mongoid/collection_spec.rb +0 -187
  127. data/spec/unit/mongoid/collections/cyclic_iterator_spec.rb +0 -75
  128. data/spec/unit/mongoid/collections/master_spec.rb +0 -41
  129. data/spec/unit/mongoid/collections/mimic_spec.rb +0 -43
  130. data/spec/unit/mongoid/collections/slaves_spec.rb +0 -81
  131. data/spec/unit/mongoid/commands/create_spec.rb +0 -30
  132. data/spec/unit/mongoid/commands/delete_all_spec.rb +0 -58
  133. data/spec/unit/mongoid/commands/delete_spec.rb +0 -38
  134. data/spec/unit/mongoid/commands/destroy_all_spec.rb +0 -23
  135. data/spec/unit/mongoid/commands/destroy_spec.rb +0 -50
  136. data/spec/unit/mongoid/commands/save_spec.rb +0 -105
  137. data/spec/unit/mongoid/commands_spec.rb +0 -275
  138. data/spec/unit/mongoid/config_spec.rb +0 -172
  139. data/spec/unit/mongoid/contexts/enumerable_spec.rb +0 -421
  140. data/spec/unit/mongoid/contexts/mongo_spec.rb +0 -682
  141. data/spec/unit/mongoid/contexts_spec.rb +0 -25
  142. data/spec/unit/mongoid/criteria_spec.rb +0 -824
  143. data/spec/unit/mongoid/criterion/complex_spec.rb +0 -19
  144. data/spec/unit/mongoid/criterion/exclusion_spec.rb +0 -91
  145. data/spec/unit/mongoid/criterion/inclusion_spec.rb +0 -219
  146. data/spec/unit/mongoid/criterion/optional_spec.rb +0 -319
  147. data/spec/unit/mongoid/cursor_spec.rb +0 -74
  148. data/spec/unit/mongoid/deprecation_spec.rb +0 -24
  149. data/spec/unit/mongoid/document_spec.rb +0 -952
  150. data/spec/unit/mongoid/errors_spec.rb +0 -103
  151. data/spec/unit/mongoid/extensions/array/accessors_spec.rb +0 -50
  152. data/spec/unit/mongoid/extensions/array/assimilation_spec.rb +0 -24
  153. data/spec/unit/mongoid/extensions/array/conversions_spec.rb +0 -35
  154. data/spec/unit/mongoid/extensions/array/parentization_spec.rb +0 -20
  155. data/spec/unit/mongoid/extensions/big_decimal/conversions_spec.rb +0 -22
  156. data/spec/unit/mongoid/extensions/binary/conversions_spec.rb +0 -22
  157. data/spec/unit/mongoid/extensions/boolean/conversions_spec.rb +0 -49
  158. data/spec/unit/mongoid/extensions/date/conversions_spec.rb +0 -102
  159. data/spec/unit/mongoid/extensions/datetime/conversions_spec.rb +0 -70
  160. data/spec/unit/mongoid/extensions/float/conversions_spec.rb +0 -61
  161. data/spec/unit/mongoid/extensions/hash/accessors_spec.rb +0 -184
  162. data/spec/unit/mongoid/extensions/hash/assimilation_spec.rb +0 -46
  163. data/spec/unit/mongoid/extensions/hash/conversions_spec.rb +0 -21
  164. data/spec/unit/mongoid/extensions/hash/criteria_helpers_spec.rb +0 -17
  165. data/spec/unit/mongoid/extensions/hash/scoping_spec.rb +0 -14
  166. data/spec/unit/mongoid/extensions/integer/conversions_spec.rb +0 -61
  167. data/spec/unit/mongoid/extensions/nil/assimilation_spec.rb +0 -24
  168. data/spec/unit/mongoid/extensions/object/conversions_spec.rb +0 -57
  169. data/spec/unit/mongoid/extensions/proc/scoping_spec.rb +0 -34
  170. data/spec/unit/mongoid/extensions/string/conversions_spec.rb +0 -17
  171. data/spec/unit/mongoid/extensions/string/inflections_spec.rb +0 -208
  172. data/spec/unit/mongoid/extensions/symbol/inflections_spec.rb +0 -91
  173. data/spec/unit/mongoid/extensions/time/conversions_spec.rb +0 -70
  174. data/spec/unit/mongoid/extras_spec.rb +0 -102
  175. data/spec/unit/mongoid/factory_spec.rb +0 -31
  176. data/spec/unit/mongoid/field_spec.rb +0 -143
  177. data/spec/unit/mongoid/fields_spec.rb +0 -181
  178. data/spec/unit/mongoid/finders_spec.rb +0 -404
  179. data/spec/unit/mongoid/identity_spec.rb +0 -109
  180. data/spec/unit/mongoid/indexes_spec.rb +0 -93
  181. data/spec/unit/mongoid/javascript_spec.rb +0 -48
  182. data/spec/unit/mongoid/matchers/all_spec.rb +0 -27
  183. data/spec/unit/mongoid/matchers/default_spec.rb +0 -27
  184. data/spec/unit/mongoid/matchers/exists_spec.rb +0 -56
  185. data/spec/unit/mongoid/matchers/gt_spec.rb +0 -39
  186. data/spec/unit/mongoid/matchers/gte_spec.rb +0 -49
  187. data/spec/unit/mongoid/matchers/in_spec.rb +0 -27
  188. data/spec/unit/mongoid/matchers/lt_spec.rb +0 -39
  189. data/spec/unit/mongoid/matchers/lte_spec.rb +0 -49
  190. data/spec/unit/mongoid/matchers/ne_spec.rb +0 -27
  191. data/spec/unit/mongoid/matchers/nin_spec.rb +0 -27
  192. data/spec/unit/mongoid/matchers/size_spec.rb +0 -27
  193. data/spec/unit/mongoid/matchers_spec.rb +0 -329
  194. data/spec/unit/mongoid/memoization_spec.rb +0 -75
  195. data/spec/unit/mongoid/named_scope_spec.rb +0 -123
  196. data/spec/unit/mongoid/scope_spec.rb +0 -240
  197. data/spec/unit/mongoid/state_spec.rb +0 -83
  198. data/spec/unit/mongoid/timestamps_spec.rb +0 -25
  199. data/spec/unit/mongoid/versioning_spec.rb +0 -41
  200. data/spec/unit/mongoid_spec.rb +0 -46
@@ -1,420 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Mongoid::Associations::HasManyRelated do
4
-
5
- let(:block) do
6
- Proc.new do
7
- def extension
8
- "Testing"
9
- end
10
- end
11
- end
12
-
13
- let(:options) do
14
- Mongoid::Associations::Options.new(
15
- :name => :posts,
16
- :foreign_key => "person_id",
17
- :extend => block
18
- )
19
- end
20
-
21
- describe "#<<" do
22
-
23
- before do
24
- @child = stub
25
- @second = stub
26
- @children = [@child, @second]
27
- end
28
-
29
- context "when parent document has been saved" do
30
-
31
- before do
32
- @parent = stub(:id => "1", :new_record? => false, :class => Person)
33
- Post.expects(:all).returns([])
34
- @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
35
- end
36
-
37
- it "saves and appends the child document" do
38
- @child.expects(:person_id=).with(@parent.id)
39
- @child.expects(:save).returns(true)
40
- @association << @child
41
- @association.size.should == 1
42
- end
43
-
44
- end
45
-
46
- context "when parent document has not been saved" do
47
-
48
- context "when appending a non mongoid object" do
49
-
50
- before do
51
- @parent = stub(:id => "1", :new_record? => true, :class => Person)
52
- Post.expects(:all).returns([])
53
- @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
54
- end
55
-
56
- it "appends the child document" do
57
- @child.expects(:person_id=).with(@parent.id)
58
- @association << @child
59
- @association.size.should == 1
60
- end
61
- end
62
-
63
- context "when appending a mongoid document" do
64
-
65
- before do
66
- @criteria = mock
67
- @parent = stub(:id => "1", :new_record? => true, :class => Person)
68
- Post.expects(:all).returns(@criteria)
69
- @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
70
- end
71
-
72
- it "appends the child document" do
73
- @criteria.expects(:entries).returns([])
74
- @child.expects(:person_id=).with(@parent.id)
75
- @association << @child
76
- @association.size.should == 1
77
- end
78
- end
79
-
80
- end
81
-
82
- context "with multiple objects" do
83
-
84
- before do
85
- @parent = stub(:id => "1", :new_record? => true, :class => Person)
86
- Post.expects(:all).returns([])
87
- @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
88
- end
89
-
90
- it "appends the child documents" do
91
- @child.expects(:person_id=).with(@parent.id)
92
- @second.expects(:person_id=).with(@parent.id)
93
- @association << [@child, @second]
94
- @association.size.should == 2
95
- end
96
-
97
- end
98
-
99
- end
100
-
101
- describe "#build" do
102
-
103
- before do
104
- @criteria = mock
105
- @criteria.expects(:entries).returns([])
106
- @parent = stub(:id => "5", :class => Person, :new_record? => true)
107
- Post.expects(:all).returns(@criteria)
108
- @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
109
- end
110
-
111
- it "adds a new object to the association" do
112
- @association.build(:title => "Sassy")
113
- @association.size.should == 1
114
- end
115
-
116
- it "sets the parent object id on the child" do
117
- @association.build(:title => "Sassy")
118
- @association.first.person_id.should == @parent.id
119
- end
120
-
121
- it "returns the new object" do
122
- @association.build(:title => "Sassy").title.should == "Sassy"
123
- end
124
-
125
- it "sets the parent object reference on the child" do
126
- @association.build(:title => "Sassy")
127
- @association.first.person.should == @parent
128
- end
129
-
130
- end
131
-
132
- describe "#concat" do
133
-
134
- before do
135
- @child = stub
136
- @second = stub
137
- end
138
-
139
- context "when parent document has been saved" do
140
-
141
- before do
142
- @parent = stub(:id => "1", :new_record? => false, :class => Person)
143
- Post.expects(:all).returns([])
144
- @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
145
- end
146
-
147
- it "saves and appends the child document" do
148
- @child.expects(:person_id=).with(@parent.id)
149
- @child.expects(:save).returns(true)
150
- @association.concat(@child)
151
- @association.size.should == 1
152
- end
153
-
154
- end
155
-
156
- context "when parent document has not been saved" do
157
-
158
- before do
159
- @parent = stub(:id => "1", :new_record? => true, :class => Person)
160
- Post.expects(:all).returns([])
161
- @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
162
- end
163
-
164
- it "appends the child document" do
165
- @child.expects(:person_id=).with(@parent.id)
166
- @association.concat(@child)
167
- @association.size.should == 1
168
- end
169
-
170
- end
171
-
172
- context "with multiple objects" do
173
-
174
- before do
175
- @parent = stub(:id => "1", :new_record? => true, :class => Person)
176
- Post.expects(:all).returns([])
177
- @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
178
- end
179
-
180
- it "appends the child documents" do
181
- @child.expects(:person_id=).with(@parent.id)
182
- @second.expects(:person_id=).with(@parent.id)
183
- @association.concat([@child, @second])
184
- @association.size.should == 2
185
- end
186
-
187
- end
188
-
189
- end
190
-
191
- describe "#create" do
192
-
193
- before do
194
- @post = mock
195
- @parent = stub(:id => "5", :class => Person, :new_record? => true)
196
- Post.expects(:all).returns([])
197
- @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
198
- Post.expects(:instantiate).returns(@post)
199
- end
200
-
201
- it "builds and saves the new object" do
202
- @post.expects(:run_callbacks).with(:before_create)
203
- @post.expects(:save).returns(true)
204
- @post.expects(:run_callbacks).with(:after_create)
205
- @association.create(:title => "Sassy")
206
- end
207
-
208
- it "returns the new object" do
209
- @post.expects(:run_callbacks).with(:before_create)
210
- @post.expects(:save).returns(true)
211
- @post.expects(:run_callbacks).with(:after_create)
212
- @association.create(:title => "Sassy").should == @post
213
- end
214
-
215
- end
216
-
217
- describe "#find" do
218
-
219
- before do
220
- @parent = stub(:id => "5", :class => Person)
221
- Post.expects(:all).returns([])
222
- @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
223
- end
224
-
225
- context "when finding by id" do
226
-
227
- before do
228
- @post = stub
229
- end
230
-
231
- it "returns the document in the array with that id" do
232
- Post.expects(:find).with("5").returns(@post)
233
- post = @association.find("5")
234
- post.should == @post
235
- end
236
-
237
- end
238
-
239
- context "when finding all with conditions" do
240
-
241
- before do
242
- @post = stub
243
- end
244
-
245
- it "passes the conditions to the association class" do
246
- Post.expects(:find).with(:all, :conditions => { :title => "Testing", :person_id => @parent.id }).returns([@post])
247
- posts = @association.find(:all, :conditions => { :title => "Testing" })
248
- posts.should == [@post]
249
- end
250
-
251
- end
252
-
253
- context "when finding first with conditions" do
254
-
255
- before do
256
- @post = stub
257
- end
258
-
259
- it "passes the conditions to the association class" do
260
- Post.expects(:find).with(:first, :conditions => { :title => "Testing", :person_id => @parent.id }).returns(@post)
261
- post = @association.find(:first, :conditions => { :title => "Testing" })
262
- post.should == @post
263
- end
264
-
265
- end
266
-
267
- context "when finding last with conditions" do
268
-
269
- before do
270
- @post = stub
271
- end
272
-
273
- it "passes the conditions to the association class" do
274
- Post.expects(:find).with(:last, :conditions => { :title => "Testing", :person_id => @parent.id }).returns(@post)
275
- post = @association.find(:last, :conditions => { :title => "Testing" })
276
- post.should == @post
277
- end
278
-
279
- end
280
-
281
- end
282
-
283
- describe ".initialize" do
284
-
285
- before do
286
- @document = Person.new
287
- @criteria = stub
288
- @first = stub(:person_id => @document.id)
289
- @second = stub(:person_id => @document.id)
290
- @related = [@first, @second]
291
- Post.expects(:all).with(:conditions => { "person_id" => @document.id }).returns(@related)
292
- end
293
-
294
- context "when related id has been set" do
295
-
296
- it "finds the object by id" do
297
- association = Mongoid::Associations::HasManyRelated.new(@document, options)
298
- association.should == @related
299
- end
300
-
301
- end
302
-
303
- context "when the options have an extension" do
304
-
305
- it "adds the extension module" do
306
- association = Mongoid::Associations::HasManyRelated.new(@document, options)
307
- association.extension.should == "Testing"
308
- end
309
-
310
- end
311
-
312
- end
313
-
314
- describe ".instantiate" do
315
-
316
- context "when related id has been set" do
317
-
318
- before do
319
- @document = Person.new
320
- end
321
-
322
- it "delegates to new" do
323
- Mongoid::Associations::HasManyRelated.expects(:new).with(@document, options, nil)
324
- association = Mongoid::Associations::HasManyRelated.instantiate(@document, options)
325
- end
326
-
327
- end
328
-
329
- end
330
-
331
- describe ".macro" do
332
-
333
- it "returns :has_many_related" do
334
- Mongoid::Associations::HasManyRelated.macro.should == :has_many_related
335
- end
336
-
337
- end
338
-
339
- describe "#push" do
340
-
341
- before do
342
- @child = stub
343
- @second = stub
344
- end
345
-
346
- context "when parent document has been saved" do
347
-
348
- before do
349
- @parent = stub(:id => "1", :new_record? => false, :class => Person)
350
- Post.expects(:all).returns([])
351
- @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
352
- end
353
-
354
- it "saves and appends the child document" do
355
- @child.expects(:person_id=).with(@parent.id)
356
- @child.expects(:save).returns(true)
357
- @association.push(@child)
358
- @association.size.should == 1
359
- end
360
-
361
- end
362
-
363
- context "when parent document has not been saved" do
364
-
365
- before do
366
- @parent = stub(:id => "1", :new_record? => true, :class => Person)
367
- Post.expects(:all).returns([])
368
- @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
369
- end
370
-
371
- it "appends the child document" do
372
- @child.expects(:person_id=).with(@parent.id)
373
- @association.push(@child)
374
- @association.size.should == 1
375
- end
376
-
377
- end
378
-
379
- context "with multiple objects" do
380
-
381
- before do
382
- @parent = stub(:id => "1", :new_record? => true, :class => Person)
383
- Post.expects(:all).returns([])
384
- @association = Mongoid::Associations::HasManyRelated.new(@parent, options)
385
- end
386
-
387
- it "appends the child documents" do
388
- @child.expects(:person_id=).with(@parent.id)
389
- @second.expects(:person_id=).with(@parent.id)
390
- @association.push(@child, @second)
391
- @association.size.should == 2
392
- end
393
-
394
- end
395
-
396
- end
397
-
398
- describe ".update" do
399
-
400
- before do
401
- @first = Post.new
402
- @second = Post.new
403
- @related = [@first, @second]
404
- @parent = Person.new
405
- end
406
-
407
- it "sets the related object id on the parent" do
408
- Mongoid::Associations::HasManyRelated.update(@related, @parent, options)
409
- @first.person_id.should == @parent.id
410
- @second.person_id.should == @parent.id
411
- end
412
-
413
- it "returns the related objects" do
414
- @proxy = Mongoid::Associations::HasManyRelated.update(@related, @parent, options)
415
- @proxy.target.should == @related
416
- end
417
-
418
- end
419
-
420
- end
@@ -1,519 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Mongoid::Associations::HasMany do
4
-
5
- before do
6
- @attributes = { "addresses" => [
7
- { "_id" => "street-1", "street" => "Street 1", "state" => "CA" },
8
- { "_id" => "street-2", "street" => "Street 2" } ] }
9
- @document = stub(:raw_attributes => @attributes, :add_observer => true, :update => true)
10
- end
11
-
12
- describe "#[]" do
13
-
14
- before do
15
- @association = Mongoid::Associations::HasMany.new(
16
- @document,
17
- Mongoid::Associations::Options.new(:name => :addresses)
18
- )
19
- end
20
-
21
- context "when the index is present in the association" do
22
-
23
- it "returns the document at the index" do
24
- @association[0].should be_a_kind_of(Address)
25
- @association[0].street.should == "Street 1"
26
- end
27
-
28
- end
29
-
30
- context "when the index is not present in the association" do
31
-
32
- it "returns nil" do
33
- @association[3].should be_nil
34
- end
35
-
36
- end
37
-
38
- end
39
-
40
- describe "#<<" do
41
-
42
- before do
43
- @association = Mongoid::Associations::HasMany.new(
44
- @document,
45
- Mongoid::Associations::Options.new(:name => :addresses)
46
- )
47
- @address = Address.new
48
- end
49
-
50
- it "adds the parent document before appending to the array" do
51
- @association << @address
52
- @association.length.should == 3
53
- @address._parent.should == @document
54
- end
55
-
56
- it "allows multiple additions" do
57
- @association << @address
58
- @association << @address
59
- @association.length.should == 4
60
- end
61
-
62
- end
63
-
64
- describe "#build" do
65
-
66
- context "setting the parent relationship" do
67
-
68
- before do
69
- @person = Person.new
70
- end
71
-
72
- it "happens before any other operation" do
73
- address = @person.addresses.build(:set_parent => true, :street => "Madison Ave")
74
- address._parent.should == @person
75
- @person.addresses.first.should == address
76
- end
77
-
78
- end
79
-
80
- context "when a type is not provided" do
81
-
82
- before do
83
- @association = Mongoid::Associations::HasMany.new(
84
- @document,
85
- Mongoid::Associations::Options.new(:name => :addresses)
86
- )
87
- end
88
-
89
- it "adds a new document to the array with the suppied parameters" do
90
- @association.build({ :street => "Street 1" })
91
- @association.length.should == 3
92
- @association[2].should be_a_kind_of(Address)
93
- @association[2].street.should == "Street 1"
94
- end
95
-
96
- it "returns the newly built object in the association" do
97
- address = @association.build({ :street => "Yet Another" })
98
- address.should be_a_kind_of(Address)
99
- address.street.should == "Yet Another"
100
- end
101
-
102
- end
103
-
104
- context "when a type is provided" do
105
-
106
- before do
107
- @association = Mongoid::Associations::HasMany.new(
108
- @document,
109
- Mongoid::Associations::Options.new(:name => :shapes)
110
- )
111
- end
112
-
113
- it "instantiates a class of the type" do
114
- circle = @association.build({ :radius => 100 }, Circle)
115
- circle.should be_a_kind_of(Circle)
116
- circle.radius.should == 100
117
- end
118
-
119
- end
120
-
121
- end
122
-
123
- describe "#create" do
124
-
125
- context "when a type is not provided" do
126
-
127
- before do
128
- @association = Mongoid::Associations::HasMany.new(
129
- @document,
130
- Mongoid::Associations::Options.new(:name => :addresses)
131
- )
132
- @address = mock(:parentize => true, :write_attributes => true)
133
- Address.expects(:instantiate).returns(@address)
134
- @address.expects(:run_callbacks).with(:before_create)
135
- @address.expects(:run_callbacks).with(:after_create)
136
- end
137
-
138
- it "builds and saves a new object" do
139
- @address.expects(:save).returns(true)
140
- address = @association.create({ :street => "Yet Another" })
141
- address.should == @address
142
- end
143
-
144
- end
145
-
146
- context "when a type is provided" do
147
-
148
- before do
149
- @association = Mongoid::Associations::HasMany.new(
150
- @document,
151
- Mongoid::Associations::Options.new(:name => :shapes)
152
- )
153
- @circle = mock(:parentize => true, :write_attributes => true)
154
- Circle.expects(:instantiate).returns(@circle)
155
- @circle.expects(:run_callbacks).with(:before_create)
156
- @circle.expects(:run_callbacks).with(:after_create)
157
- end
158
-
159
- it "instantiates a class of that type" do
160
- @circle.expects(:save).returns(true)
161
- circle = @association.create({ :radius => 100 }, Circle)
162
- circle.should == @circle
163
- end
164
-
165
- end
166
-
167
- end
168
-
169
- describe "#create!" do
170
-
171
- context "when validations pass" do
172
-
173
- before do
174
- @association = Mongoid::Associations::HasMany.new(
175
- @document,
176
- Mongoid::Associations::Options.new(:name => :addresses)
177
- )
178
- @address = mock(:parentize => true, :write_attributes => true, :errors => [])
179
- Address.expects(:instantiate).returns(@address)
180
- @address.expects(:run_callbacks).with(:before_create)
181
- @address.expects(:run_callbacks).with(:after_create)
182
- end
183
-
184
- it "builds and saves a new object" do
185
- @address.expects(:save).returns(true)
186
- address = @association.create!({ :street => "Yet Another" })
187
- address.should == @address
188
- end
189
- end
190
-
191
- context "when validations fail" do
192
-
193
- before do
194
- @association = Mongoid::Associations::HasMany.new(
195
- @document,
196
- Mongoid::Associations::Options.new(:name => :addresses)
197
- )
198
- @address = mock(:parentize => true, :write_attributes => true, :errors => [ "test" ])
199
- Address.expects(:instantiate).returns(@address)
200
- @address.expects(:run_callbacks).with(:before_create)
201
- end
202
-
203
- it "builds and saves a new object" do
204
- @address.expects(:save).returns(false)
205
- lambda {
206
- @association.create!({ :street => "Yet Another" })
207
- }.should raise_error(Mongoid::Errors::Validations)
208
- end
209
- end
210
- end
211
-
212
- describe "#concat" do
213
-
214
- before do
215
- @association = Mongoid::Associations::HasMany.new(
216
- @document,
217
- Mongoid::Associations::Options.new(:name => :addresses)
218
- )
219
- @address = Address.new
220
- end
221
-
222
- it "adds the parent document before appending to the array" do
223
- @association.concat [@address]
224
- @association.length.should == 3
225
- @address._parent.should == @document
226
- end
227
-
228
- end
229
-
230
- describe "#clear" do
231
-
232
- before do
233
- @association = Mongoid::Associations::HasMany.new(
234
- @document,
235
- Mongoid::Associations::Options.new(:name => :addresses)
236
- )
237
- @address = Address.new
238
- @association << @address
239
- end
240
-
241
- it "clears out the association" do
242
- @association.clear
243
- @association.size.should == 0
244
- end
245
-
246
- end
247
-
248
- describe "#find" do
249
-
250
- before do
251
- @association = Mongoid::Associations::HasMany.new(
252
- @document,
253
- Mongoid::Associations::Options.new(:name => :addresses)
254
- )
255
- end
256
-
257
- context "when finding all" do
258
-
259
- it "returns all the documents" do
260
- @association.find(:all).should == @association
261
- end
262
-
263
- end
264
-
265
- context "when finding by id" do
266
-
267
- it "returns the document in the array with that id" do
268
- address = @association.find("street-2")
269
- address.should_not be_nil
270
- end
271
-
272
- end
273
-
274
- end
275
-
276
- describe "#first" do
277
-
278
- context "when there are elements in the array" do
279
-
280
- before do
281
- @association = Mongoid::Associations::HasMany.new(
282
- @document,
283
- Mongoid::Associations::Options.new(:name => :addresses)
284
- )
285
- end
286
-
287
- it "returns the first element" do
288
- @association.first.should be_a_kind_of(Address)
289
- @association.first.street.should == "Street 1"
290
- end
291
-
292
- end
293
-
294
- context "when the array is empty" do
295
-
296
- before do
297
- @association = Mongoid::Associations::HasMany.new(
298
- Person.new,
299
- Mongoid::Associations::Options.new(:name => :addresses)
300
- )
301
- end
302
-
303
- it "returns nil" do
304
- @association.first.should be_nil
305
- end
306
-
307
- end
308
-
309
- end
310
-
311
- describe "#initialize" do
312
-
313
- context "when no extension exists" do
314
-
315
- before do
316
- @canvas = stub(:raw_attributes => { "shapes" => [{ "_type" => "Circle", "radius" => 5 }] }, :update => true)
317
- @association = Mongoid::Associations::HasMany.new(
318
- @canvas,
319
- Mongoid::Associations::Options.new(:name => :shapes)
320
- )
321
- end
322
-
323
- it "creates the classes based on their types" do
324
- circle = @association.first
325
- circle.should be_a_kind_of(Circle)
326
- circle.radius.should == 5
327
- end
328
-
329
- end
330
-
331
- context "when an extension is in the options" do
332
-
333
- before do
334
- @person = Person.new
335
- @block = Proc.new do
336
- def extension
337
- "Testing"
338
- end
339
- end
340
- @association = Mongoid::Associations::HasMany.new(
341
- @person,
342
- Mongoid::Associations::Options.new(:name => :addresses, :extend => @block)
343
- )
344
- end
345
-
346
- it "adds the extension module" do
347
- @association.extension.should == "Testing"
348
- end
349
-
350
- end
351
-
352
- end
353
-
354
- describe ".instantiate" do
355
-
356
- it "delegates to new" do
357
- Mongoid::Associations::HasMany.expects(:new).with(@document, @options)
358
- Mongoid::Associations::HasMany.instantiate(@document, @options)
359
- end
360
-
361
- end
362
-
363
- describe "#length" do
364
-
365
- context "#length" do
366
-
367
- it "returns the length of the delegated array" do
368
- @association = Mongoid::Associations::HasMany.new(
369
- @document,
370
- Mongoid::Associations::Options.new(:name => :addresses)
371
- )
372
- @association.length.should == 2
373
- end
374
-
375
- end
376
-
377
- end
378
-
379
- describe ".macro" do
380
-
381
- it "returns :has_many" do
382
- Mongoid::Associations::HasMany.macro.should == :has_many
383
- end
384
-
385
- end
386
-
387
- describe "#nested_build" do
388
-
389
- before do
390
- @association = Mongoid::Associations::HasMany.new(
391
- @document,
392
- Mongoid::Associations::Options.new(:name => :addresses)
393
- )
394
- end
395
-
396
- it "returns the newly built object in the association" do
397
- @association.nested_build({ "0" => { :street => "Yet Another" } })
398
- @association.size.should == 3
399
- @association.last.street.should == "Yet Another"
400
- end
401
-
402
- end
403
-
404
- describe "#method_missing" do
405
-
406
- context "when the association class has a criteria class method" do
407
-
408
- before do
409
- @association = Mongoid::Associations::HasMany.new(
410
- @document,
411
- Mongoid::Associations::Options.new(:name => :addresses)
412
- )
413
- end
414
-
415
- it "returns the criteria" do
416
- @association.california.should be_a_kind_of(Mongoid::Criteria)
417
- end
418
-
419
- it "sets the documents on the criteria" do
420
- criteria = @association.california
421
- criteria.documents.should == @association.entries
422
- end
423
-
424
- it "returns the scoped documents" do
425
- addresses = @association.california
426
- addresses.size.should == 1
427
- addresses.first.should be_a_kind_of(Address)
428
- addresses.first.state.should == "CA"
429
- end
430
-
431
- end
432
-
433
- context "when no class method exists" do
434
-
435
- before do
436
- @association = Mongoid::Associations::HasMany.new(
437
- @document,
438
- Mongoid::Associations::Options.new(:name => :addresses)
439
- )
440
- end
441
-
442
- it "delegates to the array" do
443
- @association.entries.size.should == 2
444
- end
445
-
446
- end
447
-
448
- end
449
-
450
- describe "#paginate" do
451
-
452
- before do
453
- @association = Mongoid::Associations::HasMany.new(
454
- @document,
455
- Mongoid::Associations::Options.new(:name => :addresses)
456
- )
457
- @options = { :page => 1, :per_page => 10 }
458
- @criteria = mock
459
- end
460
-
461
- it "creates a criteria and paginates it" do
462
- Mongoid::Criteria.expects(:translate).with(Address, @options).returns(@criteria)
463
- @criteria.expects(:documents=).with(@association.target)
464
- @criteria.expects(:paginate).returns([])
465
- @association.paginate(@options).should == []
466
- end
467
- end
468
-
469
- describe "#push" do
470
-
471
- before do
472
- @association = Mongoid::Associations::HasMany.new(
473
- @document,
474
- Mongoid::Associations::Options.new(:name => :addresses)
475
- )
476
- @address = Address.new
477
- end
478
-
479
- it "adds the parent document before appending to the array" do
480
- @association.push @address
481
- @association.length.should == 3
482
- @address._parent.should == @document
483
- end
484
-
485
- it "appends the document to the end of the array" do
486
- @association.push(Address.new)
487
- @association.length.should == 3
488
- end
489
-
490
- end
491
-
492
- describe ".update" do
493
-
494
- before do
495
- @address = Address.new(:street => "Madison Ave")
496
- @person = Person.new(:title => "Sir")
497
- @association = Mongoid::Associations::HasMany.update(
498
- [@address],
499
- @person,
500
- Mongoid::Associations::Options.new(:name => :addresses)
501
- )
502
- end
503
-
504
- it "parentizes the child document" do
505
- @address._parent.should == @person
506
- end
507
-
508
- it "sets the attributes of the child on the parent" do
509
- @person.attributes[:addresses].should ==
510
- [{ "_id" => "madison-ave", "street" => "Madison Ave", "_type" => "Address" }]
511
- end
512
-
513
- it "returns the association proxy" do
514
- @association.target.size.should == 1
515
- end
516
-
517
- end
518
-
519
- end