2 require 'models/developer'
3 require 'models/project'
4 require 'models/company'
7 require 'models/category'
9 require 'models/author'
10 require 'models/comment'
11 require 'models/person'
12 require 'models/reader'
14 class HasManyAssociationsTest
< ActiveRecord
::TestCase
15 fixtures
:accounts, :categories, :companies, :developers, :projects,
16 :developers_projects, :topics, :authors, :comments, :author_addresses,
17 :people, :posts, :readers
20 Client
.destroyed_client_ids
.clear
23 def force_signal37_to_load_all_clients_of_firm
24 companies(:first_firm).clients_of_firm
.each
{|f
| }
27 def test_counting_with_counter_sql
28 assert_equal
2, Firm
.find(:first).clients
.count
32 assert_equal
2, Firm
.find(:first).plain_clients
.count
35 def test_counting_with_empty_hash_conditions
36 assert_equal
2, Firm
.find(:first).plain_clients
.count(:conditions => {})
39 def test_counting_with_single_conditions
40 assert_equal
1, Firm
.find(:first).plain_clients
.count(:conditions => ['name=?', "Microsoft"])
43 def test_counting_with_single_hash
44 assert_equal
1, Firm
.find(:first).plain_clients
.count(:conditions => {:name => "Microsoft"})
47 def test_counting_with_column_name_and_hash
48 assert_equal
2, Firm
.find(:first).plain_clients
.count(:name)
51 def test_counting_with_association_limit
52 firm
= companies(:first_firm)
53 assert_equal firm
.limited_clients
.length
, firm
.limited_clients
.size
54 assert_equal firm
.limited_clients
.length
, firm
.limited_clients
.count
58 assert_equal
2, Firm
.find(:first).clients
.length
61 def test_find_with_blank_conditions
62 [[], {}, nil, ""].each
do |blank
|
63 assert_equal
2, Firm
.find(:first).clients
.find(:all, :conditions => blank
).size
67 def test_find_many_with_merged_options
68 assert_equal
1, companies(:first_firm).limited_clients
.size
69 assert_equal
1, companies(:first_firm).limited_clients
.find(:all).size
70 assert_equal
2, companies(:first_firm).limited_clients
.find(:all, :limit => nil).size
73 def test_dynamic_find_last_without_specified_order
74 assert_equal
companies(:second_client), companies(:first_firm).unsorted_clients
.find_last_by_type('Client')
77 def test_dynamic_find_should_respect_association_order
78 assert_equal
companies(:second_client), companies(:first_firm).clients_sorted_desc
.find(:first, :conditions => "type = 'Client'")
79 assert_equal
companies(:second_client), companies(:first_firm).clients_sorted_desc
.find_by_type('Client')
82 def test_dynamic_find_order_should_override_association_order
83 assert_equal
companies(:first_client), companies(:first_firm).clients_sorted_desc
.find(:first, :conditions => "type = 'Client'", :order => 'id')
84 assert_equal
companies(:first_client), companies(:first_firm).clients_sorted_desc
.find_by_type('Client', :order => 'id')
87 def test_dynamic_find_all_should_respect_association_order
88 assert_equal
[companies(:second_client), companies(:first_client)], companies(:first_firm).clients_sorted_desc
.find(:all, :conditions => "type = 'Client'")
89 assert_equal
[companies(:second_client), companies(:first_client)], companies(:first_firm).clients_sorted_desc
.find_all_by_type('Client')
92 def test_dynamic_find_all_order_should_override_association_order
93 assert_equal
[companies(:first_client), companies(:second_client)], companies(:first_firm).clients_sorted_desc
.find(:all, :conditions => "type = 'Client'", :order => 'id')
94 assert_equal
[companies(:first_client), companies(:second_client)], companies(:first_firm).clients_sorted_desc
.find_all_by_type('Client', :order => 'id')
97 def test_dynamic_find_all_should_respect_association_limit
98 assert_equal
1, companies(:first_firm).limited_clients
.find(:all, :conditions => "type = 'Client'").length
99 assert_equal
1, companies(:first_firm).limited_clients
.find_all_by_type('Client').length
102 def test_dynamic_find_all_limit_should_override_association_limit
103 assert_equal
2, companies(:first_firm).limited_clients
.find(:all, :conditions => "type = 'Client'", :limit => 9_000).length
104 assert_equal
2, companies(:first_firm).limited_clients
.find_all_by_type('Client', :limit => 9_000).length
107 def test_dynamic_find_all_should_respect_readonly_access
108 companies(:first_firm).readonly_clients
.find(:all).each
{ |c
| assert_raise(ActiveRecord
::ReadOnlyRecord) { c
.save
! } }
109 companies(:first_firm).readonly_clients
.find(:all).each
{ |c
| assert c
.readonly
? }
112 def test_cant_save_has_many_readonly_association
113 authors(:david).readonly_comments
.each
{ |c
| assert_raise(ActiveRecord
::ReadOnlyRecord) { c
.save
! } }
114 authors(:david).readonly_comments
.each
{ |c
| assert c
.readonly
? }
117 def test_triple_equality
118 assert
!(Array
=== Firm
.find(:first).clients
)
119 assert Firm
.find(:first).clients
=== Array
122 def test_finding_default_orders
123 assert_equal
"Summit", Firm
.find(:first).clients
.first
.name
126 def test_finding_with_different_class_name_and_order
127 assert_equal
"Microsoft", Firm
.find(:first).clients_sorted_desc
.first
.name
130 def test_finding_with_foreign_key
131 assert_equal
"Microsoft", Firm
.find(:first).clients_of_firm
.first
.name
134 def test_finding_with_condition
135 assert_equal
"Microsoft", Firm
.find(:first).clients_like_ms
.first
.name
138 def test_finding_with_condition_hash
139 assert_equal
"Microsoft", Firm
.find(:first).clients_like_ms_with_hash_conditions
.first
.name
142 def test_finding_using_primary_key
143 assert_equal
"Summit", Firm
.find(:first).clients_using_primary_key
.first
.name
146 def test_finding_using_sql
147 firm
= Firm
.find(:first)
148 first_client
= firm
.clients_using_sql
.first
149 assert_not_nil first_client
150 assert_equal
"Microsoft", first_client
.name
151 assert_equal
1, firm
.clients_using_sql
.size
152 assert_equal
1, Firm
.find(:first).clients_using_sql
.size
155 def test_counting_using_sql
156 assert_equal
1, Firm
.find(:first).clients_using_counter_sql
.size
157 assert Firm
.find(:first).clients_using_counter_sql
.any
?
158 assert_equal
0, Firm
.find(:first).clients_using_zero_counter_sql
.size
159 assert
!Firm
.find(:first).clients_using_zero_counter_sql
.any
?
162 def test_counting_non_existant_items_using_sql
163 assert_equal
0, Firm
.find(:first).no_clients_using_counter_sql
.size
166 def test_belongs_to_sanity
171 assert
false, "belongs_to failed if check"
176 assert
false, "belongs_to failed unless check"
181 firm
= Firm
.find(:first)
183 assert_raise(ActiveRecord
::RecordNotFound) { firm
.clients
.find
}
185 client
= firm
.clients
.find(2)
186 assert_kind_of Client
, client
188 client_ary
= firm
.clients
.find([2])
189 assert_kind_of Array
, client_ary
190 assert_equal client
, client_ary
.first
192 client_ary
= firm
.clients
.find(2, 3)
193 assert_kind_of Array
, client_ary
194 assert_equal
2, client_ary
.size
195 assert_equal client
, client_ary
.first
197 assert_raise(ActiveRecord
::RecordNotFound) { firm
.clients
.find(2, 99) }
200 def test_find_string_ids_when_using_finder_sql
201 firm
= Firm
.find(:first)
203 client
= firm
.clients_using_finder_sql
.find("2")
204 assert_kind_of Client
, client
206 client_ary
= firm
.clients_using_finder_sql
.find(["2"])
207 assert_kind_of Array
, client_ary
208 assert_equal client
, client_ary
.first
210 client_ary
= firm
.clients_using_finder_sql
.find("2", "3")
211 assert_kind_of Array
, client_ary
212 assert_equal
2, client_ary
.size
213 assert client_ary
.include?(client
)
217 firm
= Firm
.find(:first)
218 assert_equal
2, firm
.clients
.find(:all, :conditions => "#{QUOTED_TYPE} = 'Client'").length
219 assert_equal
1, firm
.clients
.find(:all, :conditions => "name = 'Summit'").length
223 firm
= companies(:first_firm)
225 assert
! firm
.clients
.loaded
?
228 firm
.clients
.find_each(:batch_size => 1) {|c
| assert_equal firm
.id
, c
.firm_id
}
231 assert
! firm
.clients
.loaded
?
234 def test_find_each_with_conditions
235 firm
= companies(:first_firm)
238 firm
.clients
.find_each(:batch_size => 1, :conditions => {:name => "Microsoft"}) do |c
|
239 assert_equal firm
.id
, c
.firm_id
240 assert_equal
"Microsoft", c
.name
244 assert
! firm
.clients
.loaded
?
247 def test_find_in_batches
248 firm
= companies(:first_firm)
250 assert
! firm
.clients
.loaded
?
253 firm
.clients
.find_in_batches(:batch_size => 2) do |clients
|
254 clients
.each
{|c
| assert_equal firm
.id
, c
.firm_id
}
258 assert
! firm
.clients
.loaded
?
261 def test_find_all_sanitized
262 firm
= Firm
.find(:first)
263 summit
= firm
.clients
.find(:all, :conditions => "name = 'Summit'")
264 assert_equal summit
, firm
.clients
.find(:all, :conditions => ["name = ?", "Summit"])
265 assert_equal summit
, firm
.clients
.find(:all, :conditions => ["name = :name", { :name => "Summit" }])
269 firm
= Firm
.find(:first)
270 client2
= Client
.find(2)
271 assert_equal firm
.clients
.first
, firm
.clients
.find(:first)
272 assert_equal client2
, firm
.clients
.find(:first, :conditions => "#{QUOTED_TYPE} = 'Client'")
275 def test_find_first_sanitized
276 firm
= Firm
.find(:first)
277 client2
= Client
.find(2)
278 assert_equal client2
, firm
.clients
.find(:first, :conditions => ["#{QUOTED_TYPE} = ?", 'Client'])
279 assert_equal client2
, firm
.clients
.find(:first, :conditions => ["#{QUOTED_TYPE} = :type", { :type => 'Client' }])
282 def test_find_in_collection
283 assert_equal Client
.find(2).name
, companies(:first_firm).clients
.find(2).name
284 assert_raise(ActiveRecord
::RecordNotFound) { companies(:first_firm).clients
.find(6) }
287 def test_find_grouped
288 all_clients_of_firm1
= Client
.find(:all, :conditions => "firm_id = 1")
289 grouped_clients_of_firm1
= Client
.find(:all, :conditions => "firm_id = 1", :group => "firm_id", :select => 'firm_id, count(id) as clients_count')
290 assert_equal
2, all_clients_of_firm1
.size
291 assert_equal
1, grouped_clients_of_firm1
.size
294 def test_find_scoped_grouped
295 assert_equal
1, companies(:first_firm).clients_grouped_by_firm_id
.size
296 assert_equal
1, companies(:first_firm).clients_grouped_by_firm_id
.length
297 assert_equal
2, companies(:first_firm).clients_grouped_by_name
.size
298 assert_equal
2, companies(:first_firm).clients_grouped_by_name
.length
301 def test_find_scoped_grouped_having
302 assert_equal
1, authors(:david).popular_grouped_posts
.length
303 assert_equal
0, authors(:mary).popular_grouped_posts
.length
307 force_signal37_to_load_all_clients_of_firm
308 natural
= Client
.new("name" => "Natural Company")
309 companies(:first_firm).clients_of_firm
<< natural
310 assert_equal
2, companies(:first_firm).clients_of_firm
.size
# checking via the collection
311 assert_equal
2, companies(:first_firm).clients_of_firm(true).size
# checking using the db
312 assert_equal natural
, companies(:first_firm).clients_of_firm
.last
315 def test_adding_using_create
316 first_firm
= companies(:first_firm)
317 assert_equal
2, first_firm
.plain_clients
.size
318 natural
= first_firm
.plain_clients
.create(:name => "Natural Company")
319 assert_equal
3, first_firm
.plain_clients
.length
320 assert_equal
3, first_firm
.plain_clients
.size
323 def test_create_with_bang_on_has_many_when_parent_is_new_raises
324 assert_raise(ActiveRecord
::RecordNotSaved) do
326 firm
.plain_clients
.create
! :name=>"Whoever"
330 def test_regular_create_on_has_many_when_parent_is_new_raises
331 assert_raise(ActiveRecord
::RecordNotSaved) do
333 firm
.plain_clients
.create
:name=>"Whoever"
337 def test_create_with_bang_on_has_many_raises_when_record_not_saved
338 assert_raise(ActiveRecord
::RecordInvalid) do
339 firm
= Firm
.find(:first)
340 firm
.plain_clients
.create
!
344 def test_create_with_bang_on_habtm_when_parent_is_new_raises
345 assert_raise(ActiveRecord
::RecordNotSaved) do
346 Developer
.new("name" => "Aredridel").projects
.create
!
350 def test_adding_a_mismatch_class
351 assert_raise(ActiveRecord
::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm
<< nil }
352 assert_raise(ActiveRecord
::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm
<< 1 }
353 assert_raise(ActiveRecord
::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm
<< Topic
.find(1) }
356 def test_adding_a_collection
357 force_signal37_to_load_all_clients_of_firm
358 companies(:first_firm).clients_of_firm
.concat([Client
.new("name" => "Natural Company"), Client
.new("name" => "Apple")])
359 assert_equal
3, companies(:first_firm).clients_of_firm
.size
360 assert_equal
3, companies(:first_firm).clients_of_firm(true).size
364 company
= companies(:first_firm)
365 new_client
= assert_no_queries
{ company
.clients_of_firm
.build("name" => "Another Client") }
366 assert
!company
.clients_of_firm
.loaded
?
368 assert_equal
"Another Client", new_client
.name
369 assert new_client
.new_record
?
370 assert_equal new_client
, company
.clients_of_firm
.last
373 def test_collection_size_after_building
374 company
= companies(:first_firm) # company already has one client
375 company
.clients_of_firm
.build("name" => "Another Client")
376 company
.clients_of_firm
.build("name" => "Yet Another Client")
377 assert_equal
3, company
.clients_of_firm
.size
380 def test_collection_size_twice_for_regressions
381 post
= posts(:thinking)
382 assert_equal
0, post
.readers
.size
383 # This test needs a post that has no readers, we assert it to ensure it holds,
384 # but need to reload the post because the very call to #size hides the bug.
387 size1
= post
.readers
.size
388 size2
= post
.readers
.size
389 assert_equal size1
, size2
393 company
= companies(:first_firm)
394 new_clients
= assert_no_queries
{ company
.clients_of_firm
.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) }
395 assert_equal
2, new_clients
.size
398 def test_build_followed_by_save_does_not_load_target
399 new_client
= companies(:first_firm).clients_of_firm
.build("name" => "Another Client")
400 assert
companies(:first_firm).save
401 assert
!companies(:first_firm).clients_of_firm
.loaded
?
404 def test_build_without_loading_association
405 first_topic
= topics(:first)
408 assert_equal
1, first_topic
.replies
.length
411 first_topic
.replies
.build(:title => "Not saved", :content => "Superstars")
412 assert_equal
2, first_topic
.replies
.size
415 assert_equal
2, first_topic
.replies
.to_ary
.size
418 def test_build_via_block
419 company
= companies(:first_firm)
420 new_client
= assert_no_queries
{ company
.clients_of_firm
.build
{|client
| client
.name
= "Another Client" } }
421 assert
!company
.clients_of_firm
.loaded
?
423 assert_equal
"Another Client", new_client
.name
424 assert new_client
.new_record
?
425 assert_equal new_client
, company
.clients_of_firm
.last
428 def test_build_many_via_block
429 company
= companies(:first_firm)
430 new_clients
= assert_no_queries
do
431 company
.clients_of_firm
.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) do |client
|
432 client
.name
= "changed"
436 assert_equal
2, new_clients
.size
437 assert_equal
"changed", new_clients
.first
.name
438 assert_equal
"changed", new_clients
.last
.name
441 def test_create_without_loading_association
442 first_firm
= companies(:first_firm)
446 assert_equal
1, first_firm
.clients_of_firm
.size
447 first_firm
.clients_of_firm
.reset
450 first_firm
.clients_of_firm
.create(:name => "Superstars")
453 assert_equal
2, first_firm
.clients_of_firm
.size
457 force_signal37_to_load_all_clients_of_firm
458 new_client
= companies(:first_firm).clients_of_firm
.create("name" => "Another Client")
459 assert
!new_client
.new_record
?
460 assert_equal new_client
, companies(:first_firm).clients_of_firm
.last
461 assert_equal new_client
, companies(:first_firm).clients_of_firm(true).last
465 companies(:first_firm).clients_of_firm
.create([{"name" => "Another Client"}, {"name" => "Another Client II"}])
466 assert_equal
3, companies(:first_firm).clients_of_firm(true).size
469 def test_create_followed_by_save_does_not_load_target
470 new_client
= companies(:first_firm).clients_of_firm
.create("name" => "Another Client")
471 assert
companies(:first_firm).save
472 assert
!companies(:first_firm).clients_of_firm
.loaded
?
475 def test_find_or_initialize
476 the_client
= companies(:first_firm).clients
.find_or_initialize_by_name("Yet another client")
477 assert_equal
companies(:first_firm).id
, the_client
.firm_id
478 assert_equal
"Yet another client", the_client
.name
479 assert the_client
.new_record
?
482 def test_find_or_create
483 number_of_clients
= companies(:first_firm).clients
.size
484 the_client
= companies(:first_firm).clients
.find_or_create_by_name("Yet another client")
485 assert_equal number_of_clients
+ 1, companies(:first_firm, :reload).clients
.size
486 assert_equal the_client
, companies(:first_firm).clients
.find_or_create_by_name("Yet another client")
487 assert_equal number_of_clients
+ 1, companies(:first_firm, :reload).clients
.size
491 force_signal37_to_load_all_clients_of_firm
492 companies(:first_firm).clients_of_firm
.delete(companies(:first_firm).clients_of_firm
.first
)
493 assert_equal
0, companies(:first_firm).clients_of_firm
.size
494 assert_equal
0, companies(:first_firm).clients_of_firm(true).size
497 def test_deleting_before_save
498 new_firm
= Firm
.new("name" => "A New Firm, Inc.")
499 new_client
= new_firm
.clients_of_firm
.build("name" => "Another Client")
500 assert_equal
1, new_firm
.clients_of_firm
.size
501 new_firm
.clients_of_firm
.delete(new_client
)
502 assert_equal
0, new_firm
.clients_of_firm
.size
505 def test_deleting_a_collection
506 force_signal37_to_load_all_clients_of_firm
507 companies(:first_firm).clients_of_firm
.create("name" => "Another Client")
508 assert_equal
2, companies(:first_firm).clients_of_firm
.size
509 companies(:first_firm).clients_of_firm
.delete([companies(:first_firm).clients_of_firm
[0], companies(:first_firm).clients_of_firm
[1]])
510 assert_equal
0, companies(:first_firm).clients_of_firm
.size
511 assert_equal
0, companies(:first_firm).clients_of_firm(true).size
515 force_signal37_to_load_all_clients_of_firm
516 companies(:first_firm).clients_of_firm
.create("name" => "Another Client")
517 assert_equal
2, companies(:first_firm).clients_of_firm
.size
518 companies(:first_firm).clients_of_firm
.delete_all
519 assert_equal
0, companies(:first_firm).clients_of_firm
.size
520 assert_equal
0, companies(:first_firm).clients_of_firm(true).size
523 def test_delete_all_with_not_yet_loaded_association_collection
524 force_signal37_to_load_all_clients_of_firm
525 companies(:first_firm).clients_of_firm
.create("name" => "Another Client")
526 assert_equal
2, companies(:first_firm).clients_of_firm
.size
527 companies(:first_firm).clients_of_firm
.reset
528 companies(:first_firm).clients_of_firm
.delete_all
529 assert_equal
0, companies(:first_firm).clients_of_firm
.size
530 assert_equal
0, companies(:first_firm).clients_of_firm(true).size
533 def test_clearing_an_association_collection
534 firm
= companies(:first_firm)
535 client_id
= firm
.clients_of_firm
.first
.id
536 assert_equal
1, firm
.clients_of_firm
.size
538 firm
.clients_of_firm
.clear
540 assert_equal
0, firm
.clients_of_firm
.size
541 assert_equal
0, firm
.clients_of_firm(true).size
542 assert_equal
[], Client
.destroyed_client_ids
[firm
.id
]
544 # Should not be destroyed since the association is not dependent.
545 assert_nothing_raised
do
546 assert Client
.find(client_id
).firm
.nil?
550 def test_clearing_a_dependent_association_collection
551 firm
= companies(:first_firm)
552 client_id
= firm
.dependent_clients_of_firm
.first
.id
553 assert_equal
1, firm
.dependent_clients_of_firm
.size
555 # :dependent means destroy is called on each client
556 firm
.dependent_clients_of_firm
.clear
558 assert_equal
0, firm
.dependent_clients_of_firm
.size
559 assert_equal
0, firm
.dependent_clients_of_firm(true).size
560 assert_equal
[client_id
], Client
.destroyed_client_ids
[firm
.id
]
562 # Should be destroyed since the association is dependent.
563 assert Client
.find_by_id(client_id
).nil?
566 def test_clearing_an_exclusively_dependent_association_collection
567 firm
= companies(:first_firm)
568 client_id
= firm
.exclusively_dependent_clients_of_firm
.first
.id
569 assert_equal
1, firm
.exclusively_dependent_clients_of_firm
.size
571 assert_equal
[], Client
.destroyed_client_ids
[firm
.id
]
573 # :exclusively_dependent means each client is deleted directly from
574 # the database without looping through them calling destroy.
575 firm
.exclusively_dependent_clients_of_firm
.clear
577 assert_equal
0, firm
.exclusively_dependent_clients_of_firm
.size
578 assert_equal
0, firm
.exclusively_dependent_clients_of_firm(true).size
579 # no destroy-filters should have been called
580 assert_equal
[], Client
.destroyed_client_ids
[firm
.id
]
582 # Should be destroyed since the association is exclusively dependent.
583 assert Client
.find_by_id(client_id
).nil?
586 def test_dependent_association_respects_optional_conditions_on_delete
587 firm
= companies(:odegy)
588 Client
.create(:client_of => firm
.id
, :name => "BigShot Inc.")
589 Client
.create(:client_of => firm
.id
, :name => "SmallTime Inc.")
590 # only one of two clients is included in the association due to the :conditions key
591 assert_equal
2, Client
.find_all_by_client_of(firm
.id
).size
592 assert_equal
1, firm
.dependent_conditional_clients_of_firm
.size
594 # only the correctly associated client should have been deleted
595 assert_equal
1, Client
.find_all_by_client_of(firm
.id
).size
598 def test_dependent_association_respects_optional_sanitized_conditions_on_delete
599 firm
= companies(:odegy)
600 Client
.create(:client_of => firm
.id
, :name => "BigShot Inc.")
601 Client
.create(:client_of => firm
.id
, :name => "SmallTime Inc.")
602 # only one of two clients is included in the association due to the :conditions key
603 assert_equal
2, Client
.find_all_by_client_of(firm
.id
).size
604 assert_equal
1, firm
.dependent_sanitized_conditional_clients_of_firm
.size
606 # only the correctly associated client should have been deleted
607 assert_equal
1, Client
.find_all_by_client_of(firm
.id
).size
610 def test_dependent_association_respects_optional_hash_conditions_on_delete
611 firm
= companies(:odegy)
612 Client
.create(:client_of => firm
.id
, :name => "BigShot Inc.")
613 Client
.create(:client_of => firm
.id
, :name => "SmallTime Inc.")
614 # only one of two clients is included in the association due to the :conditions key
615 assert_equal
2, Client
.find_all_by_client_of(firm
.id
).size
616 assert_equal
1, firm
.dependent_sanitized_conditional_clients_of_firm
.size
618 # only the correctly associated client should have been deleted
619 assert_equal
1, Client
.find_all_by_client_of(firm
.id
).size
623 def test_creation_respects_hash_condition
624 ms_client
= companies(:first_firm).clients_like_ms_with_hash_conditions
.build
626 assert ms_client
.save
627 assert_equal
'Microsoft', ms_client
.name
629 another_ms_client
= companies(:first_firm).clients_like_ms_with_hash_conditions
.create
631 assert
!another_ms_client
.new_record
?
632 assert_equal
'Microsoft', another_ms_client
.name
635 def test_dependent_delete_and_destroy_with_belongs_to
636 author_address
= author_addresses(:david_address)
637 assert_equal
[], AuthorAddress
.destroyed_author_address_ids
[authors(:david).id
]
639 assert_difference
"AuthorAddress.count", -2 do
640 authors(:david).destroy
643 assert_equal
nil, AuthorAddress
.find_by_id(authors(:david).author_address_id
)
644 assert_equal
nil, AuthorAddress
.find_by_id(authors(:david).author_address_extra_id
)
647 def test_invalid_belongs_to_dependent_option_raises_exception
648 assert_raise ArgumentError
do
649 Author
.belongs_to
:special_author_address, :dependent => :nullify
653 def test_clearing_without_initial_access
654 firm
= companies(:first_firm)
656 firm
.clients_of_firm
.clear
658 assert_equal
0, firm
.clients_of_firm
.size
659 assert_equal
0, firm
.clients_of_firm(true).size
662 def test_deleting_a_item_which_is_not_in_the_collection
663 force_signal37_to_load_all_clients_of_firm
664 summit
= Client
.find_by_name('Summit')
665 companies(:first_firm).clients_of_firm
.delete(summit
)
666 assert_equal
1, companies(:first_firm).clients_of_firm
.size
667 assert_equal
1, companies(:first_firm).clients_of_firm(true).size
668 assert_equal
2, summit
.client_of
671 def test_deleting_type_mismatch
672 david
= Developer
.find(1)
673 david
.projects
.reload
674 assert_raise(ActiveRecord
::AssociationTypeMismatch) { david
.projects
.delete(1) }
677 def test_deleting_self_type_mismatch
678 david
= Developer
.find(1)
679 david
.projects
.reload
680 assert_raise(ActiveRecord
::AssociationTypeMismatch) { david
.projects
.delete(Project
.find(1).developers
) }
684 force_signal37_to_load_all_clients_of_firm
686 assert_difference
"Client.count", -1 do
687 companies(:first_firm).clients_of_firm
.destroy(companies(:first_firm).clients_of_firm
.first
)
690 assert_equal
0, companies(:first_firm).reload
.clients_of_firm
.size
691 assert_equal
0, companies(:first_firm).clients_of_firm(true).size
694 def test_destroying_a_collection
695 force_signal37_to_load_all_clients_of_firm
696 companies(:first_firm).clients_of_firm
.create("name" => "Another Client")
697 assert_equal
2, companies(:first_firm).clients_of_firm
.size
699 assert_difference
"Client.count", -2 do
700 companies(:first_firm).clients_of_firm
.destroy([companies(:first_firm).clients_of_firm
[0], companies(:first_firm).clients_of_firm
[1]])
703 assert_equal
0, companies(:first_firm).reload
.clients_of_firm
.size
704 assert_equal
0, companies(:first_firm).clients_of_firm(true).size
708 force_signal37_to_load_all_clients_of_firm
709 assert
!companies(:first_firm).clients_of_firm
.empty
?, "37signals has clients after load"
710 companies(:first_firm).clients_of_firm
.destroy_all
711 assert
companies(:first_firm).clients_of_firm
.empty
?, "37signals has no clients after destroy all"
712 assert
companies(:first_firm).clients_of_firm(true).empty
?, "37signals has no clients after destroy all and refresh"
716 firm
= companies(:first_firm)
717 assert_equal
2, firm
.clients
.size
719 assert Client
.find(:all, :conditions => "firm_id=#{firm.id}").empty
?
722 def test_destroy_dependent_when_deleted_from_association
723 firm
= Firm
.find(:first)
724 assert_equal
2, firm
.clients
.size
726 client
= firm
.clients
.first
727 firm
.clients
.delete(client
)
729 assert_raise(ActiveRecord
::RecordNotFound) { Client
.find(client
.id
) }
730 assert_raise(ActiveRecord
::RecordNotFound) { firm
.clients
.find(client
.id
) }
731 assert_equal
1, firm
.clients
.size
734 def test_three_levels_of_dependence
735 topic
= Topic
.create
"title" => "neat and simple"
736 reply
= topic
.replies
.create
"title" => "neat and simple", "content" => "still digging it"
737 silly_reply
= reply
.replies
.create
"title" => "neat and simple", "content" => "ain't complaining"
739 assert_nothing_raised
{ topic
.destroy
}
742 uses_transaction
:test_dependence_with_transaction_support_on_failure
743 def test_dependence_with_transaction_support_on_failure
744 firm
= companies(:first_firm)
745 clients
= firm
.clients
746 assert_equal
2, clients
.length
747 clients
.last
.instance_eval
{ def before_destroy() raise "Trigger rollback" end }
749 firm
.destroy
rescue "do nothing"
751 assert_equal
2, Client
.find(:all, :conditions => "firm_id=#{firm.id}").size
754 def test_dependence_on_account
755 num_accounts
= Account
.count
756 companies(:first_firm).destroy
757 assert_equal num_accounts
- 1, Account
.count
760 def test_depends_and_nullify
761 num_accounts
= Account
.count
762 num_companies
= Company
.count
764 core
= companies(:rails_core)
765 assert_equal
accounts(:rails_core_account), core
.account
766 assert_equal
companies(:leetsoft, :jadedpixel), core
.companies
768 assert_nil
accounts(:rails_core_account).reload
.firm_id
769 assert_nil
companies(:leetsoft).reload
.client_of
770 assert_nil
companies(:jadedpixel).reload
.client_of
773 assert_equal num_accounts
, Account
.count
776 def test_included_in_collection
777 assert
companies(:first_firm).clients
.include?(Client
.find(2))
780 def test_adding_array_and_collection
781 assert_nothing_raised
{ Firm
.find(:first).clients
+ Firm
.find(:all).last
.clients
}
784 def test_find_all_without_conditions
785 firm
= companies(:first_firm)
786 assert_equal
2, firm
.clients
.find(:all).length
789 def test_replace_with_less
790 firm
= Firm
.find(:first)
791 firm
.clients
= [companies(:first_client)]
792 assert firm
.save
, "Could not save firm"
794 assert_equal
1, firm
.clients
.length
797 def test_replace_with_less_and_dependent_nullify
798 num_companies
= Company
.count
799 companies(:rails_core).companies
= []
800 assert_equal num_companies
, Company
.count
803 def test_replace_with_new
804 firm
= Firm
.find(:first)
805 firm
.clients
= [companies(:second_client), Client
.new("name" => "New Client")]
808 assert_equal
2, firm
.clients
.length
809 assert
!firm
.clients
.include?(:first_client)
813 assert_equal
[companies(:first_client).id
, companies(:second_client).id
], companies(:first_firm).client_ids
816 def test_get_ids_for_loaded_associations
817 company
= companies(:first_firm)
818 company
.clients(true)
825 def test_get_ids_for_unloaded_associations_does_not_load_them
826 company
= companies(:first_firm)
827 assert
!company
.clients
.loaded
?
828 assert_equal
[companies(:first_client).id
, companies(:second_client).id
], company
.client_ids
829 assert
!company
.clients
.loaded
?
832 def test_get_ids_for_unloaded_finder_sql_associations_loads_them
833 company
= companies(:first_firm)
834 assert
!company
.clients_using_sql
.loaded
?
835 assert_equal
[companies(:second_client).id
], company
.clients_using_sql_ids
836 assert company
.clients_using_sql
.loaded
?
839 def test_assign_ids_ignoring_blanks
840 firm
= Firm
.create
!(:name => 'Apple')
841 firm
.client_ids
= [companies(:first_client).id
, nil, companies(:second_client).id
, '']
844 assert_equal
2, firm
.clients(true).size
845 assert firm
.clients
.include?(companies(:second_client))
848 def test_get_ids_for_through
849 assert_equal
[comments(:eager_other_comment1).id
], authors(:mary).comment_ids
852 def test_modifying_a_through_a_has_many_should_raise
854 lambda
{ authors(:mary).comment_ids
= [comments(:greetings).id
, comments(:more_greetings).id
] },
855 lambda
{ authors(:mary).comments
= [comments(:greetings), comments(:more_greetings)] },
856 lambda
{ authors(:mary).comments
<< Comment
.create
!(:body => "Yay", :post_id => 424242) },
857 lambda
{ authors(:mary).comments
.delete(authors(:mary).comments
.first
) },
858 ].each
{|block
| assert_raise(ActiveRecord
::HasManyThroughCantAssociateThroughHasManyReflection, &block
) }
861 def test_dynamic_find_should_respect_association_order_for_through
862 assert_equal Comment
.find(10), authors(:david).comments_desc
.find(:first, :conditions => "comments.type = 'SpecialComment'")
863 assert_equal Comment
.find(10), authors(:david).comments_desc
.find_by_type('SpecialComment')
866 def test_dynamic_find_order_should_override_association_order_for_through
867 assert_equal Comment
.find(3), authors(:david).comments_desc
.find(:first, :conditions => "comments.type = 'SpecialComment'", :order => 'comments.id')
868 assert_equal Comment
.find(3), authors(:david).comments_desc
.find_by_type('SpecialComment', :order => 'comments.id')
871 def test_dynamic_find_all_should_respect_association_order_for_through
872 assert_equal
[Comment
.find(10), Comment
.find(7), Comment
.find(6), Comment
.find(3)], authors(:david).comments_desc
.find(:all, :conditions => "comments.type = 'SpecialComment'")
873 assert_equal
[Comment
.find(10), Comment
.find(7), Comment
.find(6), Comment
.find(3)], authors(:david).comments_desc
.find_all_by_type('SpecialComment')
876 def test_dynamic_find_all_order_should_override_association_order_for_through
877 assert_equal
[Comment
.find(3), Comment
.find(6), Comment
.find(7), Comment
.find(10)], authors(:david).comments_desc
.find(:all, :conditions => "comments.type = 'SpecialComment'", :order => 'comments.id')
878 assert_equal
[Comment
.find(3), Comment
.find(6), Comment
.find(7), Comment
.find(10)], authors(:david).comments_desc
.find_all_by_type('SpecialComment', :order => 'comments.id')
881 def test_dynamic_find_all_should_respect_association_limit_for_through
882 assert_equal
1, authors(:david).limited_comments
.find(:all, :conditions => "comments.type = 'SpecialComment'").length
883 assert_equal
1, authors(:david).limited_comments
.find_all_by_type('SpecialComment').length
886 def test_dynamic_find_all_order_should_override_association_limit_for_through
887 assert_equal
4, authors(:david).limited_comments
.find(:all, :conditions => "comments.type = 'SpecialComment'", :limit => 9_000).length
888 assert_equal
4, authors(:david).limited_comments
.find_all_by_type('SpecialComment', :limit => 9_000).length
891 def test_find_all_include_over_the_same_table_for_through
892 assert_equal
2, people(:michael).posts
.find(:all, :include => :people).length
895 def test_has_many_through_respects_hash_conditions
896 assert_equal
authors(:david).hello_posts
, authors(:david).hello_posts_with_hash_conditions
897 assert_equal
authors(:david).hello_post_comments
, authors(:david).hello_post_comments_with_hash_conditions
900 def test_include_uses_array_include_after_loaded
901 firm
= companies(:first_firm)
902 firm
.clients
.class # force load target
904 client
= firm
.clients
.first
907 assert firm
.clients
.loaded
?
908 assert firm
.clients
.include?(client
)
912 def test_include_checks_if_record_exists_if_target_not_loaded
913 firm
= companies(:first_firm)
914 client
= firm
.clients
.first
917 assert
! firm
.clients
.loaded
?
919 assert firm
.clients
.include?(client
)
921 assert
! firm
.clients
.loaded
?
924 def test_include_loads_collection_if_target_uses_finder_sql
925 firm
= companies(:first_firm)
926 client
= firm
.clients_using_sql
.first
929 assert
! firm
.clients_using_sql
.loaded
?
930 assert firm
.clients_using_sql
.include?(client
)
931 assert firm
.clients_using_sql
.loaded
?
935 def test_include_returns_false_for_non_matching_record_to_verify_scoping
936 firm
= companies(:first_firm)
937 client
= Client
.create
!(:name => 'Not Associated')
939 assert
! firm
.clients
.loaded
?
940 assert
! firm
.clients
.include?(client
)
943 def test_calling_first_or_last_on_association_should_not_load_association
944 firm
= companies(:first_firm)
947 assert
!firm
.clients
.loaded
?
950 def test_calling_first_or_last_on_loaded_association_should_not_fetch_with_query
951 firm
= companies(:first_firm)
952 firm
.clients
.class # force load target
953 assert firm
.clients
.loaded
?
957 assert_equal
2, firm
.clients
.first(2).size
959 assert_equal
2, firm
.clients
.last(2).size
963 def test_calling_first_or_last_on_existing_record_with_build_should_load_association
964 firm
= companies(:first_firm)
965 firm
.clients
.build(:name => 'Foo')
966 assert
!firm
.clients
.loaded
?
973 assert firm
.clients
.loaded
?
976 def test_calling_first_or_last_on_existing_record_with_create_should_not_load_association
977 firm
= companies(:first_firm)
978 firm
.clients
.create(:name => 'Foo')
979 assert
!firm
.clients
.loaded
?
986 assert
!firm
.clients
.loaded
?
989 def test_calling_first_or_last_on_new_record_should_not_run_queries
998 def test_calling_first_or_last_with_find_options_on_loaded_association_should_fetch_with_query
999 firm
= companies(:first_firm)
1000 firm
.clients
.class # force load target
1003 assert firm
.clients
.loaded
?
1004 firm
.clients
.first(:order => 'name')
1005 firm
.clients
.last(:order => 'name')
1009 def test_calling_first_or_last_with_integer_on_association_should_load_association
1010 firm
= companies(:first_firm)
1013 firm
.clients
.first(2)
1014 firm
.clients
.last(2)
1017 assert firm
.clients
.loaded
?
1020 def test_joins_with_namespaced_model_should_use_correct_type
1021 old
= ActiveRecord
::Base.store_full_sti_class
1022 ActiveRecord
::Base.store_full_sti_class
= true
1024 firm
= Namespaced
::Firm.create({ :name => 'Some Company' })
1025 firm
.clients
.create({ :name => 'Some Client' })
1027 stats
= Namespaced
::Firm.find(firm
.id
, {
1028 :select => "#{Namespaced::Firm.table_name}.id, COUNT(#{Namespaced::Client.table_name}.id) AS num_clients",
1030 :group => "#{Namespaced::Firm.table_name}.id"
1032 assert_equal
1, stats
.num_clients
.to_i
1035 ActiveRecord
::Base.store_full_sti_class
= old
1038 def test_association_proxy_transaction_method_starts_transaction_in_association_class
1039 Comment
.expects(:transaction)
1040 Post
.find(:first).comments
.transaction
do
1045 def test_sending_new_to_association_proxy_should_have_same_effect_as_calling_new
1046 client_association
= companies(:first_firm).clients
1047 assert_equal client_association
.new
.attributes
, client_association
.send(:new).attributes
1050 def test_respond_to_private_class_methods
1051 client_association
= companies(:first_firm).clients
1052 assert
!client_association
.respond_to
?(:private_method)
1053 assert client_association
.respond_to
?(:private_method, true)
1056 def test_creating_using_primary_key
1057 firm
= Firm
.find(:first)
1058 client
= firm
.clients_using_primary_key
.create
!(:name => 'test')
1059 assert_equal firm
.name
, client
.firm_name