Froze rails gems
[depot.git] / vendor / rails / activerecord / test / cases / associations / belongs_to_associations_test.rb
1 require "cases/helper"
2 require 'models/developer'
3 require 'models/project'
4 require 'models/company'
5 require 'models/topic'
6 require 'models/reply'
7 require 'models/computer'
8 require 'models/customer'
9 require 'models/order'
10 require 'models/post'
11 require 'models/author'
12 require 'models/tag'
13 require 'models/tagging'
14 require 'models/comment'
15 require 'models/sponsor'
16 require 'models/member'
17
18 class BelongsToAssociationsTest < ActiveRecord::TestCase
19 fixtures :accounts, :companies, :developers, :projects, :topics,
20 :developers_projects, :computers, :authors, :posts, :tags, :taggings, :comments
21
22 def test_belongs_to
23 Client.find(3).firm.name
24 assert_equal companies(:first_firm).name, Client.find(3).firm.name
25 assert !Client.find(3).firm.nil?, "Microsoft should have a firm"
26 end
27
28 def test_proxy_assignment
29 account = Account.find(1)
30 assert_nothing_raised { account.firm = account.firm }
31 end
32
33 def test_triple_equality
34 assert Client.find(3).firm === Firm
35 assert Firm === Client.find(3).firm
36 end
37
38 def test_type_mismatch
39 assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = 1 }
40 assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = Project.find(1) }
41 end
42
43 def test_natural_assignment
44 apple = Firm.create("name" => "Apple")
45 citibank = Account.create("credit_limit" => 10)
46 citibank.firm = apple
47 assert_equal apple.id, citibank.firm_id
48 end
49
50 def test_no_unexpected_aliasing
51 first_firm = companies(:first_firm)
52 another_firm = companies(:another_firm)
53
54 citibank = Account.create("credit_limit" => 10)
55 citibank.firm = first_firm
56 original_proxy = citibank.firm
57 citibank.firm = another_firm
58
59 assert_equal first_firm.object_id, original_proxy.target.object_id
60 assert_equal another_firm.object_id, citibank.firm.target.object_id
61 end
62
63 def test_creating_the_belonging_object
64 citibank = Account.create("credit_limit" => 10)
65 apple = citibank.create_firm("name" => "Apple")
66 assert_equal apple, citibank.firm
67 citibank.save
68 citibank.reload
69 assert_equal apple, citibank.firm
70 end
71
72 def test_building_the_belonging_object
73 citibank = Account.create("credit_limit" => 10)
74 apple = citibank.build_firm("name" => "Apple")
75 citibank.save
76 assert_equal apple.id, citibank.firm_id
77 end
78
79 def test_natural_assignment_to_nil
80 client = Client.find(3)
81 client.firm = nil
82 client.save
83 assert_nil client.firm(true)
84 assert_nil client.client_of
85 end
86
87 def test_with_different_class_name
88 assert_equal Company.find(1).name, Company.find(3).firm_with_other_name.name
89 assert_not_nil Company.find(3).firm_with_other_name, "Microsoft should have a firm"
90 end
91
92 def test_with_condition
93 assert_equal Company.find(1).name, Company.find(3).firm_with_condition.name
94 assert_not_nil Company.find(3).firm_with_condition, "Microsoft should have a firm"
95 end
96
97 def test_with_select
98 assert_equal Company.find(2).firm_with_select.attributes.size, 1
99 assert_equal Company.find(2, :include => :firm_with_select ).firm_with_select.attributes.size, 1
100 end
101
102 def test_belongs_to_counter
103 debate = Topic.create("title" => "debate")
104 assert_equal 0, debate.send(:read_attribute, "replies_count"), "No replies yet"
105
106 trash = debate.replies.create("title" => "blah!", "content" => "world around!")
107 assert_equal 1, Topic.find(debate.id).send(:read_attribute, "replies_count"), "First reply created"
108
109 trash.destroy
110 assert_equal 0, Topic.find(debate.id).send(:read_attribute, "replies_count"), "First reply deleted"
111 end
112
113 def test_belongs_to_counter_with_assigning_nil
114 p = Post.find(1)
115 c = Comment.find(1)
116
117 assert_equal p.id, c.post_id
118 assert_equal 2, Post.find(p.id).comments.size
119
120 c.post = nil
121
122 assert_equal 1, Post.find(p.id).comments.size
123 end
124
125 def test_belongs_to_counter_with_reassigning
126 t1 = Topic.create("title" => "t1")
127 t2 = Topic.create("title" => "t2")
128 r1 = Reply.new("title" => "r1", "content" => "r1")
129 r1.topic = t1
130
131 assert r1.save
132 assert_equal 1, Topic.find(t1.id).replies.size
133 assert_equal 0, Topic.find(t2.id).replies.size
134
135 r1.topic = Topic.find(t2.id)
136
137 assert r1.save
138 assert_equal 0, Topic.find(t1.id).replies.size
139 assert_equal 1, Topic.find(t2.id).replies.size
140
141 r1.topic = nil
142
143 assert_equal 0, Topic.find(t1.id).replies.size
144 assert_equal 0, Topic.find(t2.id).replies.size
145
146 r1.topic = t1
147
148 assert_equal 1, Topic.find(t1.id).replies.size
149 assert_equal 0, Topic.find(t2.id).replies.size
150
151 r1.destroy
152
153 assert_equal 0, Topic.find(t1.id).replies.size
154 assert_equal 0, Topic.find(t2.id).replies.size
155 end
156
157 def test_belongs_to_counter_after_save
158 topic = Topic.create!(:title => "monday night")
159 topic.replies.create!(:title => "re: monday night", :content => "football")
160 assert_equal 1, Topic.find(topic.id)[:replies_count]
161
162 topic.save!
163 assert_equal 1, Topic.find(topic.id)[:replies_count]
164 end
165
166 def test_belongs_to_counter_after_update_attributes
167 topic = Topic.create!(:title => "37s")
168 topic.replies.create!(:title => "re: 37s", :content => "rails")
169 assert_equal 1, Topic.find(topic.id)[:replies_count]
170
171 topic.update_attributes(:title => "37signals")
172 assert_equal 1, Topic.find(topic.id)[:replies_count]
173 end
174
175 def test_belongs_to_counter_after_save
176 topic = Topic.create("title" => "monday night")
177 topic.replies.create("title" => "re: monday night", "content" => "football")
178 assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count")
179
180 topic.save
181 assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count")
182 end
183
184 def test_belongs_to_counter_after_update_attributes
185 topic = Topic.create("title" => "37s")
186 topic.replies.create("title" => "re: 37s", "content" => "rails")
187 assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count")
188
189 topic.update_attributes("title" => "37signals")
190 assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count")
191 end
192
193 def test_assignment_before_parent_saved
194 client = Client.find(:first)
195 apple = Firm.new("name" => "Apple")
196 client.firm = apple
197 assert_equal apple, client.firm
198 assert apple.new_record?
199 assert client.save
200 assert apple.save
201 assert !apple.new_record?
202 assert_equal apple, client.firm
203 assert_equal apple, client.firm(true)
204 end
205
206 def test_assignment_before_child_saved
207 final_cut = Client.new("name" => "Final Cut")
208 firm = Firm.find(1)
209 final_cut.firm = firm
210 assert final_cut.new_record?
211 assert final_cut.save
212 assert !final_cut.new_record?
213 assert !firm.new_record?
214 assert_equal firm, final_cut.firm
215 assert_equal firm, final_cut.firm(true)
216 end
217
218 def test_assignment_before_either_saved
219 final_cut = Client.new("name" => "Final Cut")
220 apple = Firm.new("name" => "Apple")
221 final_cut.firm = apple
222 assert final_cut.new_record?
223 assert apple.new_record?
224 assert final_cut.save
225 assert !final_cut.new_record?
226 assert !apple.new_record?
227 assert_equal apple, final_cut.firm
228 assert_equal apple, final_cut.firm(true)
229 end
230
231 def test_new_record_with_foreign_key_but_no_object
232 c = Client.new("firm_id" => 1)
233 assert_equal Firm.find(:first), c.firm_with_basic_id
234 end
235
236 def test_forgetting_the_load_when_foreign_key_enters_late
237 c = Client.new
238 assert_nil c.firm_with_basic_id
239
240 c.firm_id = 1
241 assert_equal Firm.find(:first), c.firm_with_basic_id
242 end
243
244 def test_field_name_same_as_foreign_key
245 computer = Computer.find(1)
246 assert_not_nil computer.developer, ":foreign key == attribute didn't lock up" # '
247 end
248
249 def test_counter_cache
250 topic = Topic.create :title => "Zoom-zoom-zoom"
251 assert_equal 0, topic[:replies_count]
252
253 reply = Reply.create(:title => "re: zoom", :content => "speedy quick!")
254 reply.topic = topic
255
256 assert_equal 1, topic.reload[:replies_count]
257 assert_equal 1, topic.replies.size
258
259 topic[:replies_count] = 15
260 assert_equal 15, topic.replies.size
261 end
262
263 def test_custom_counter_cache
264 reply = Reply.create(:title => "re: zoom", :content => "speedy quick!")
265 assert_equal 0, reply[:replies_count]
266
267 silly = SillyReply.create(:title => "gaga", :content => "boo-boo")
268 silly.reply = reply
269
270 assert_equal 1, reply.reload[:replies_count]
271 assert_equal 1, reply.replies.size
272
273 reply[:replies_count] = 17
274 assert_equal 17, reply.replies.size
275 end
276
277 def test_store_two_association_with_one_save
278 num_orders = Order.count
279 num_customers = Customer.count
280 order = Order.new
281
282 customer1 = order.billing = Customer.new
283 customer2 = order.shipping = Customer.new
284 assert order.save
285 assert_equal customer1, order.billing
286 assert_equal customer2, order.shipping
287
288 order.reload
289
290 assert_equal customer1, order.billing
291 assert_equal customer2, order.shipping
292
293 assert_equal num_orders +1, Order.count
294 assert_equal num_customers +2, Customer.count
295 end
296
297
298 def test_store_association_in_two_relations_with_one_save
299 num_orders = Order.count
300 num_customers = Customer.count
301 order = Order.new
302
303 customer = order.billing = order.shipping = Customer.new
304 assert order.save
305 assert_equal customer, order.billing
306 assert_equal customer, order.shipping
307
308 order.reload
309
310 assert_equal customer, order.billing
311 assert_equal customer, order.shipping
312
313 assert_equal num_orders +1, Order.count
314 assert_equal num_customers +1, Customer.count
315 end
316
317 def test_store_association_in_two_relations_with_one_save_in_existing_object
318 num_orders = Order.count
319 num_customers = Customer.count
320 order = Order.create
321
322 customer = order.billing = order.shipping = Customer.new
323 assert order.save
324 assert_equal customer, order.billing
325 assert_equal customer, order.shipping
326
327 order.reload
328
329 assert_equal customer, order.billing
330 assert_equal customer, order.shipping
331
332 assert_equal num_orders +1, Order.count
333 assert_equal num_customers +1, Customer.count
334 end
335
336 def test_store_association_in_two_relations_with_one_save_in_existing_object_with_values
337 num_orders = Order.count
338 num_customers = Customer.count
339 order = Order.create
340
341 customer = order.billing = order.shipping = Customer.new
342 assert order.save
343 assert_equal customer, order.billing
344 assert_equal customer, order.shipping
345
346 order.reload
347
348 customer = order.billing = order.shipping = Customer.new
349
350 assert order.save
351 order.reload
352
353 assert_equal customer, order.billing
354 assert_equal customer, order.shipping
355
356 assert_equal num_orders +1, Order.count
357 assert_equal num_customers +2, Customer.count
358 end
359
360
361 def test_association_assignment_sticks
362 post = Post.find(:first)
363
364 author1, author2 = Author.find(:all, :limit => 2)
365 assert_not_nil author1
366 assert_not_nil author2
367
368 # make sure the association is loaded
369 post.author
370
371 # set the association by id, directly
372 post.author_id = author2.id
373
374 # save and reload
375 post.save!
376 post.reload
377
378 # the author id of the post should be the id we set
379 assert_equal post.author_id, author2.id
380 end
381
382 def test_cant_save_readonly_association
383 assert_raise(ActiveRecord::ReadOnlyRecord) { companies(:first_client).readonly_firm.save! }
384 assert companies(:first_client).readonly_firm.readonly?
385 end
386
387 def test_polymorphic_assignment_foreign_type_field_updating
388 # should update when assigning a saved record
389 sponsor = Sponsor.new
390 member = Member.create
391 sponsor.sponsorable = member
392 assert_equal "Member", sponsor.sponsorable_type
393
394 # should update when assigning a new record
395 sponsor = Sponsor.new
396 member = Member.new
397 sponsor.sponsorable = member
398 assert_equal "Member", sponsor.sponsorable_type
399 end
400
401 def test_polymorphic_assignment_updates_foreign_id_field_for_new_and_saved_records
402 sponsor = Sponsor.new
403 saved_member = Member.create
404 new_member = Member.new
405
406 sponsor.sponsorable = saved_member
407 assert_equal saved_member.id, sponsor.sponsorable_id
408
409 sponsor.sponsorable = new_member
410 assert_equal nil, sponsor.sponsorable_id
411 end
412
413 def test_save_fails_for_invalid_belongs_to
414 assert log = AuditLog.create(:developer_id=>0,:message=>"")
415
416 log.developer = Developer.new
417 assert !log.developer.valid?
418 assert !log.valid?
419 assert !log.save
420 assert_equal "is invalid", log.errors.on("developer")
421 end
422
423 def test_save_succeeds_for_invalid_belongs_to_with_validate_false
424 assert log = AuditLog.create(:developer_id=>0,:message=>"")
425
426 log.unvalidated_developer = Developer.new
427 assert !log.unvalidated_developer.valid?
428 assert log.valid?
429 assert log.save
430 end
431
432 def test_belongs_to_proxy_should_not_respond_to_private_methods
433 assert_raises(NoMethodError) { companies(:first_firm).private_method }
434 assert_raises(NoMethodError) { companies(:second_client).firm.private_method }
435 end
436
437 def test_belongs_to_proxy_should_respond_to_private_methods_via_send
438 companies(:first_firm).send(:private_method)
439 companies(:second_client).firm.send(:private_method)
440 end
441 end