Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 9233

Show
Ignore:
Timestamp:
04/06/08 03:01:09 (2 years ago)
Author:
pratik
Message:

Split associations_test.rb into multiple files based on association type. [Pratik]

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/activerecord/test/cases/associations_test.rb

    r9232 r9233  
    180180end 
    181181 
    182 class HasOneAssociationsTest < ActiveRecord::TestCase 
    183   fixtures :accounts, :companies, :developers, :projects, :developers_projects 
    184  
    185   def setup 
    186     Account.destroyed_account_ids.clear 
    187   end 
    188  
    189   def test_has_one 
    190     assert_equal companies(:first_firm).account, Account.find(1) 
    191     assert_equal Account.find(1).credit_limit, companies(:first_firm).account.credit_limit 
    192   end 
    193    
    194   def test_has_one_cache_nils 
    195     firm = companies(:another_firm) 
    196     assert_queries(1) { assert_nil firm.account } 
    197     assert_queries(0) { assert_nil firm.account } 
    198  
    199     firms = Firm.find(:all, :include => :account) 
    200     assert_queries(0) { firms.each(&:account) } 
    201   end 
    202  
    203   def test_can_marshal_has_one_association_with_nil_target 
    204     firm = Firm.new 
    205     assert_nothing_raised do 
    206       assert_equal firm.attributes, Marshal.load(Marshal.dump(firm)).attributes 
    207     end 
    208  
    209     firm.account 
    210     assert_nothing_raised do 
    211       assert_equal firm.attributes, Marshal.load(Marshal.dump(firm)).attributes 
    212     end 
    213   end 
    214  
    215   def test_proxy_assignment 
    216     company = companies(:first_firm) 
    217     assert_nothing_raised { company.account = company.account } 
    218   end 
    219  
    220   def test_triple_equality 
    221     assert Account === companies(:first_firm).account 
    222     assert companies(:first_firm).account === Account 
    223   end 
    224  
    225   def test_type_mismatch 
    226     assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).account = 1 } 
    227     assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).account = Project.find(1) } 
    228   end 
    229  
    230   def test_natural_assignment 
    231     apple = Firm.create("name" => "Apple") 
    232     citibank = Account.create("credit_limit" => 10) 
    233     apple.account = citibank 
    234     assert_equal apple.id, citibank.firm_id 
    235   end 
    236  
    237   def test_natural_assignment_to_nil 
    238     old_account_id = companies(:first_firm).account.id 
    239     companies(:first_firm).account = nil 
    240     companies(:first_firm).save 
    241     assert_nil companies(:first_firm).account 
    242     # account is dependent, therefore is destroyed when reference to owner is lost 
    243     assert_raises(ActiveRecord::RecordNotFound) { Account.find(old_account_id) } 
    244   end 
    245  
    246   def test_assignment_without_replacement 
    247     apple = Firm.create("name" => "Apple") 
    248     citibank = Account.create("credit_limit" => 10) 
    249     apple.account = citibank 
    250     assert_equal apple.id, citibank.firm_id 
    251  
    252     hsbc = apple.build_account({ :credit_limit => 20}, false) 
    253     assert_equal apple.id, hsbc.firm_id 
    254     hsbc.save 
    255     assert_equal apple.id, citibank.firm_id 
    256  
    257     nykredit = apple.create_account({ :credit_limit => 30}, false) 
    258     assert_equal apple.id, nykredit.firm_id 
    259     assert_equal apple.id, citibank.firm_id 
    260     assert_equal apple.id, hsbc.firm_id 
    261   end 
    262  
    263   def test_assignment_without_replacement_on_create 
    264     apple = Firm.create("name" => "Apple") 
    265     citibank = Account.create("credit_limit" => 10) 
    266     apple.account = citibank 
    267     assert_equal apple.id, citibank.firm_id 
    268  
    269     hsbc = apple.create_account({:credit_limit => 10}, false) 
    270     assert_equal apple.id, hsbc.firm_id 
    271     hsbc.save 
    272     assert_equal apple.id, citibank.firm_id 
    273   end 
    274  
    275   def test_dependence 
    276     num_accounts = Account.count 
    277  
    278     firm = Firm.find(1) 
    279     assert !firm.account.nil? 
    280     account_id = firm.account.id 
    281     assert_equal [], Account.destroyed_account_ids[firm.id] 
    282  
    283     firm.destroy 
    284     assert_equal num_accounts - 1, Account.count 
    285     assert_equal [account_id], Account.destroyed_account_ids[firm.id] 
    286   end 
    287  
    288   def test_exclusive_dependence 
    289     num_accounts = Account.count 
    290  
    291     firm = ExclusivelyDependentFirm.find(9) 
    292     assert !firm.account.nil? 
    293     account_id = firm.account.id 
    294     assert_equal [], Account.destroyed_account_ids[firm.id] 
    295  
    296     firm.destroy 
    297     assert_equal num_accounts - 1, Account.count 
    298     assert_equal [], Account.destroyed_account_ids[firm.id] 
    299   end 
    300  
    301   def test_dependence_with_nil_associate 
    302     firm = DependentFirm.new(:name => 'nullify') 
    303     firm.save! 
    304     assert_nothing_raised { firm.destroy } 
    305   end 
    306  
    307   def test_succesful_build_association 
    308     firm = Firm.new("name" => "GlobalMegaCorp") 
    309     firm.save 
    310  
    311     account = firm.build_account("credit_limit" => 1000) 
    312     assert account.save 
    313     assert_equal account, firm.account 
    314   end 
    315  
    316   def test_failing_build_association 
    317     firm = Firm.new("name" => "GlobalMegaCorp") 
    318     firm.save 
    319  
    320     account = firm.build_account 
    321     assert !account.save 
    322     assert_equal "can't be empty", account.errors.on("credit_limit") 
    323   end 
    324  
    325   def test_build_association_twice_without_saving_affects_nothing 
    326     count_of_account = Account.count 
    327     firm = Firm.find(:first) 
    328     account1 = firm.build_account("credit_limit" => 1000) 
    329     account2 = firm.build_account("credit_limit" => 2000) 
    330  
    331     assert_equal count_of_account, Account.count 
    332   end 
    333  
    334   def test_create_association 
    335     firm = Firm.create(:name => "GlobalMegaCorp") 
    336     account = firm.create_account(:credit_limit => 1000) 
    337     assert_equal account, firm.reload.account 
    338   end 
    339  
    340   def test_build 
    341     firm = Firm.new("name" => "GlobalMegaCorp") 
    342     firm.save 
    343  
    344     firm.account = account = Account.new("credit_limit" => 1000) 
    345     assert_equal account, firm.account 
    346     assert account.save 
    347     assert_equal account, firm.account 
    348   end 
    349  
    350   def test_build_before_child_saved 
    351     firm = Firm.find(1) 
    352  
    353     account = firm.account.build("credit_limit" => 1000) 
    354     assert_equal account, firm.account 
    355     assert account.new_record? 
    356     assert firm.save 
    357     assert_equal account, firm.account 
    358     assert !account.new_record? 
    359   end 
    360  
    361   def test_build_before_either_saved 
    362     firm = Firm.new("name" => "GlobalMegaCorp") 
    363  
    364     firm.account = account = Account.new("credit_limit" => 1000) 
    365     assert_equal account, firm.account 
    366     assert account.new_record? 
    367     assert firm.save 
    368     assert_equal account, firm.account 
    369     assert !account.new_record? 
    370   end 
    371  
    372   def test_failing_build_association 
    373     firm = Firm.new("name" => "GlobalMegaCorp") 
    374     firm.save 
    375  
    376     firm.account = account = Account.new 
    377     assert_equal account, firm.account 
    378     assert !account.save 
    379     assert_equal account, firm.account 
    380     assert_equal "can't be empty", account.errors.on("credit_limit") 
    381   end 
    382  
    383   def test_create 
    384     firm = Firm.new("name" => "GlobalMegaCorp") 
    385     firm.save 
    386     firm.account = account = Account.create("credit_limit" => 1000) 
    387     assert_equal account, firm.account 
    388   end 
    389  
    390   def test_create_before_save 
    391     firm = Firm.new("name" => "GlobalMegaCorp") 
    392     firm.account = account = Account.create("credit_limit" => 1000) 
    393     assert_equal account, firm.account 
    394   end 
    395  
    396   def test_dependence_with_missing_association 
    397     Account.destroy_all 
    398     firm = Firm.find(1) 
    399     assert firm.account.nil? 
    400     firm.destroy 
    401   end 
    402  
    403   def test_dependence_with_missing_association_and_nullify 
    404     Account.destroy_all 
    405     firm = DependentFirm.find(:first) 
    406     assert firm.account.nil? 
    407     firm.destroy 
    408   end 
    409  
    410   def test_assignment_before_parent_saved 
    411     firm = Firm.new("name" => "GlobalMegaCorp") 
    412     firm.account = a = Account.find(1) 
    413     assert firm.new_record? 
    414     assert_equal a, firm.account 
    415     assert firm.save 
    416     assert_equal a, firm.account 
    417     assert_equal a, firm.account(true) 
    418   end 
    419  
    420   def test_finding_with_interpolated_condition 
    421     firm = Firm.find(:first) 
    422     superior = firm.clients.create(:name => 'SuperiorCo') 
    423     superior.rating = 10 
    424     superior.save 
    425     assert_equal 10, firm.clients_with_interpolated_conditions.first.rating 
    426   end 
    427  
    428   def test_assignment_before_child_saved 
    429     firm = Firm.find(1) 
    430     firm.account = a = Account.new("credit_limit" => 1000) 
    431     assert !a.new_record? 
    432     assert_equal a, firm.account 
    433     assert_equal a, firm.account 
    434     assert_equal a, firm.account(true) 
    435   end 
    436    
    437   def test_save_fails_for_invalid_has_one 
    438     firm = Firm.find(:first) 
    439     assert firm.valid? 
    440      
    441     firm.account = Account.new 
    442      
    443     assert !firm.account.valid? 
    444     assert !firm.valid? 
    445     assert !firm.save 
    446     assert_equal "is invalid", firm.errors.on("account") 
    447   end 
    448  
    449   def test_assignment_before_either_saved 
    450     firm = Firm.new("name" => "GlobalMegaCorp") 
    451     firm.account = a = Account.new("credit_limit" => 1000) 
    452     assert firm.new_record? 
    453     assert a.new_record? 
    454     assert_equal a, firm.account 
    455     assert firm.save 
    456     assert !firm.new_record? 
    457     assert !a.new_record? 
    458     assert_equal a, firm.account 
    459     assert_equal a, firm.account(true) 
    460   end 
    461  
    462   def test_not_resaved_when_unchanged 
    463     firm = Firm.find(:first, :include => :account) 
    464     firm.name += '-changed' 
    465     assert_queries(1) { firm.save! } 
    466  
    467     firm = Firm.find(:first) 
    468     firm.account = Account.find(:first) 
    469     assert_queries(Firm.partial_updates? ? 0 : 1) { firm.save! } 
    470  
    471     firm = Firm.find(:first).clone 
    472     firm.account = Account.find(:first) 
    473     assert_queries(2) { firm.save! } 
    474  
    475     firm = Firm.find(:first).clone 
    476     firm.account = Account.find(:first).clone 
    477     assert_queries(2) { firm.save! } 
    478   end 
    479  
    480   def test_save_still_works_after_accessing_nil_has_one 
    481     jp = Company.new :name => 'Jaded Pixel' 
    482     jp.dummy_account.nil? 
    483  
    484     assert_nothing_raised do 
    485       jp.save! 
    486     end 
    487   end 
    488  
    489   def test_cant_save_readonly_association 
    490     assert_raise(ActiveRecord::ReadOnlyRecord) { companies(:first_firm).readonly_account.save!  } 
    491     assert companies(:first_firm).readonly_account.readonly? 
    492   end 
    493  
    494 end 
    495  
    496 class HasOneThroughAssociationsTest < ActiveRecord::TestCase 
    497   fixtures :members, :clubs, :memberships, :sponsors 
    498    
    499   def setup 
    500     @member = members(:groucho) 
    501   end 
    502  
    503   def test_has_one_through_with_has_one 
    504     assert_equal clubs(:boring_club), @member.club 
    505   end 
    506  
    507   def test_has_one_through_with_has_many 
    508     assert_equal clubs(:moustache_club), @member.favourite_club 
    509   end 
    510    
    511   def test_creating_association_creates_through_record 
    512     new_member = Member.create(:name => "Chris") 
    513     new_member.club = Club.create(:name => "LRUG") 
    514     assert_not_nil new_member.current_membership 
    515     assert_not_nil new_member.club 
    516   end 
    517    
    518   def test_replace_target_record 
    519     new_club = Club.create(:name => "Marx Bros") 
    520     @member.club = new_club 
    521     @member.reload 
    522     assert_equal new_club, @member.club 
    523   end 
    524    
    525   def test_replacing_target_record_deletes_old_association 
    526     assert_no_difference "Membership.count" do 
    527       new_club = Club.create(:name => "Bananarama") 
    528       @member.club = new_club 
    529       @member.reload       
    530     end 
    531   end 
    532    
    533   def test_has_one_through_polymorphic 
    534     assert_equal clubs(:moustache_club), @member.sponsor_club 
    535   end 
    536    
    537   def has_one_through_to_has_many 
    538     assert_equal 2, @member.fellow_members.size 
    539   end 
    540    
    541   def test_has_one_through_eager_loading 
    542     members = Member.find(:all, :include => :club, :conditions => ["name = ?", "Groucho Marx"]) 
    543     assert_equal 1, members.size 
    544     assert_not_nil assert_no_queries {members[0].club} 
    545   end 
    546    
    547   def test_has_one_through_eager_loading_through_polymorphic 
    548     members = Member.find(:all, :include => :sponsor_club, :conditions => ["name = ?", "Groucho Marx"]) 
    549     assert_equal 1, members.size 
    550     assert_not_nil assert_no_queries {members[0].sponsor_club}     
    551   end 
    552  
    553   def test_has_one_through_polymorphic_with_source_type 
    554     assert_equal members(:groucho), clubs(:moustache_club).sponsored_member 
    555   end 
    556  
    557   def test_eager_has_one_through_polymorphic_with_source_type 
    558     clubs = Club.find(:all, :include => :sponsored_member, :conditions => ["name = ?","Moustache and Eyebrow Fancier Club"]) 
    559     # Only the eyebrow fanciers club has a sponsored_member 
    560     assert_not_nil assert_no_queries {clubs[0].sponsored_member} 
    561   end 
    562  
    563 end 
    564  
    565 class HasManyThroughAssociationsTest < ActiveRecord::TestCase 
    566   fixtures :posts, :readers, :people 
    567  
    568   def test_associate_existing 
    569     assert_queries(2) { posts(:thinking);people(:david) } 
    570      
    571     assert_queries(1) do 
    572        posts(:thinking).people << people(:david) 
    573     end 
    574      
    575     assert_queries(1) do 
    576       assert posts(:thinking).people.include?(people(:david)) 
    577     end 
    578      
    579     assert posts(:thinking).reload.people(true).include?(people(:david)) 
    580   end 
    581  
    582   def test_associating_new 
    583     assert_queries(1) { posts(:thinking) } 
    584     new_person = nil # so block binding catches it 
    585      
    586     assert_queries(0) do 
    587       new_person = Person.new 
    588     end 
    589      
    590     # Associating new records always saves them 
    591     # Thus, 1 query for the new person record, 1 query for the new join table record 
    592     assert_queries(2) do 
    593       posts(:thinking).people << new_person 
    594     end 
    595      
    596     assert_queries(1) do 
    597       assert posts(:thinking).people.include?(new_person) 
    598     end 
    599      
    600     assert posts(:thinking).reload.people(true).include?(new_person) 
    601   end 
    602  
    603   def test_associate_new_by_building 
    604     assert_queries(1) { posts(:thinking) } 
    605      
    606     assert_queries(0) do 
    607       posts(:thinking).people.build(:first_name=>"Bob") 
    608       posts(:thinking).people.new(:first_name=>"Ted") 
    609     end 
    610      
    611     # Should only need to load the association once 
    612     assert_queries(1) do 
    613       assert posts(:thinking).people.collect(&:first_name).include?("Bob") 
    614       assert posts(:thinking).people.collect(&:first_name).include?("Ted") 
    615     end 
    616      
    617     # 2 queries for each new record (1 to save the record itself, 1 for the join model) 
    618     #    * 2 new records = 4 
    619     # + 1 query to save the actual post = 5 
    620     assert_queries(5) do 
    621       posts(:thinking).save 
    622     end 
    623      
    624     assert posts(:thinking).reload.people(true).collect(&:first_name).include?("Bob") 
    625     assert posts(:thinking).reload.people(true).collect(&:first_name).include?("Ted") 
    626   end 
    627  
    628   def test_delete_association 
    629     assert_queries(2){posts(:welcome);people(:michael); } 
    630      
    631     assert_queries(1) do 
    632       posts(:welcome).people.delete(people(:michael)) 
    633     end 
    634      
    635     assert_queries(1) do 
    636       assert posts(:welcome).people.empty? 
    637     end 
    638      
    639     assert posts(:welcome).reload.people(true).empty? 
    640   end 
    641  
    642   def test_replace_association 
    643     assert_queries(4){posts(:welcome);people(:david);people(:michael); posts(:welcome).people(true)} 
    644      
    645     # 1 query to delete the existing reader (michael) 
    646     # 1 query to associate the new reader (david) 
    647     assert_queries(2) do 
    648       posts(:welcome).people = [people(:david)] 
    649     end 
    650      
    651     assert_queries(0){ 
    652       assert posts(:welcome).people.include?(people(:david)) 
    653       assert !posts(:welcome).people.include?(people(:michael)) 
    654     } 
    655      
    656     assert posts(:welcome).reload.people(true).include?(people(:david)) 
    657     assert !posts(:welcome).reload.people(true).include?(people(:michael)) 
    658   end 
    659  
    660   def test_associate_with_create 
    661     assert_queries(1) { posts(:thinking) } 
    662      
    663     # 1 query for the new record, 1 for the join table record 
    664     # No need to update the actual collection yet! 
    665     assert_queries(2) do 
    666       posts(:thinking).people.create(:first_name=>"Jeb") 
    667     end 
    668      
    669     # *Now* we actually need the collection so it's loaded 
    670     assert_queries(1) do 
    671       assert posts(:thinking).people.collect(&:first_name).include?("Jeb") 
    672     end 
    673      
    674     assert posts(:thinking).reload.people(true).collect(&:first_name).include?("Jeb") 
    675   end 
    676  
    677   def test_clear_associations 
    678     assert_queries(2) { posts(:welcome);posts(:welcome).people(true) } 
    679      
    680     assert_queries(1) do 
    681       posts(:welcome).people.clear 
    682     end 
    683      
    684     assert_queries(0) do 
    685       assert posts(:welcome).people.empty? 
    686     end 
    687      
    688     assert posts(:welcome).reload.people(true).empty? 
    689   end 
    690  
    691   def test_association_callback_ordering 
    692     Post.reset_log 
    693     log = Post.log 
    694     post = posts(:thinking) 
    695  
    696     post.people_with_callbacks << people(:michael) 
    697     assert_equal [ 
    698       [:added, :before, "Michael"], 
    699       [:added, :after, "Michael"] 
    700     ], log.last(2) 
    701  
    702     post.people_with_callbacks.push(people(:david), Person.create!(:first_name => "Bob"), Person.new(:first_name => "Lary")) 
    703     assert_equal [ 
    704       [:added, :before, "David"], 
    705       [:added, :after, "David"], 
    706       [:added, :before, "Bob"], 
    707       [:added, :after, "Bob"], 
    708       [:added, :before, "Lary"], 
    709       [:added, :after, "Lary"] 
    710     ],log.last(6) 
    711  
    712     post.people_with_callbacks.build(:first_name => "Ted") 
    713     assert_equal [ 
    714       [:added, :before, "Ted"], 
    715       [:added, :after, "Ted"] 
    716     ], log.last(2) 
    717  
    718     post.people_with_callbacks.create(:first_name => "Sam") 
    719     assert_equal [ 
    720       [:added, :before, "Sam"], 
    721       [:added, :after, "Sam"] 
    722     ], log.last(2) 
    723  
    724     post.people_with_callbacks = [people(:michael),people(:david), Person.new(:first_name => "Julian"), Person.create!(:first_name => "Roger")] 
    725     assert_equal (%w(Ted Bob Sam Lary) * 2).sort, log[-12..-5].collect(&:last).sort 
    726     assert_equal [ 
    727       [:added, :before, "Julian"], 
    728       [:added, :after, "Julian"], 
    729       [:added, :before, "Roger"], 
    730       [:added, :after, "Roger"] 
    731     ], log.last(4) 
    732  
    733     post.people_with_callbacks.clear 
    734     assert_equal (%w(Michael David Julian Roger) * 2).sort, log.last(8).collect(&:last).sort 
    735   end 
    736 end 
    737  
    738 class HasManyAssociationsTest < ActiveRecord::TestCase 
    739   fixtures :accounts, :categories, :companies, :developers, :projects, 
    740            :developers_projects, :topics, :authors, :comments, :author_addresses, 
    741            :people, :posts 
    742  
    743   def setup 
    744     Client.destroyed_client_ids.clear 
    745   end 
    746  
    747   def force_signal37_to_load_all_clients_of_firm 
    748     companies(:first_firm).clients_of_firm.each {|f| } 
    749   end 
    750  
    751   def test_counting_with_counter_sql 
    752     assert_equal 2, Firm.find(:first).clients.count 
    753   end 
    754  
    755   def test_counting 
    756     assert_equal 2, Firm.find(:first).plain_clients.count 
    757   end 
    758  
    759   def test_counting_with_single_conditions 
    760     assert_equal 2, Firm.find(:first).plain_clients.count(:conditions => '1=1') 
    761   end 
    762  
    763   def test_counting_with_single_hash 
    764     assert_equal 2, Firm.find(:first).plain_clients.count(:conditions => '1=1') 
    765   end 
    766  
    767   def test_counting_with_column_name_and_hash 
    768     assert_equal 2, Firm.find(:first).plain_clients.count(:all, :conditions => '1=1') 
    769   end 
    770  
    771   def test_finding 
    772     assert_equal 2, Firm.find(:first).clients.length 
    773   end 
    774  
    775   def test_find_many_with_merged_options 
    776     assert_equal 1, companies(:first_firm).limited_clients.size 
    777     assert_equal 1, companies(:first_firm).limited_clients.find(:all).size 
    778     assert_equal 2, companies(:first_firm).limited_clients.find(:all, :limit => nil).size 
    779   end 
    780  
    781   def test_dynamic_find_should_respect_association_order 
    782     assert_equal companies(:second_client), companies(:first_firm).clients_sorted_desc.find(:first, :conditions => "type = 'Client'") 
    783     assert_equal companies(:second_client), companies(:first_firm).clients_sorted_desc.find_by_type('Client') 
    784   end 
    785  
    786   def test_dynamic_find_order_should_override_association_order 
    787     assert_equal companies(:first_client), companies(:first_firm).clients_sorted_desc.find(:first, :conditions => "type = 'Client'", :order => 'id') 
    788     assert_equal companies(:first_client), companies(:first_firm).clients_sorted_desc.find_by_type('Client', :order => 'id') 
    789   end 
    790  
    791   def test_dynamic_find_all_should_respect_association_order 
    792     assert_equal [companies(:second_client), companies(:first_client)], companies(:first_firm).clients_sorted_desc.find(:all, :conditions => "type = 'Client'") 
    793     assert_equal [companies(:second_client), companies(:first_client)], companies(:first_firm).clients_sorted_desc.find_all_by_type('Client') 
    794   end 
    795  
    796   def test_dynamic_find_all_order_should_override_association_order 
    797     assert_equal [companies(:first_client), companies(:second_client)], companies(:first_firm).clients_sorted_desc.find(:all, :conditions => "type = 'Client'", :order => 'id') 
    798     assert_equal [companies(:first_client), companies(:second_client)], companies(:first_firm).clients_sorted_desc.find_all_by_type('Client', :order => 'id') 
    799   end 
    800  
    801   def test_dynamic_find_all_should_respect_association_limit 
    802     assert_equal 1, companies(:first_firm).limited_clients.find(:all, :conditions => "type = 'Client'").length 
    803     assert_equal 1, companies(:first_firm).limited_clients.find_all_by_type('Client').length 
    804   end 
    805  
    806   def test_dynamic_find_all_limit_should_override_association_limit 
    807     assert_equal 2, companies(:first_firm).limited_clients.find(:all, :conditions => "type = 'Client'", :limit => 9_000).length 
    808     assert_equal 2, companies(:first_firm).limited_clients.find_all_by_type('Client', :limit => 9_000).length 
    809   end 
    810  
    811   def test_dynamic_find_all_should_respect_readonly_access 
    812     companies(:first_firm).readonly_clients.find(:all).each { |c| assert_raise(ActiveRecord::ReadOnlyRecord) { c.save!  } } 
    813     companies(:first_firm).readonly_clients.find(:all).each { |c| assert c.readonly? } 
    814   end 
    815  
    816   def test_cant_save_has_many_readonly_association 
    817     authors(:david).readonly_comments.each { |c| assert_raise(ActiveRecord::ReadOnlyRecord) { c.save! } } 
    818     authors(:david).readonly_comments.each { |c| assert c.readonly? } 
    819   end 
    820  
    821   def test_triple_equality 
    822     assert !(Array === Firm.find(:first).clients) 
    823     assert Firm.find(:first).clients === Array 
    824   end 
    825  
    826   def test_finding_default_orders 
    827     assert_equal "Summit", Firm.find(:first).clients.first.name 
    828   end 
    829  
    830   def test_finding_with_different_class_name_and_order 
    831     assert_equal "Microsoft", Firm.find(:first).clients_sorted_desc.first.name 
    832   end 
    833  
    834   def test_finding_with_foreign_key 
    835     assert_equal "Microsoft", Firm.find(:first).clients_of_firm.first.name 
    836   end 
    837  
    838   def test_finding_with_condition 
    839     assert_equal "Microsoft", Firm.find(:first).clients_like_ms.first.name 
    840   end 
    841  
    842   def test_finding_with_condition_hash 
    843     assert_equal "Microsoft", Firm.find(:first).clients_like_ms_with_hash_conditions.first.name 
    844   end 
    845  
    846   def test_finding_using_sql 
    847     firm = Firm.find(:first) 
    848     first_client = firm.clients_using_sql.first 
    849     assert_not_nil first_client 
    850     assert_equal "Microsoft", first_client.name 
    851     assert_equal 1, firm.clients_using_sql.size 
    852     assert_equal 1, Firm.find(:first).clients_using_sql.size 
    853   end 
    854  
    855   def test_counting_using_sql 
    856     assert_equal 1, Firm.find(:first).clients_using_counter_sql.size 
    857     assert Firm.find(:first).clients_using_counter_sql.any? 
    858     assert_equal 0, Firm.find(:first).clients_using_zero_counter_sql.size 
    859     assert !Firm.find(:first).clients_using_zero_counter_sql.any? 
    860   end 
    861  
    862   def test_counting_non_existant_items_using_sql 
    863     assert_equal 0, Firm.find(:first).no_clients_using_counter_sql.size 
    864   end 
    865  
    866   def test_belongs_to_sanity 
    867     c = Client.new 
    868     assert_nil c.firm 
    869  
    870     if c.firm 
    871       assert false, "belongs_to failed if check" 
    872     end 
    873  
    874     unless c.firm 
    875     else 
    876       assert false,  "belongs_to failed unless check" 
    877     end 
    878   end 
    879  
    880   def test_find_ids 
    881     firm = Firm.find(:first) 
    882  
    883     assert_raises(ActiveRecord::RecordNotFound) { firm.clients.find } 
    884  
    885     client = firm.clients.find(2) 
    886     assert_kind_of Client, client 
    887  
    888     client_ary = firm.clients.find([2]) 
    889     assert_kind_of Array, client_ary 
    890     assert_equal client, client_ary.first 
    891  
    892     client_ary = firm.clients.find(2, 3) 
    893     assert_kind_of Array, client_ary 
    894     assert_equal 2, client_ary.size 
    895     assert_equal client, client_ary.first 
    896  
    897     assert_raises(ActiveRecord::RecordNotFound) { firm.clients.find(2, 99) } 
    898   end 
    899  
    900   def test_find_string_ids_when_using_finder_sql 
    901     firm = Firm.find(:first) 
    902  
    903     client = firm.clients_using_finder_sql.find("2") 
    904     assert_kind_of Client, client 
    905  
    906     client_ary = firm.clients_using_finder_sql.find(["2"]) 
    907     assert_kind_of Array, client_ary 
    908     assert_equal client, client_ary.first 
    909  
    910     client_ary = firm.clients_using_finder_sql.find("2", "3") 
    911     assert_kind_of Array, client_ary 
    912     assert_equal 2, client_ary.size 
    913     assert client_ary.include?(client) 
    914   end 
    915  
    916   def test_find_all 
    917     firm = Firm.find(:first) 
    918     assert_equal 2, firm.clients.find(:all, :conditions => "#{QUOTED_TYPE} = 'Client'").length 
    919     assert_equal 1, firm.clients.find(:all, :conditions => "name = 'Summit'").length 
    920   end 
    921  
    922   def test_find_all_sanitized 
    923     firm = Firm.find(:first) 
    924     summit = firm.clients.find(:all, :conditions => "name = 'Summit'") 
    925     assert_equal summit, firm.clients.find(:all, :conditions => ["name = ?", "Summit"]) 
    926     assert_equal summit, firm.clients.find(:all, :conditions => ["name = :name", { :name => "Summit" }]) 
    927   end 
    928  
    929   def test_find_first 
    930     firm = Firm.find(:first) 
    931     client2 = Client.find(2) 
    932     assert_equal firm.clients.first, firm.clients.find(:first) 
    933     assert_equal client2, firm.clients.find(:first, :conditions => "#{QUOTED_TYPE} = 'Client'") 
    934   end 
    935  
    936   def test_find_first_sanitized 
    937     firm = Firm.find(:first) 
    938     client2 = Client.find(2) 
    939     assert_equal client2, firm.clients.find(:first, :conditions => ["#{QUOTED_TYPE} = ?", 'Client']) 
    940     assert_equal client2, firm.clients.find(:first, :conditions => ["#{QUOTED_TYPE} = :type", { :type => 'Client' }]) 
    941   end 
    942  
    943   def test_find_in_collection 
    944     assert_equal Client.find(2).name, companies(:first_firm).clients.find(2).name 
    945     assert_raises(ActiveRecord::RecordNotFound) { companies(:first_firm).clients.find(6) } 
    946   end 
    947  
    948   def test_find_grouped 
    949     all_clients_of_firm1 = Client.find(:all, :conditions => "firm_id = 1") 
    950     grouped_clients_of_firm1 = Client.find(:all, :conditions => "firm_id = 1", :group => "firm_id", :select => 'firm_id, count(id) as clients_count') 
    951     assert_equal 2, all_clients_of_firm1.size 
    952     assert_equal 1, grouped_clients_of_firm1.size 
    953   end 
    954  
    955   def test_adding 
    956     force_signal37_to_load_all_clients_of_firm 
    957     natural = Client.new("name" => "Natural Company") 
    958     companies(:first_firm).clients_of_firm << natural 
    959     assert_equal 2, companies(:first_firm).clients_of_firm.size # checking via the collection 
    960     assert_equal 2, companies(:first_firm).clients_of_firm(true).size # checking using the db 
    961     assert_equal natural, companies(:first_firm).clients_of_firm.last 
    962   end 
    963  
    964   def test_adding_using_create 
    965     first_firm = companies(:first_firm) 
    966     assert_equal 2, first_firm.plain_clients.size 
    967     natural = first_firm.plain_clients.create(:name => "Natural Company") 
    968     assert_equal 3, first_firm.plain_clients.length 
    969     assert_equal 3, first_firm.plain_clients.size 
    970   end 
    971  
    972   def test_create_with_bang_on_has_many_when_parent_is_new_raises 
    973     assert_raises(ActiveRecord::RecordNotSaved) do 
    974       firm = Firm.new 
    975       firm.plain_clients.create! :name=>"Whoever" 
    976     end 
    977   end 
    978  
    979   def test_regular_create_on_has_many_when_parent_is_new_raises 
    980     assert_raises(ActiveRecord::RecordNotSaved) do 
    981       firm = Firm.new 
    982       firm.plain_clients.create :name=>"Whoever" 
    983     end 
    984   end 
    985  
    986   def test_create_with_bang_on_has_many_raises_when_record_not_saved 
    987     assert_raises(ActiveRecord::RecordInvalid) do 
    988       firm = Firm.find(:first) 
    989       firm.plain_clients.create! 
    990     end 
    991   end 
    992  
    993   def test_create_with_bang_on_habtm_when_parent_is_new_raises 
    994     assert_raises(ActiveRecord::RecordNotSaved) do 
    995       Developer.new("name" => "Aredridel").projects.create! 
    996     end 
    997   end 
    998  
    999   def test_adding_a_mismatch_class 
    1000     assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << nil } 
    1001     assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << 1 } 
    1002     assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << Topic.find(1) } 
    1003   end 
    1004  
    1005   def test_adding_a_collection 
    1006     force_signal37_to_load_all_clients_of_firm 
    1007     companies(:first_firm).clients_of_firm.concat([Client.new("name" => "Natural Company"), Client.new("name" => "Apple")]) 
    1008     assert_equal 3, companies(:first_firm).clients_of_firm.size 
    1009     assert_equal 3, companies(:first_firm).clients_of_firm(true).size 
    1010   end 
    1011  
    1012   def test_adding_before_save 
    1013     no_of_firms = Firm.count 
    1014     no_of_clients = Client.count 
    1015  
    1016     new_firm = Firm.new("name" => "A New Firm, Inc") 
    1017     c = Client.new("name" => "Apple") 
    1018  
    1019     new_firm.clients_of_firm.push Client.new("name" => "Natural Company") 
    1020     assert_equal 1, new_firm.clients_of_firm.size 
    1021     new_firm.clients_of_firm << c 
    1022     assert_equal 2, new_firm.clients_of_firm.size 
    1023  
    1024     assert_equal no_of_firms, Firm.count      # Firm was not saved to database. 
    1025     assert_equal no_of_clients, Client.count  # Clients were not saved to database. 
    1026     assert new_firm.save 
    1027     assert !new_firm.new_record? 
    1028     assert !c.new_record? 
    1029     assert_equal new_firm, c.firm 
    1030     assert_equal no_of_firms+1, Firm.count      # Firm was saved to database. 
    1031     assert_equal no_of_clients+2, Client.count  # Clients were saved to database. 
    1032  
    1033     assert_equal 2, new_firm.clients_of_firm.size 
    1034     assert_equal 2, new_firm.clients_of_firm(true).size 
    1035   end 
    1036  
    1037   def test_invalid_adding 
    1038     firm = Firm.find(1) 
    1039     assert !(firm.clients_of_firm << c = Client.new) 
    1040     assert c.new_record? 
    1041     assert !firm.valid? 
    1042     assert !firm.save 
    1043     assert c.new_record? 
    1044   end 
    1045  
    1046   def test_invalid_adding_before_save 
    1047     no_of_firms = Firm.count 
    1048     no_of_clients = Client.count 
    1049     new_firm = Firm.new("name" => "A New Firm, Inc") 
    1050     new_firm.clients_of_firm.concat([c = Client.new, Client.new("name" => "Apple")]) 
    1051     assert c.new_record? 
    1052     assert !c.valid? 
    1053     assert !new_firm.valid? 
    1054     assert !new_firm.save 
    1055     assert c.new_record? 
    1056     assert new_firm.new_record? 
    1057   end 
    1058  
    1059   def test_build 
    1060     company = companies(:first_firm) 
    1061     new_client = assert_no_queries { company.clients_of_firm.build("name" => "Another Client") } 
    1062     assert !company.clients_of_firm.loaded? 
    1063      
    1064     assert_equal "Another Client", new_client.name 
    1065     assert new_client.new_record? 
    1066     assert_equal new_client, company.clients_of_firm.last 
    1067     assert_queries(2) { assert company.save } 
    1068     assert !new_client.new_record? 
    1069     assert_equal 2, company.clients_of_firm(true).size 
    1070   end 
    1071  
    1072   def test_build_many 
    1073     company = companies(:first_firm) 
    1074     new_clients = assert_no_queries { company.clients_of_firm.build([{"name" => "Another Client"}, {"name" => "Another Client II"}]) } 
    1075      
    1076     assert_equal 2, new_clients.size 
    1077     assert_queries(3) { assert company.save } 
    1078     assert_equal 3, company.clients_of_firm(true).size 
    1079   end 
    1080  
    1081   def test_build_followed_by_save_does_not_load_target 
    1082     new_client = companies(:first_firm).clients_of_firm.build("name" => "Another Client") 
    1083     assert companies(:first_firm).save 
    1084     assert !companies(:first_firm).clients_of_firm.loaded? 
    1085   end 
    1086  
    1087   def test_build_without_loading_association 
    1088     first_topic = topics(:first) 
    1089     Reply.column_names 
    1090  
    1091     assert_equal 1, first_topic.replies.length 
    1092  
    1093     assert_no_queries do 
    1094       first_topic.replies.build(:title => "Not saved", :content => "Superstars") 
    1095       assert_equal 2, first_topic.replies.size 
    1096     end 
    1097  
    1098     assert_equal 2, first_topic.replies.to_ary.size 
    1099   end 
    1100  
    1101   def test_create_without_loading_association 
    1102     first_firm  = companies(:first_firm) 
    1103     Firm.column_names 
    1104     Client.column_names 
    1105  
    1106     assert_equal 1, first_firm.clients_of_firm.size 
    1107     first_firm.clients_of_firm.reset 
    1108  
    1109     assert_queries(1) do 
    1110       first_firm.clients_of_firm.create(:name => "Superstars") 
    1111     end 
    1112  
    1113     assert_equal 2, first_firm.clients_of_firm.size 
    1114   end 
    1115  
    1116   def test_invalid_build 
    1117     new_client = companies(:first_firm).clients_of_firm.build 
    1118     assert new_client.new_record? 
    1119     assert !new_client.valid? 
    1120     assert_equal new_client, companies(:first_firm).clients_of_firm.last 
    1121     assert !companies(:first_firm).save 
    1122     assert new_client.new_record? 
    1123     assert_equal 1, companies(:first_firm).clients_of_firm(true).size 
    1124   end 
    1125  
    1126   def test_create 
    1127     force_signal37_to_load_all_clients_of_firm 
    1128     new_client = companies(:first_firm).clients_of_firm.create("name" => "Another Client") 
    1129     assert !new_client.new_record? 
    1130     assert_equal new_client, companies(:first_firm).clients_of_firm.last 
    1131     assert_equal new_client, companies(:first_firm).clients_of_firm(true).last 
    1132   end 
    1133  
    1134   def test_create_many 
    1135     companies(:first_firm).clients_of_firm.create([{"name" => "Another Client"}, {"name" => "Another Client II"}]) 
    1136     assert_equal 3, companies(:first_firm).clients_of_firm(true).size 
    1137   end 
    1138  
    1139   def test_create_followed_by_save_does_not_load_target 
    1140     new_client = companies(:first_firm).clients_of_firm.create("name" => "Another Client") 
    1141     assert companies(:first_firm).save 
    1142     assert !companies(:first_firm).clients_of_firm.loaded? 
    1143   end 
    1144  
    1145   def test_find_or_initialize 
    1146     the_client = companies(:first_firm).clients.find_or_initialize_by_name("Yet another client") 
    1147     assert_equal companies(:first_firm).id, the_client.firm_id 
    1148     assert_equal "Yet another client", the_client.name 
    1149     assert the_client.new_record? 
    1150   end 
    1151  
    1152   def test_find_or_create 
    1153     number_of_clients = companies(:first_firm).clients.size 
    1154     the_client = companies(:first_firm).clients.find_or_create_by_name("Yet another client") 
    1155     assert_equal number_of_clients + 1, companies(:first_firm, :reload).clients.size 
    1156     assert_equal the_client, companies(:first_firm).clients.find_or_create_by_name("Yet another client") 
    1157     assert_equal number_of_clients + 1, companies(:first_firm, :reload).clients.size 
    1158   end 
    1159  
    1160   def test_deleting 
    1161     force_signal37_to_load_all_clients_of_firm 
    1162     companies(:first_firm).clients_of_firm.delete(companies(:first_firm).clients_of_firm.first) 
    1163     assert_equal 0, companies(:first_firm).clients_of_firm.size 
    1164     assert_equal 0, companies(:first_firm).clients_of_firm(true).size 
    1165   end 
    1166  
    1167   def test_deleting_before_save 
    1168     new_firm = Firm.new("name" => "A New Firm, Inc.") 
    1169     new_client = new_firm.clients_of_firm.build("name" => "Another Client") 
    1170     assert_equal 1, new_firm.clients_of_firm.size 
    1171     new_firm.clients_of_firm.delete(new_client) 
    1172     assert_equal 0, new_firm.clients_of_firm.size 
    1173   end 
    1174  
    1175   def test_deleting_a_collection 
    1176     force_signal37_to_load_all_clients_of_firm 
    1177     companies(:first_firm).clients_of_firm.create("name" => "Another Client") 
    1178     assert_equal 2, companies(:first_firm).clients_of_firm.size 
    1179     companies(:first_firm).clients_of_firm.delete([companies(:first_firm).clients_of_firm[0], companies(:first_firm).clients_of_firm[1]]) 
    1180     assert_equal 0, companies(:first_firm).clients_of_firm.size 
    1181     assert_equal 0, companies(:first_firm).clients_of_firm(true).size 
    1182   end 
    1183  
    1184   def test_delete_all 
    1185     force_signal37_to_load_all_clients_of_firm 
    1186     companies(:first_firm).clients_of_firm.create("name" => "Another Client") 
    1187     assert_equal 2, companies(:first_firm).clients_of_firm.size 
    1188     companies(:first_firm).clients_of_firm.delete_all 
    1189     assert_equal 0, companies(:first_firm).clients_of_firm.size 
    1190     assert_equal 0, companies(:first_firm).clients_of_firm(true).size 
    1191   end 
    1192  
    1193   def test_delete_all_with_not_yet_loaded_association_collection 
    1194     force_signal37_to_load_all_clients_of_firm 
    1195     companies(:first_firm).clients_of_firm.create("name" => "Another Client") 
    1196     assert_equal 2, companies(:first_firm).clients_of_firm.size 
    1197     companies(:first_firm).clients_of_firm.reset 
    1198     companies(:first_firm).clients_of_firm.delete_all 
    1199     assert_equal 0, companies(:first_firm).clients_of_firm.size 
    1200     assert_equal 0, companies(:first_firm).clients_of_firm(true).size 
    1201   end 
    1202  
    1203   def test_clearing_an_association_collection 
    1204     firm = companies(:first_firm) 
    1205     client_id = firm.clients_of_firm.first.id 
    1206     assert_equal 1, firm.clients_of_firm.size 
    1207  
    1208     firm.clients_of_firm.clear 
    1209  
    1210     assert_equal 0, firm.clients_of_firm.size 
    1211     assert_equal 0, firm.clients_of_firm(true).size 
    1212     assert_equal [], Client.destroyed_client_ids[firm.id] 
    1213  
    1214     # Should not be destroyed since the association is not dependent. 
    1215     assert_nothing_raised do 
    1216       assert Client.find(client_id).firm.nil? 
    1217     end 
    1218   end 
    1219  
    1220   def test_clearing_a_dependent_association_collection 
    1221     firm = companies(:first_firm) 
    1222     client_id = firm.dependent_clients_of_firm.first.id 
    1223     assert_equal 1, firm.dependent_clients_of_firm.size 
    1224  
    1225     # :dependent means destroy is called on each client 
    1226     firm.dependent_clients_of_firm.clear 
    1227  
    1228     assert_equal 0, firm.dependent_clients_of_firm.size 
    1229     assert_equal 0, firm.dependent_clients_of_firm(true).size 
    1230     assert_equal [client_id], Client.destroyed_client_ids[firm.id] 
    1231  
    1232     # Should be destroyed since the association is dependent. 
    1233     assert Client.find_by_id(client_id).nil? 
    1234   end 
    1235  
    1236   def test_clearing_an_exclusively_dependent_association_collection 
    1237     firm = companies(:first_firm) 
    1238     client_id = firm.exclusively_dependent_clients_of_firm.first.id 
    1239     assert_equal 1, firm.exclusively_dependent_clients_of_firm.size 
    1240  
    1241     assert_equal [], Client.destroyed_client_ids[firm.id] 
    1242  
    1243     # :exclusively_dependent means each client is deleted directly from 
    1244     # the database without looping through them calling destroy. 
    1245     firm.exclusively_dependent_clients_of_firm.clear 
    1246  
    1247     assert_equal 0, firm.exclusively_dependent_clients_of_firm.size 
    1248     assert_equal 0, firm.exclusively_dependent_clients_of_firm(true).size 
    1249     # no destroy-filters should have been called 
    1250     assert_equal [], Client.destroyed_client_ids[firm.id] 
    1251  
    1252     # Should be destroyed since the association is exclusively dependent. 
    1253     assert Client.find_by_id(client_id).nil? 
    1254   end 
    1255  
    1256   def test_dependent_association_respects_optional_conditions_on_delete 
    1257     firm = companies(:odegy) 
    1258     Client.create(:client_of => firm.id, :name => "BigShot Inc.") 
    1259     Client.create(:client_of => firm.id, :name => "SmallTime Inc.") 
    1260     # only one of two clients is included in the association due to the :conditions key 
    1261     assert_equal 2, Client.find_all_by_client_of(firm.id).size 
    1262     assert_equal 1, firm.dependent_conditional_clients_of_firm.size 
    1263     firm.destroy 
    1264     # only the correctly associated client should have been deleted 
    1265     assert_equal 1, Client.find_all_by_client_of(firm.id).size 
    1266   end 
    1267  
    1268   def test_dependent_association_respects_optional_sanitized_conditions_on_delete 
    1269     firm = companies(:odegy) 
    1270     Client.create(:client_of => firm.id, :name => "BigShot Inc.") 
    1271     Client.create(:client_of => firm.id, :name => "SmallTime Inc.") 
    1272     # only one of two clients is included in the association due to the :conditions key 
    1273     assert_equal 2, Client.find_all_by_client_of(firm.id).size 
    1274     assert_equal 1, firm.dependent_sanitized_conditional_clients_of_firm.size 
    1275     firm.destroy 
    1276     # only the correctly associated client should have been deleted 
    1277     assert_equal 1, Client.find_all_by_client_of(firm.id).size 
    1278   end 
    1279  
    1280   def test_creation_respects_hash_condition 
    1281     ms_client = companies(:first_firm).clients_like_ms_with_hash_conditions.build 
    1282      
    1283     assert        ms_client.save 
    1284     assert_equal  'Microsoft', ms_client.name 
    1285      
    1286     another_ms_client = companies(:first_firm).clients_like_ms_with_hash_conditions.create 
    1287  
    1288     assert        !another_ms_client.new_record? 
    1289     assert_equal  'Microsoft', another_ms_client.name 
    1290   end 
    1291  
    1292   def test_dependent_delete_and_destroy_with_belongs_to 
    1293     author_address = author_addresses(:david_address) 
    1294     assert_equal [], AuthorAddress.destroyed_author_address_ids[authors(:david).id] 
    1295  
    1296     assert_difference "AuthorAddress.count", -2 do 
    1297       authors(:david).destroy 
    1298     end 
    1299  
    1300     assert_equal [author_address.id], AuthorAddress.destroyed_author_address_ids[authors(:david).id] 
    1301   end 
    1302  
    1303   def test_invalid_belongs_to_dependent_option_raises_exception 
    1304     assert_raises ArgumentError do 
    1305       Author.belongs_to :special_author_address, :dependent => :nullify 
    1306     end 
    1307   end 
    1308  
    1309   def test_clearing_without_initial_access 
    1310     firm = companies(:first_firm) 
    1311  
    1312     firm.clients_of_firm.clear 
    1313  
    1314     assert_equal 0, firm.clients_of_firm.size 
    1315     assert_equal 0, firm.clients_of_firm(true).size 
    1316   end 
    1317  
    1318   def test_deleting_a_item_which_is_not_in_the_collection 
    1319     force_signal37_to_load_all_clients_of_firm 
    1320     summit = Client.find_by_name('Summit') 
    1321     companies(:first_firm).clients_of_firm.delete(summit) 
    1322     assert_equal 1, companies(:first_firm).clients_of_firm.size 
    1323     assert_equal 1, companies(:first_firm).clients_of_firm(true).size 
    1324     assert_equal 2, summit.client_of 
    1325   end 
    1326  
    1327   def test_deleting_type_mismatch 
    1328     david = Developer.find(1) 
    1329     david.projects.reload 
    1330     assert_raises(ActiveRecord::AssociationTypeMismatch) { david.projects.delete(1) } 
    1331   end 
    1332  
    1333   def test_deleting_self_type_mismatch 
    1334     david = Developer.find(1) 
    1335     david.projects.reload 
    1336     assert_raises(ActiveRecord::AssociationTypeMismatch) { david.projects.delete(Project.find(1).developers) } 
    1337   end 
    1338  
    1339   def test_destroy_all 
    1340     force_signal37_to_load_all_clients_of_firm 
    1341     assert !companies(:first_firm).clients_of_firm.empty?, "37signals has clients after load" 
    1342     companies(:first_firm).clients_of_firm.destroy_all 
    1343     assert companies(:first_firm).clients_of_firm.empty?, "37signals has no clients after destroy all" 
    1344     assert companies(:first_firm).clients_of_firm(true).empty?, "37signals has no clients after destroy all and refresh" 
    1345   end 
    1346  
    1347   def test_dependence 
    1348     firm = companies(:first_firm) 
    1349     assert_equal 2, firm.clients.size 
    1350     firm.destroy 
    1351     assert Client.find(:all, :conditions => "firm_id=#{firm.id}").empty? 
    1352   end 
    1353  
    1354   def test_destroy_dependent_when_deleted_from_association 
    1355     firm = Firm.find(:first) 
    1356     assert_equal 2, firm.clients.size 
    1357  
    1358     client = firm.clients.first 
    1359     firm.clients.delete(client) 
    1360  
    1361     assert_raise(ActiveRecord::RecordNotFound) { Client.find(client.id) } 
    1362     assert_raise(ActiveRecord::RecordNotFound) { firm.clients.find(client.id) } 
    1363     assert_equal 1, firm.clients.size 
    1364   end 
    1365  
    1366   def test_three_levels_of_dependence 
    1367     topic = Topic.create "title" => "neat and simple" 
    1368     reply = topic.replies.create "title" => "neat and simple", "content" => "still digging it" 
    1369     silly_reply = reply.replies.create "title" => "neat and simple", "content" => "ain't complaining" 
    1370  
    1371     assert_nothing_raised { topic.destroy } 
    1372   end 
    1373  
    1374   uses_transaction :test_dependence_with_transaction_support_on_failure 
    1375   def test_dependence_with_transaction_support_on_failure 
    1376     firm = companies(:first_firm) 
    1377     clients = firm.clients 
    1378     assert_equal 2, clients.length 
    1379     clients.last.instance_eval { def before_destroy() raise "Trigger rollback" end } 
    1380  
    1381     firm.destroy rescue "do nothing" 
    1382  
    1383     assert_equal 2, Client.find(:all, :conditions => "firm_id=#{firm.id}").size 
    1384   end 
    1385  
    1386   def test_dependence_on_account 
    1387     num_accounts = Account.count 
    1388     companies(:first_firm).destroy 
    1389     assert_equal num_accounts - 1, Account.count 
    1390   end 
    1391  
    1392   def test_depends_and_nullify 
    1393     num_accounts = Account.count 
    1394     num_companies = Company.count 
    1395  
    1396     core = companies(:rails_core) 
    1397     assert_equal accounts(:rails_core_account), core.account 
    1398     assert_equal companies(:leetsoft, :jadedpixel), core.companies 
    1399     core.destroy 
    1400     assert_nil accounts(:rails_core_account).reload.firm_id 
    1401     assert_nil companies(:leetsoft).reload.client_of 
    1402     assert_nil companies(:jadedpixel).reload.client_of 
    1403  
    1404  
    1405     assert_equal num_accounts, Account.count 
    1406   end 
    1407  
    1408   def test_included_in_collection 
    1409     assert companies(:first_firm).clients.include?(Client.find(2)) 
    1410   end 
    1411  
    1412   def test_adding_array_and_collection 
    1413     assert_nothing_raised { Firm.find(:first).clients + Firm.find(:all).last.clients } 
    1414   end 
    1415  
    1416   def test_find_all_without_conditions 
    1417     firm = companies(:first_firm) 
    1418     assert_equal 2, firm.clients.find(:all).length 
    1419   end 
    1420  
    1421   def test_replace_with_less 
    1422     firm = Firm.find(:first) 
    1423     firm.clients = [companies(:first_client)] 
    1424     assert firm.save, "Could not save firm" 
    1425     firm.reload 
    1426     assert_equal 1, firm.clients.length 
    1427   end 
    1428  
    1429   def test_replace_with_less_and_dependent_nullify 
    1430     num_companies = Company.count 
    1431     companies(:rails_core).companies = [] 
    1432     assert_equal num_companies, Company.count 
    1433   end 
    1434  
    1435   def test_replace_with_new 
    1436     firm = Firm.find(:first) 
    1437     firm.clients = [companies(:second_client), Client.new("name" => "New Client")] 
    1438     firm.save 
    1439     firm.reload 
    1440     assert_equal 2, firm.clients.length 
    1441     assert !firm.clients.include?(:first_client) 
    1442   end 
    1443  
    1444   def test_replace_on_new_object 
    1445     firm = Firm.new("name" => "New Firm") 
    1446     firm.clients = [companies(:second_client), Client.new("name" => "New Client")] 
    1447     assert firm.save 
    1448     firm.reload 
    1449     assert_equal 2, firm.clients.length 
    1450     assert firm.clients.include?(Client.find_by_name("New Client")) 
    1451   end 
    1452  
    1453   def test_get_ids 
    1454     assert_equal [companies(:first_client).id, companies(:second_client).id], companies(:first_firm).client_ids 
    1455   end 
    1456  
    1457   def test_assign_ids 
    1458     firm = Firm.new("name" => "Apple") 
    1459     firm.client_ids = [companies(:first_client).id, companies(:second_client).id] 
    1460     firm.save 
    1461     firm.reload 
    1462     assert_equal 2, firm.clients.length 
    1463     assert firm.clients.include?(companies(:second_client)) 
    1464   end 
    1465  
    1466   def test_assign_ids_ignoring_blanks 
    1467     firm = Firm.create!(:name => 'Apple') 
    1468     firm.client_ids = [companies(:first_client).id, nil, companies(:second_client).id, ''] 
    1469     firm.save! 
    1470  
    1471     assert_equal 2, firm.clients(true).size 
    1472     assert firm.clients.include?(companies(:second_client)) 
    1473   end 
    1474  
    1475   def test_get_ids_for_through 
    1476     assert_equal [comments(:eager_other_comment1).id], authors(:mary).comment_ids 
    1477   end 
    1478  
    1479   def test_modifying_a_through_a_has_many_should_raise 
    1480     [ 
    1481       lambda { authors(:mary).comment_ids = [comments(:greetings).id, comments(:more_greetings).id] }, 
    1482       lambda { authors(:mary).comments = [comments(:greetings), comments(:more_greetings)] }, 
    1483       lambda { authors(:mary).comments << Comment.create!(:body => "Yay", :post_id => 424242) }, 
    1484       lambda { authors(:mary).comments.delete(authors(:mary).comments.first) }, 
    1485     ].each {|block| assert_raise(ActiveRecord::HasManyThroughCantAssociateThroughHasManyReflection, &block) } 
    1486   end 
    1487  
    1488  
    1489   def test_assign_ids_for_through_a_belongs_to 
    1490     post = Post.new(:title => "Assigning IDs works!", :body => "You heared it here first, folks!") 
    1491     post.person_ids = [people(:david).id, people(:michael).id] 
    1492     post.save 
    1493     post.reload 
    1494     assert_equal 2, post.people.length 
    1495     assert post.people.include?(people(:david)) 
    1496   end 
    1497  
    1498   def test_dynamic_find_should_respect_association_order_for_through 
    1499     assert_equal Comment.find(10), authors(:david).comments_desc.find(:first, :conditions => "comments.type = 'SpecialComment'") 
    1500     assert_equal Comment.find(10), authors(:david).comments_desc.find_by_type('SpecialComment') 
    1501   end 
    1502  
    1503   def test_dynamic_find_order_should_override_association_order_for_through 
    1504     assert_equal Comment.find(3), authors(:david).comments_desc.find(:first, :conditions => "comments.type = 'SpecialComment'", :order => 'comments.id') 
    1505     assert_equal Comment.find(3), authors(:david).comments_desc.find_by_type('SpecialComment', :order => 'comments.id') 
    1506   end 
    1507  
    1508   def test_dynamic_find_all_should_respect_association_order_for_through 
    1509     assert_equal [Comment.find(10), Comment.find(7), Comment.find(6), Comment.find(3)], authors(:david).comments_desc.find(:all, :conditions => "comments.type = 'SpecialComment'") 
    1510     assert_equal [Comment.find(10), Comment.find(7), Comment.find(6), Comment.find(3)], authors(:david).comments_desc.find_all_by_type('SpecialComment') 
    1511   end 
    1512  
    1513   def test_dynamic_find_all_order_should_override_association_order_for_through 
    1514     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') 
    1515     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') 
    1516   end 
    1517  
    1518   def test_dynamic_find_all_should_respect_association_limit_for_through 
    1519     assert_equal 1, authors(:david).limited_comments.find(:all, :conditions => "comments.type = 'SpecialComment'").length 
    1520     assert_equal 1, authors(:david).limited_comments.find_all_by_type('SpecialComment').length 
    1521   end 
    1522  
    1523   def test_dynamic_find_all_order_should_override_association_limit_for_through 
    1524     assert_equal 4, authors(:david).limited_comments.find(:all, :conditions => "comments.type = 'SpecialComment'", :limit => 9_000).length 
    1525     assert_equal 4, authors(:david).limited_comments.find_all_by_type('SpecialComment', :limit => 9_000).length 
    1526   end 
    1527    
    1528   def test_find_all_include_over_the_same_table_for_through 
    1529     assert_equal 2, people(:michael).posts.find(:all, :include => :people).length 
    1530   end 
    1531  
    1532   def test_has_many_through_respects_hash_conditions 
    1533     assert_equal authors(:david).hello_posts, authors(:david).hello_posts_with_hash_conditions 
    1534     assert_equal authors(:david).hello_post_comments, authors(:david).hello_post_comments_with_hash_conditions 
    1535   end 
    1536  
    1537   def test_include_uses_array_include_after_loaded 
    1538     firm = companies(:first_firm) 
    1539     client = firm.clients.first 
    1540  
    1541     assert_no_queries do 
    1542       assert firm.clients.loaded? 
    1543       assert firm.clients.include?(client) 
    1544     end 
    1545   end 
    1546  
    1547   def test_include_checks_if_record_exists_if_target_not_loaded 
    1548     firm = companies(:first_firm) 
    1549     client = firm.clients.first 
    1550  
    1551     firm.reload 
    1552     assert ! firm.clients.loaded? 
    1553     assert_queries(1) do 
    1554       assert firm.clients.include?(client) 
    1555     end 
    1556     assert ! firm.clients.loaded? 
    1557   end 
    1558  
    1559   def test_include_returns_false_for_non_matching_record_to_verify_scoping 
    1560     firm = companies(:first_firm) 
    1561     client = Client.create!(:name => 'Not Associated') 
    1562  
    1563     assert ! firm.clients.loaded? 
    1564     assert ! firm.clients.include?(client) 
    1565   end 
    1566  
    1567 end 
    1568  
    1569 class BelongsToAssociationsTest < ActiveRecord::TestCase 
    1570   fixtures :accounts, :companies, :developers, :projects, :topics, 
    1571            :developers_projects, :computers, :authors, :posts, :tags, :taggings, :comments 
    1572  
    1573   def test_belongs_to 
    1574     Client.find(3).firm.name 
    1575     assert_equal companies(:first_firm).name, Client.find(3).firm.name 
    1576     assert !Client.find(3).firm.nil?, "Microsoft should have a firm" 
    1577   end 
    1578  
    1579   def test_proxy_assignment 
    1580     account = Account.find(1) 
    1581     assert_nothing_raised { account.firm = account.firm } 
    1582   end 
    1583  
    1584   def test_triple_equality 
    1585     assert Client.find(3).firm === Firm 
    1586     assert Firm === Client.find(3).firm 
    1587   end 
    1588  
    1589   def test_type_mismatch 
    1590     assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = 1 } 
    1591     assert_raise(ActiveRecord::AssociationTypeMismatch) { Account.find(1).firm = Project.find(1) } 
    1592   end 
    1593  
    1594   def test_natural_assignment 
    1595     apple = Firm.create("name" => "Apple") 
    1596     citibank = Account.create("credit_limit" => 10) 
    1597     citibank.firm = apple 
    1598     assert_equal apple.id, citibank.firm_id 
    1599   end 
    1600  
    1601   def test_no_unexpected_aliasing 
    1602     first_firm = companies(:first_firm) 
    1603     another_firm = companies(:another_firm) 
    1604  
    1605     citibank = Account.create("credit_limit" => 10) 
    1606     citibank.firm = first_firm 
    1607     original_proxy = citibank.firm 
    1608     citibank.firm = another_firm 
    1609  
    1610     assert_equal first_firm.object_id, original_proxy.object_id 
    1611     assert_equal another_firm.object_id, citibank.firm.object_id 
    1612   end 
    1613  
    1614   def test_creating_the_belonging_object 
    1615     citibank = Account.create("credit_limit" => 10) 
    1616     apple    = citibank.create_firm("name" => "Apple") 
    1617     assert_equal apple, citibank.firm 
    1618     citibank.save 
    1619     citibank.reload 
    1620     assert_equal apple, citibank.firm 
    1621   end 
    1622  
    1623   def test_building_the_belonging_object 
    1624     citibank = Account.create("credit_limit" => 10) 
    1625     apple    = citibank.build_firm("name" => "Apple") 
    1626     citibank.save 
    1627     assert_equal apple.id, citibank.firm_id 
    1628   end 
    1629  
    1630   def test_natural_assignment_to_nil 
    1631     client = Client.find(3) 
    1632     client.firm = nil 
    1633     client.save 
    1634     assert_nil client.firm(true) 
    1635     assert_nil client.client_of 
    1636   end 
    1637  
    1638   def test_with_different_class_name 
    1639     assert_equal Company.find(1).name, Company.find(3).firm_with_other_name.name 
    1640     assert_not_nil Company.find(3).firm_with_other_name, "Microsoft should have a firm" 
    1641   end 
    1642  
    1643   def test_with_condition 
    1644     assert_equal Company.find(1).name, Company.find(3).firm_with_condition.name 
    1645     assert_not_nil Company.find(3).firm_with_condition, "Microsoft should have a firm" 
    1646   end 
    1647  
    1648   def test_belongs_to_counter 
    1649     debate = Topic.create("title" => "debate") 
    1650     assert_equal 0, debate.send(:read_attribute, "replies_count"), "No replies yet" 
    1651  
    1652     trash = debate.replies.create("title" => "blah!", "content" => "world around!") 
    1653     assert_equal 1, Topic.find(debate.id).send(:read_attribute, "replies_count"), "First reply created" 
    1654  
    1655     trash.destroy 
    1656     assert_equal 0, Topic.find(debate.id).send(:read_attribute, "replies_count"), "First reply deleted" 
    1657   end 
    1658  
    1659   def test_belongs_to_counter_with_assigning_nil 
    1660     p = Post.find(1) 
    1661     c = Comment.find(1) 
    1662  
    1663     assert_equal p.id, c.post_id 
    1664     assert_equal 2, Post.find(p.id).comments.size 
    1665  
    1666     c.post = nil 
    1667  
    1668     assert_equal 1, Post.find(p.id).comments.size 
    1669   end 
    1670  
    1671   def test_belongs_to_counter_with_reassigning 
    1672     t1 = Topic.create("title" => "t1") 
    1673     t2 = Topic.create("title" => "t2") 
    1674     r1 = Reply.new("title" => "r1", "content" => "r1") 
    1675     r1.topic = t1 
    1676  
    1677     assert r1.save 
    1678     assert_equal 1, Topic.find(t1.id).replies.size 
    1679     assert_equal 0, Topic.find(t2.id).replies.size 
    1680  
    1681     r1.topic = Topic.find(t2.id) 
    1682  
    1683     assert r1.save 
    1684     assert_equal 0, Topic.find(t1.id).replies.size 
    1685     assert_equal 1, Topic.find(t2.id).replies.size 
    1686  
    1687     r1.topic = nil 
    1688  
    1689     assert_equal 0, Topic.find(t1.id).replies.size 
    1690     assert_equal 0, Topic.find(t2.id).replies.size 
    1691  
    1692     r1.topic = t1 
    1693  
    1694     assert_equal 1, Topic.find(t1.id).replies.size 
    1695     assert_equal 0, Topic.find(t2.id).replies.size 
    1696  
    1697     r1.destroy 
    1698  
    1699     assert_equal 0, Topic.find(t1.id).replies.size 
    1700     assert_equal 0, Topic.find(t2.id).replies.size 
    1701   end 
    1702  
    1703   def test_belongs_to_counter_after_save 
    1704     topic = Topic.create!(:title => "monday night") 
    1705     topic.replies.create!(:title => "re: monday night", :content => "football") 
    1706     assert_equal 1, Topic.find(topic.id)[:replies_count] 
    1707  
    1708     topic.save! 
    1709     assert_equal 1, Topic.find(topic.id)[:replies_count] 
    1710   end 
    1711  
    1712   def test_belongs_to_counter_after_update_attributes 
    1713     topic = Topic.create!(:title => "37s") 
    1714     topic.replies.create!(:title => "re: 37s", :content => "rails") 
    1715     assert_equal 1, Topic.find(topic.id)[:replies_count] 
    1716  
    1717     topic.update_attributes(:title => "37signals") 
    1718     assert_equal 1, Topic.find(topic.id)[:replies_count] 
    1719   end 
    1720  
    1721   def test_belongs_to_counter_after_save 
    1722     topic = Topic.create("title" => "monday night") 
    1723     topic.replies.create("title" => "re: monday night", "content" => "football") 
    1724     assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count") 
    1725  
    1726     topic.save 
    1727     assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count") 
    1728   end 
    1729  
    1730   def test_belongs_to_counter_after_update_attributes 
    1731     topic = Topic.create("title" => "37s") 
    1732     topic.replies.create("title" => "re: 37s", "content" => "rails") 
    1733     assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count") 
    1734  
    1735     topic.update_attributes("title" => "37signals") 
    1736     assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count") 
    1737   end 
    1738  
    1739   def test_assignment_before_parent_saved 
    1740     client = Client.find(:first) 
    1741     apple = Firm.new("name" => "Apple") 
    1742     client.firm = apple 
    1743     assert_equal apple, client.firm 
    1744     assert apple.new_record? 
    1745     assert client.save 
    1746     assert apple.save 
    1747     assert !apple.new_record? 
    1748     assert_equal apple, client.firm 
    1749     assert_equal apple, client.firm(true) 
    1750   end 
    1751  
    1752   def test_assignment_before_child_saved 
    1753     final_cut = Client.new("name" => "Final Cut") 
    1754     firm = Firm.find(1) 
    1755     final_cut.firm = firm 
    1756     assert final_cut.new_record? 
    1757     assert final_cut.save 
    1758     assert !final_cut.new_record? 
    1759     assert !firm.new_record? 
    1760     assert_equal firm, final_cut.firm 
    1761     assert_equal firm, final_cut.firm(true) 
    1762   end 
    1763  
    1764   def test_assignment_before_either_saved 
    1765     final_cut = Client.new("name" => "Final Cut") 
    1766     apple = Firm.new("name" => "Apple") 
    1767     final_cut.firm = apple 
    1768     assert final_cut.new_record? 
    1769     assert apple.new_record? 
    1770     assert final_cut.save 
    1771     assert !final_cut.new_record? 
    1772     assert !apple.new_record? 
    1773     assert_equal apple, final_cut.firm 
    1774     assert_equal apple, final_cut.firm(true) 
    1775   end 
    1776  
    1777   def test_new_record_with_foreign_key_but_no_object 
    1778     c = Client.new("firm_id" => 1) 
    1779     assert_equal Firm.find(:first), c.firm_with_basic_id 
    1780   end 
    1781  
    1782   def test_forgetting_the_load_when_foreign_key_enters_late 
    1783     c = Client.new 
    1784     assert_nil c.firm_with_basic_id 
    1785  
    1786     c.firm_id = 1 
    1787     assert_equal Firm.find(:first), c.firm_with_basic_id 
    1788   end 
    1789  
    1790   def test_field_name_same_as_foreign_key 
    1791     computer = Computer.find(1) 
    1792     assert_not_nil computer.developer, ":foreign key == attribute didn't lock up" # ' 
    1793   end 
    1794  
    1795   def test_counter_cache 
    1796     topic = Topic.create :title => "Zoom-zoom-zoom" 
    1797     assert_equal 0, topic[:replies_count] 
    1798  
    1799     reply = Reply.create(:title => "re: zoom", :content => "speedy quick!") 
    1800     reply.topic = topic 
    1801  
    1802     assert_equal 1, topic.reload[:replies_count] 
    1803     assert_equal 1, topic.replies.size 
    1804  
    1805     topic[:replies_count] = 15 
    1806     assert_equal 15, topic.replies.size 
    1807   end 
    1808  
    1809   def test_custom_counter_cache 
    1810     reply = Reply.create(:title => "re: zoom", :content => "speedy quick!") 
    1811     assert_equal 0, reply[:replies_count] 
    1812  
    1813     silly = SillyReply.create(:title => "gaga", :content => "boo-boo") 
    1814     silly.reply = reply 
    1815  
    1816     assert_equal 1, reply.reload[:replies_count] 
    1817     assert_equal 1, reply.replies.size 
    1818  
    1819     reply[:replies_count] = 17 
    1820     assert_equal 17, reply.replies.size 
    1821   end 
    1822  
    1823   def test_store_two_association_with_one_save 
    1824     num_orders = Order.count 
    1825     num_customers = Customer.count 
    1826     order = Order.new 
    1827  
    1828     customer1 = order.billing = Customer.new 
    1829     customer2 = order.shipping = Customer.new 
    1830     assert order.save 
    1831     assert_equal customer1, order.billing 
    1832     assert_equal customer2, order.shipping 
    1833  
    1834     order.reload 
    1835  
    1836     assert_equal customer1, order.billing 
    1837     assert_equal customer2, order.shipping 
    1838  
    1839     assert_equal num_orders +1, Order.count 
    1840     assert_equal num_customers +2, Customer.count 
    1841   end 
    1842  
    1843  
    1844   def test_store_association_in_two_relations_with_one_save 
    1845     num_orders = Order.count 
    1846     num_customers = Customer.count 
    1847     order = Order.new 
    1848  
    1849     customer = order.billing = order.shipping = Customer.new 
    1850     assert order.save 
    1851     assert_equal customer, order.billing 
    1852     assert_equal customer, order.shipping 
    1853  
    1854     order.reload 
    1855  
    1856     assert_equal customer, order.billing 
    1857     assert_equal customer, order.shipping 
    1858  
    1859     assert_equal num_orders +1, Order.count 
    1860     assert_equal num_customers +1, Customer.count 
    1861   end 
    1862  
    1863   def test_store_association_in_two_relations_with_one_save_in_existing_object 
    1864     num_orders = Order.count 
    1865     num_customers = Customer.count 
    1866     order = Order.create 
    1867  
    1868     customer = order.billing = order.shipping = Customer.new 
    1869     assert order.save 
    1870     assert_equal customer, order.billing 
    1871     assert_equal customer, order.shipping 
    1872  
    1873     order.reload 
    1874  
    1875     assert_equal customer, order.billing 
    1876     assert_equal customer, order.shipping 
    1877  
    1878     assert_equal num_orders +1, Order.count 
    1879     assert_equal num_customers +1, Customer.count 
    1880   end 
    1881  
    1882   def test_store_association_in_two_relations_with_one_save_in_existing_object_with_values 
    1883     num_orders = Order.count 
    1884     num_customers = Customer.count 
    1885     order = Order.create 
    1886  
    1887     customer = order.billing = order.shipping = Customer.new 
    1888     assert order.save 
    1889     assert_equal customer, order.billing 
    1890     assert_equal customer, order.shipping 
    1891  
    1892     order.reload 
    1893  
    1894     customer = order.billing = order.shipping = Customer.new 
    1895  
    1896     assert order.save 
    1897     order.reload 
    1898  
    1899     assert_equal customer, order.billing 
    1900     assert_equal customer, order.shipping 
    1901  
    1902     assert_equal num_orders +1, Order.count 
    1903     assert_equal num_customers +2, Customer.count 
    1904   end 
    1905  
    1906  
    1907   def test_association_assignment_sticks 
    1908     post = Post.find(:first) 
    1909  
    1910     author1, author2 = Author.find(:all, :limit => 2) 
    1911     assert_not_nil author1 
    1912     assert_not_nil author2 
    1913  
    1914     # make sure the association is loaded 
    1915     post.author 
    1916  
    1917     # set the association by id, directly 
    1918     post.author_id = author2.id 
    1919  
    1920     # save and reload 
    1921     post.save! 
    1922     post.reload 
    1923  
    1924     # the author id of the post should be the id we set 
    1925     assert_equal post.author_id, author2.id 
    1926   end 
    1927  
    1928   def test_cant_save_readonly_association 
    1929     assert_raise(ActiveRecord::ReadOnlyRecord) { companies(:first_client).readonly_firm.save! } 
    1930     assert companies(:first_client).readonly_firm.readonly? 
    1931   end 
    1932  
    1933 end 
    1934  
    1935  
    1936 class ProjectWithAfterCreateHook < ActiveRecord::Base 
    1937   set_table_name 'projects' 
    1938   has_and_belongs_to_many :developers, 
    1939     :class_name => "DeveloperForProjectWithAfterCreateHook", 
    1940     :join_table => "developers_projects", 
    1941     :foreign_key => "project_id", 
    1942     :association_foreign_key => "developer_id" 
    1943  
    1944   after_create :add_david 
    1945  
    1946   def add_david 
    1947     david = DeveloperForProjectWithAfterCreateHook.find_by_name('David') 
    1948     david.projects << self 
    1949   end 
    1950 end 
    1951  
    1952 class DeveloperForProjectWithAfterCreateHook < ActiveRecord::Base 
    1953   set_table_name 'developers' 
    1954   has_and_belongs_to_many :projects, 
    1955     :class_name => "ProjectWithAfterCreateHook", 
    1956     :join_table => "developers_projects", 
    1957     :association_foreign_key => "project_id", 
    1958     :foreign_key => "developer_id" 
    1959 end 
    1960  
    1961  
    1962 class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase 
    1963   fixtures :accounts, :companies, :categories, :posts, :categories_posts, :developers, :projects, :developers_projects, 
    1964            :parrots, :pirates, :treasures, :price_estimates 
    1965  
    1966   def test_has_and_belongs_to_many 
    1967     david = Developer.find(1) 
    1968  
    1969     assert !david.projects.empty? 
    1970     assert_equal 2, david.projects.size 
    1971  
    1972     active_record = Project.find(1) 
    1973     assert !active_record.developers.empty? 
    1974     assert_equal 3, active_record.developers.size 
    1975     assert active_record.developers.include?(david) 
    1976   end 
    1977  
    1978   def test_triple_equality 
    1979     assert !(Array === Developer.find(1).projects) 
    1980     assert Developer.find(1).projects === Array 
    1981   end 
    1982  
    1983   def test_adding_single 
    1984     jamis = Developer.find(2) 
    1985     jamis.projects.reload # causing the collection to load 
    1986     action_controller = Project.find(2) 
    1987     assert_equal 1, jamis.projects.size 
    1988     assert_equal 1, action_controller.developers.size 
    1989  
    1990     jamis.projects << action_controller 
    1991  
    1992     assert_equal 2, jamis.projects.size 
    1993     assert_equal 2, jamis.projects(true).size 
    1994     assert_equal 2, action_controller.developers(true).size 
    1995   end 
    1996  
    1997   def test_adding_type_mismatch 
    1998     jamis = Developer.find(2) 
    1999     assert_raise(ActiveRecord::AssociationTypeMismatch) { jamis.projects << nil } 
    2000     assert_raise(ActiveRecord::AssociationTypeMismatch) { jamis.projects << 1 } 
    2001   end 
    2002  
    2003   def test_adding_from_the_project 
    2004     jamis = Developer.find(2) 
    2005     action_controller = Project.find(2) 
    2006     action_controller.developers.reload 
    2007     assert_equal 1, jamis.projects.size 
    2008     assert_equal 1, action_controller.developers.size 
    2009  
    2010     action_controller.developers << jamis 
    2011  
    2012     assert_equal 2, jamis.projects(true).size 
    2013     assert_equal 2, action_controller.developers.size 
    2014     assert_equal 2, action_controller.developers(true).size 
    2015   end 
    2016  
    2017   def test_adding_from_the_project_fixed_timestamp 
    2018     jamis = Developer.find(2) 
    2019     action_controller = Project.find(2) 
    2020     action_controller.developers.reload 
    2021     assert_equal 1, jamis.projects.size 
    2022     assert_equal 1, action_controller.developers.size 
    2023     updated_at = jamis.updated_at 
    2024  
    2025     action_controller.developers << jamis 
    2026  
    2027     assert_equal updated_at, jamis.updated_at 
    2028     assert_equal 2, jamis.projects(true).size 
    2029     assert_equal 2, action_controller.developers.size 
    2030     assert_equal 2, action_controller.developers(true).size 
    2031   end 
    2032  
    2033   def test_adding_multiple 
    2034     aredridel = Developer.new("name" => "Aredridel") 
    2035     aredridel.save 
    2036     aredridel.projects.reload 
    2037     aredridel.projects.push(Project.find(1), Project.find(2)) 
    2038     assert_equal 2, aredridel.projects.size 
    2039     assert_equal 2, aredridel.projects(true).size 
    2040   end 
    2041  
    2042   def test_adding_a_collection 
    2043     aredridel = Developer.new("name" => "Aredridel") 
    2044     aredridel.save 
    2045     aredridel.projects.reload 
    2046     aredridel.projects.concat([Project.find(1), Project.find(2)]) 
    2047     assert_equal 2, aredridel.projects.size 
    2048     assert_equal 2, aredridel.projects(true).size 
    2049   end 
    2050  
    2051   def test_adding_uses_default_values_on_join_table 
    2052     ac = projects(:action_controller) 
    2053     assert !developers(:jamis).projects.include?(ac) 
    2054     developers(:jamis).projects << ac 
    2055  
    2056     assert developers(:jamis, :reload).projects.include?(ac) 
    2057     project = developers(:jamis).projects.detect { |p| p == ac } 
    2058     assert_equal 1, project.access_level.to_i 
    2059   end 
    2060  
    2061   def test_habtm_attribute_access_and_respond_to 
    2062     project = developers(:jamis).projects[0] 
    2063     assert project.has_attribute?("name") 
    2064     assert project.has_attribute?("joined_on") 
    2065     assert project.has_attribute?("access_level") 
    2066     assert project.respond_to?("name") 
    2067     assert project.respond_to?("name=") 
    2068     assert project.respond_to?("name?") 
    2069     assert project.respond_to?("joined_on") 
    2070     # given that the 'join attribute' won't be persisted, I don't 
    2071     # think we should define the mutators 
    2072     #assert project.respond_to?("joined_on=") 
    2073     assert project.respond_to?("joined_on?") 
    2074     assert project.respond_to?("access_level") 
    2075     #assert project.respond_to?("access_level=") 
    2076     assert project.respond_to?("access_level?") 
    2077   end 
    2078  
    2079   def test_habtm_adding_before_save 
    2080     no_of_devels = Developer.count 
    2081     no_of_projects = Project.count 
    2082     aredridel = Developer.new("name" => "Aredridel") 
    2083     aredridel.projects.concat([Project.find(1), p = Project.new("name" => "Projekt")]) 
    2084     assert aredridel.new_record? 
    2085     assert p.new_record? 
    2086     assert aredridel.save 
    2087     assert !aredridel.new_record? 
    2088     assert_equal no_of_devels+1, Developer.count 
    2089     assert_equal no_of_projects+1, Project.count 
    2090     assert_equal 2, aredridel.projects.size 
    2091     assert_equal 2, aredridel.projects(true).size 
    2092   end 
    2093  
    2094   def test_habtm_saving_multiple_relationships 
    2095     new_project = Project.new("name" => "Grimetime") 
    2096     amount_of_developers = 4 
    2097     developers = (0...amount_of_developers).collect {|i| Developer.create(:name => "JME #{i}") }.reverse 
    2098  
    2099     new_project.developer_ids = [developers[0].id, developers[1].id] 
    2100     new_project.developers_with_callback_ids = [developers[2].id, developers[3].id] 
    2101     assert new_project.save 
    2102  
    2103     new_project.reload 
    2104     assert_equal amount_of_developers, new_project.developers.size 
    2105     assert_equal developers, new_project.developers 
    2106   end 
    2107  
    2108   def test_habtm_unique_order_preserved 
    2109     assert_equal developers(:poor_jamis, :jamis, :david), projects(:active_record).non_unique_developers 
    2110     assert_equal developers(:poor_jamis, :jamis, :david), projects(:active_record).developers 
    2111   end 
    2112  
    2113   def test_build 
    2114     devel = Developer.find(1) 
    2115     proj = assert_no_queries { devel.projects.build("name" => "Projekt") } 
    2116     assert !devel.projects.loaded? 
    2117      
    2118     assert_equal devel.projects.last, proj 
    2119     assert devel.projects.loaded? 
    2120      
    2121     assert proj.new_record? 
    2122     devel.save 
    2123     assert !proj.new_record? 
    2124     assert_equal devel.projects.last, proj 
    2125     assert_equal Developer.find(1).projects.sort_by(&:id).last, proj  # prove join table is updated 
    2126   end 
    2127  
    2128   def test_build_by_new_record 
    2129     devel = Developer.new(:name => "Marcel", :salary => 75000) 
    2130     proj1 = devel.projects.build(:name => "Make bed") 
    2131     proj2 = devel.projects.build(:name => "Lie in it") 
    2132     assert_equal devel.projects.last, proj2 
    2133     assert proj2.new_record? 
    2134     devel.save 
    2135     assert !devel.new_record? 
    2136     assert !proj2.new_record? 
    2137     assert_equal devel.projects.last, proj2 
    2138     assert_equal Developer.find_by_name("Marcel").projects.last, proj2  # prove join table is updated 
    2139   end 
    2140  
    2141   def test_create 
    2142     devel = Developer.find(1) 
    2143     proj = devel.projects.create("name" => "Projekt") 
    2144     assert !devel.projects.loaded? 
    2145      
    2146     assert_equal devel.projects.last, proj 
    2147     assert devel.projects.loaded? 
    2148      
    2149     assert !proj.new_record? 
    2150     assert_equal Developer.find(1).projects.sort_by(&:id).last, proj  # prove join table is updated 
    2151   end 
    2152  
    2153   def test_create_by_new_record 
    2154     devel = Developer.new(:name => "Marcel", :salary => 75000) 
    2155     proj1 = devel.projects.build(:name => "Make bed") 
    2156     proj2 = devel.projects.build(:name => "Lie in it") 
    2157     assert_equal devel.projects.last, proj2 
    2158     assert proj2.new_record? 
    2159     devel.save 
    2160     assert !devel.new_record? 
    2161     assert !proj2.new_record? 
    2162     assert_equal devel.projects.last, proj2 
    2163     assert_equal Developer.find_by_name("Marcel").projects.last, proj2  # prove join table is updated 
    2164   end 
    2165  
    2166   def test_creation_respects_hash_condition 
    2167     post = categories(:general).post_with_conditions.build(:body => '') 
    2168      
    2169     assert        post.save 
    2170     assert_equal  'Yet Another Testing Title', post.title 
    2171      
    2172     another_post = categories(:general).post_with_conditions.create(:body => '') 
    2173  
    2174     assert        !another_post.new_record? 
    2175     assert_equal  'Yet Another Testing Title', another_post.title 
    2176   end 
    2177  
    2178   def test_uniq_after_the_fact 
    2179     dev = developers(:jamis) 
    2180     dev.projects << projects(:active_record) 
    2181     dev.projects << projects(:active_record) 
    2182      
    2183     assert_equal 3, dev.projects.size 
    2184     assert_equal 1, dev.projects.uniq.size 
    2185   end 
    2186  
    2187   def test_uniq_before_the_fact 
    2188     projects(:active_record).developers << developers(:jamis) 
    2189     projects(:active_record).developers << developers(:david) 
    2190     assert_equal 3, projects(:active_record, :reload).developers.size 
    2191   end 
    2192  
    2193   def test_deleting 
    2194     david = Developer.find(1) 
    2195     active_record = Project.find(1) 
    2196     david.projects.reload 
    2197     assert_equal 2, david.projects.size 
    2198     assert_equal 3, active_record.developers.size 
    2199  
    2200     david.projects.delete(active_record) 
    2201  
    2202     assert_equal 1, david.projects.size 
    2203     assert_equal 1, david.projects(true).size 
    2204     assert_equal 2, active_record.developers(true).size 
    2205   end 
    2206  
    2207   def test_deleting_array 
    2208     david = Developer.find(1) 
    2209     david.projects.reload 
    2210     david.projects.delete(Project.find(:all)) 
    2211     assert_equal 0, david.projects.size 
    2212     assert_equal 0, david.projects(true).size 
    2213   end 
    2214  
    2215   def test_deleting_with_sql 
    2216     david = Developer.find(1) 
    2217     active_record = Project.find(1) 
    2218     active_record.developers.reload 
    2219     assert_equal 3, active_record.developers_by_sql.size 
    2220  
    2221     active_record.developers_by_sql.delete(david) 
    2222     assert_equal 2, active_record.developers_by_sql(true).size 
    2223   end 
    2224  
    2225   def test_deleting_array_with_sql 
    2226     active_record = Project.find(1) 
    2227     active_record.developers.reload 
    2228     assert_equal 3, active_record.developers_by_sql.size 
    2229  
    2230     active_record.developers_by_sql.delete(Developer.find(:all)) 
    2231     assert_equal 0, active_record.developers_by_sql(true).size 
    2232   end 
    2233  
    2234   def test_deleting_all 
    2235     david = Developer.find(1) 
    2236     david.projects.reload 
    2237     david.projects.clear 
    2238     assert_equal 0, david.projects.size 
    2239     assert_equal 0, david.projects(true).size 
    2240   end 
    2241  
    2242   def test_removing_associations_on_destroy 
    2243     david = DeveloperWithBeforeDestroyRaise.find(1) 
    2244     assert !david.projects.empty? 
    2245     assert_nothing_raised { david.destroy } 
    2246     assert david.projects.empty? 
    2247     assert DeveloperWithBeforeDestroyRaise.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = 1").empty? 
    2248   end 
    2249  
    2250   def test_additional_columns_from_join_table 
    2251     assert_date_from_db Date.new(2004, 10, 10), Developer.find(1).projects.first.joined_on.to_date 
    2252   end 
    2253  
    2254   def test_destroy_all 
    2255     david = Developer.find(1) 
    2256     david.projects.reload 
    2257     assert !david.projects.empty? 
    2258     david.projects.destroy_all 
    2259     assert david.projects.empty? 
    2260     assert david.projects(true).empty? 
    2261   end 
    2262  
    2263   def test_deprecated_push_with_attributes_was_removed 
    2264     jamis = developers(:jamis) 
    2265     assert_raise(NoMethodError) do 
    2266       jamis.projects.push_with_attributes(projects(:action_controller), :joined_on => Date.today) 
    2267     end 
    2268   end 
    2269  
    2270   def test_associations_with_conditions 
    2271     assert_equal 3, projects(:active_record).developers.size 
    2272     assert_equal 1, projects(:active_record).developers_named_david.size 
    2273     assert_equal 1, projects(:active_record).developers_named_david_with_hash_conditions.size 
    2274  
    2275     assert_equal developers(:david), projects(:active_record).developers_named_david.find(developers(:david).id) 
    2276     assert_equal developers(:david), projects(:active_record).developers_named_david_with_hash_conditions.find(developers(:david).id) 
    2277     assert_equal developers(:david), projects(:active_record).salaried_developers.find(developers(:david).id) 
    2278  
    2279     projects(:active_record).developers_named_david.clear 
    2280     assert_equal 2, projects(:active_record, :reload).developers.size 
    2281   end 
    2282  
    2283   def test_find_in_association 
    2284     # Using sql 
    2285     assert_equal developers(:david), projects(:active_record).developers.find(developers(:david).id), "SQL find" 
    2286  
    2287     # Using ruby 
    2288     active_record = projects(:active_record) 
    2289     active_record.developers.reload 
    2290     assert_equal developers(:david), active_record.developers.find(developers(:david).id), "Ruby find" 
    2291   end 
    2292  
    2293   def test_include_uses_array_include_after_loaded 
    2294     project = projects(:active_record) 
    2295     developer = project.developers.first 
    2296      
    2297     assert_no_queries do 
    2298       assert project.developers.loaded? 
    2299       assert project.developers.include?(developer) 
    2300     end 
    2301   end 
    2302    
    2303   def test_include_checks_if_record_exists_if_target_not_loaded 
    2304     project = projects(:active_record) 
    2305     developer = project.developers.first 
    2306  
    2307     project.reload 
    2308     assert ! project.developers.loaded? 
    2309     assert_queries(1) do 
    2310       assert project.developers.include?(developer) 
    2311     end 
    2312     assert ! project.developers.loaded? 
    2313   end 
    2314  
    2315   def test_include_returns_false_for_non_matching_record_to_verify_scoping 
    2316     project = projects(:active_record) 
    2317     developer = Developer.create :name => "Bryan", :salary => 50_000 
    2318  
    2319     assert ! project.developers.loaded? 
    2320     assert ! project.developers.include?(developer) 
    2321   end 
    2322  
    2323   def test_find_in_association_with_custom_finder_sql 
    2324     assert_equal developers(:david), projects(:active_record).developers_with_finder_sql.find(developers(:david).id), "SQL find" 
    2325  
    2326     active_record = projects(:active_record) 
    2327     active_record.developers_with_finder_sql.reload 
    2328     assert_equal developers(:david), active_record.developers_with_finder_sql.find(developers(:david).id), "Ruby find" 
    2329   end 
    2330  
    2331   def test_find_in_association_with_custom_finder_sql_and_string_id 
    2332     assert_equal developers(:david), projects(:active_record).developers_with_finder_sql.find(developers(:david).id.to_s), "SQL find" 
    2333   end 
    2334  
    2335   def test_find_with_merged_options 
    2336     assert_equal 1, projects(:active_record).limited_developers.size 
    2337     assert_equal 1, projects(:active_record).limited_developers.find(:all).size 
    2338     assert_equal 3, projects(:active_record).limited_developers.find(:all, :limit => nil).size 
    2339   end 
    2340  
    2341   def test_dynamic_find_should_respect_association_order 
    2342     # Developers are ordered 'name DESC, id DESC' 
    2343     low_id_jamis = developers(:jamis) 
    2344     middle_id_jamis = developers(:poor_jamis) 
    2345     high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis') 
    2346  
    2347     assert_equal high_id_jamis, projects(:active_record).developers.find(:first, :conditions => "name = 'Jamis'") 
    2348     assert_equal high_id_jamis, projects(:active_record).developers.find_by_name('Jamis') 
    2349   end 
    2350  
    2351   def test_dynamic_find_order_should_override_association_order 
    2352     # Developers are ordered 'name DESC, id DESC' 
    2353     low_id_jamis = developers(:jamis) 
    2354     middle_id_jamis = developers(:poor_jamis) 
    2355     high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis') 
    2356  
    2357     assert_equal low_id_jamis, projects(:active_record).developers.find(:first, :conditions => "name = 'Jamis'", :order => 'id') 
    2358     assert_equal low_id_jamis, projects(:active_record).developers.find_by_name('Jamis', :order => 'id') 
    2359   end 
    2360  
    2361   def test_dynamic_find_all_should_respect_association_order 
    2362     # Developers are ordered 'name DESC, id DESC' 
    2363     low_id_jamis = developers(:jamis) 
    2364     middle_id_jamis = developers(:poor_jamis) 
    2365     high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis') 
    2366  
    2367     assert_equal [high_id_jamis, middle_id_jamis, low_id_jamis], projects(:active_record).developers.find(:all, :conditions => "name = 'Jamis'") 
    2368     assert_equal [high_id_jamis, middle_id_jamis, low_id_jamis], projects(:active_record).developers.find_all_by_name('Jamis') 
    2369   end 
    2370  
    2371   def test_dynamic_find_all_order_should_override_association_order 
    2372     # Developers are ordered 'name DESC, id DESC' 
    2373     low_id_jamis = developers(:jamis) 
    2374     middle_id_jamis = developers(:poor_jamis) 
    2375     high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis') 
    2376  
    2377     assert_equal [low_id_jamis, middle_id_jamis, high_id_jamis], projects(:active_record).developers.find(:all, :conditions => "name = 'Jamis'", :order => 'id') 
    2378     assert_equal [low_id_jamis, middle_id_jamis, high_id_jamis], projects(:active_record).developers.find_all_by_name('Jamis', :order => 'id') 
    2379   end 
    2380  
    2381   def test_dynamic_find_all_should_respect_association_limit 
    2382     assert_equal 1, projects(:active_record).limited_developers.find(:all, :conditions => "name = 'Jamis'").length 
    2383     assert_equal 1, projects(:active_record).limited_developers.find_all_by_name('Jamis').length 
    2384   end 
    2385  
    2386   def test_dynamic_find_all_order_should_override_association_limit 
    2387     assert_equal 2, projects(:active_record).limited_developers.find(:all, :conditions => "name = 'Jamis'", :limit => 9_000).length 
    2388     assert_equal 2, projects(:active_record).limited_developers.find_all_by_name('Jamis', :limit => 9_000).length 
    2389   end 
    2390  
    2391   def test_dynamic_find_all_should_respect_readonly_access 
    2392     projects(:active_record).readonly_developers.each { |d| assert_raise(ActiveRecord::ReadOnlyRecord) { d.save!  } if d.valid?} 
    2393     projects(:active_record).readonly_developers.each { |d| d.readonly? } 
    2394   end 
    2395  
    2396   def test_new_with_values_in_collection 
    2397     jamis = DeveloperForProjectWithAfterCreateHook.find_by_name('Jamis') 
    2398     david = DeveloperForProjectWithAfterCreateHook.find_by_name('David') 
    2399     project = ProjectWithAfterCreateHook.new(:name => "Cooking with Bertie") 
    2400     project.developers << jamis 
    2401     project.save! 
    2402     project.reload 
    2403  
    2404     assert project.developers.include?(jamis) 
    2405     assert project.developers.include?(david) 
    2406   end 
    2407  
    2408   def test_find_in_association_with_options 
    2409     developers = projects(:active_record).developers.find(:all) 
    2410     assert_equal 3, developers.size 
    2411  
    2412     assert_equal developers(:poor_jamis), projects(:active_record).developers.find(:first, :conditions => "salary < 10000") 
    2413     assert_equal developers(:jamis),      projects(:active_record).developers.find(:first, :order => "salary DESC") 
    2414   end 
    2415  
    2416   def test_replace_with_less 
    2417     david = developers(:david) 
    2418     david.projects = [projects(:action_controller)] 
    2419     assert david.save 
    2420     assert_equal 1, david.projects.length 
    2421   end 
    2422  
    2423   def test_replace_with_new 
    2424     david = developers(:david) 
    2425     david.projects = [projects(:action_controller), Project.new("name" => "ActionWebSearch")] 
    2426     david.save 
    2427     assert_equal 2, david.projects.length 
    2428     assert !david.projects.include?(projects(:active_record)) 
    2429   end 
    2430  
    2431   def test_replace_on_new_object 
    2432     new_developer = Developer.new("name" => "Matz") 
    2433     new_developer.projects = [projects(:action_controller), Project.new("name" => "ActionWebSearch")] 
    2434     new_developer.save 
    2435     assert_equal 2, new_developer.projects.length 
    2436   end 
    2437  
    2438   def test_consider_type 
    2439     developer = Developer.find(:first) 
    2440     special_project = SpecialProject.create("name" => "Special Project") 
    2441  
    2442     other_project = developer.projects.first 
    2443     developer.special_projects << special_project 
    2444     developer.reload 
    2445  
    2446     assert developer.projects.include?(special_project) 
    2447     assert developer.special_projects.include?(special_project) 
    2448     assert !developer.special_projects.include?(other_project) 
    2449   end 
    2450  
    2451   def test_update_attributes_after_push_without_duplicate_join_table_rows 
    2452     developer = Developer.new("name" => "Kano") 
    2453     project = SpecialProject.create("name" => "Special Project") 
    2454     assert developer.save 
    2455     developer.projects << project 
    2456     developer.update_attribute("name", "Bruza") 
    2457     assert_equal 1, Developer.connection.select_value(<<-end_sql).to_i 
    2458       SELECT count(*) FROM developers_projects 
    2459       WHERE project_id = #{project.id} 
    2460       AND developer_id = #{developer.id} 
    2461     end_sql 
    2462   end 
    2463  
    2464   def test_updating_attributes_on_non_rich_associations 
    2465     welcome = categories(:technology).posts.first 
    2466     welcome.title = "Something else" 
    2467     assert welcome.save! 
    2468   end 
    2469  
    2470   def test_habtm_respects_select 
    2471     categories(:technology).select_testing_posts(true).each do |o| 
    2472       assert_respond_to o, :correctness_marker 
    2473     end 
    2474     assert_respond_to categories(:technology).select_testing_posts.find(:first), :correctness_marker 
    2475   end 
    2476  
    2477   def test_updating_attributes_on_rich_associations 
    2478     david = projects(:action_controller).developers.first 
    2479     david.name = "DHH" 
    2480     assert_raises(ActiveRecord::ReadOnlyRecord) { david.save! } 
    2481   end 
    2482  
    2483   def test_updating_attributes_on_rich_associations_with_limited_find_from_reflection 
    2484     david = projects(:action_controller).selected_developers.first 
    2485     david.name = "DHH" 
    2486     assert_nothing_raised { david.save! } 
    2487   end 
    2488  
    2489  
    2490   def test_updating_attributes_on_rich_associations_with_limited_find 
    2491     david = projects(:action_controller).developers.find(:all, :select => "developers.*").first 
    2492     david.name = "DHH" 
    2493     assert david.save! 
    2494   end 
    2495  
    2496   def test_join_table_alias 
    2497     assert_equal 3, Developer.find(:all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL').size 
    2498   end 
    2499  
    2500   def test_join_with_group 
    2501     group = Developer.columns.inject([]) do |g, c| 
    2502       g << "developers.#{c.name}" 
    2503       g << "developers_projects_2.#{c.name}" 
    2504     end 
    2505     Project.columns.each { |c| group << "projects.#{c.name}" } 
    2506  
    2507     assert_equal 3, Developer.find(:all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL', :group => group.join(",")).size 
    2508   end 
    2509  
    2510   def test_get_ids 
    2511     assert_equal projects(:active_record, :action_controller).map(&:id).sort, developers(:david).project_ids.sort 
    2512     assert_equal [projects(:active_record).id], developers(:jamis).project_ids 
    2513   end 
    2514  
    2515   def test_assign_ids 
    2516     developer = Developer.new("name" => "Joe") 
    2517     developer.project_ids = projects(:active_record, :action_controller).map(&:id) 
    2518     developer.save 
    2519     developer.reload 
    2520     assert_equal 2, developer.projects.length 
    2521     assert_equal projects(:active_record), developer.projects[0] 
    2522     assert_equal projects(:action_controller), developer.projects[1] 
    2523   end 
    2524  
    2525   def test_assign_ids_ignoring_blanks 
    2526     developer = Developer.new("name" => "Joe") 
    2527     developer.project_ids = [projects(:active_record).id, nil, projects(:action_controller).id, ''] 
    2528     developer.save 
    2529     developer.reload 
    2530     assert_equal 2, developer.projects.length 
    2531     assert_equal projects(:active_record), developer.projects[0] 
    2532     assert_equal projects(:action_controller), developer.projects[1] 
    2533   end 
    2534  
    2535   def test_select_limited_ids_list 
    2536     # Set timestamps 
    2537     Developer.transaction do 
    2538       Developer.find(:all, :order => 'id').each_with_index do |record, i| 
    2539         record.update_attributes(:created_at => 5.years.ago + (i * 5.minutes)) 
    2540       end 
    2541     end 
    2542  
    2543     join_base = ActiveRecord::Associations::ClassMethods::JoinDependency::JoinBase.new(Project) 
    2544     join_dep  = ActiveRecord::Associations::ClassMethods::JoinDependency.new(join_base, :developers, nil) 
    2545     projects  = Project.send(:select_limited_ids_list, {:order => 'developers.created_at'}, join_dep) 
    2546     assert !projects.include?("'"), projects 
    2547     assert_equal %w(1 2), projects.scan(/\d/).sort 
    2548   end 
    2549  
    2550   def test_scoped_find_on_through_association_doesnt_return_read_only_records 
    2551     tag = Post.find(1).tags.find_by_name("General") 
    2552  
    2553     assert_nothing_raised do 
    2554       tag.save! 
    2555     end 
    2556   end 
    2557  
    2558   def test_has_many_through_polymorphic_has_manys_works 
    2559     assert_equal [10, 20].to_set, pirates(:redbeard).treasure_estimates.map(&:price).to_set 
    2560   end 
    2561 end 
    2562  
    2563  
    2564182class OverridingAssociationsTest < ActiveRecord::TestCase 
    2565183  class Person < ActiveRecord::Base; end