diff options
Diffstat (limited to 'activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb')
-rw-r--r-- | activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb | 206 |
1 files changed, 69 insertions, 137 deletions
diff --git a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb index ed7d9a782c..73d02c9676 100644 --- a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb @@ -72,7 +72,7 @@ class DeveloperWithCounterSQL < ActiveRecord::Base :join_table => "developers_projects", :association_foreign_key => "project_id", :foreign_key => "developer_id", - :counter_sql => 'SELECT COUNT(*) AS count_all FROM projects INNER JOIN developers_projects ON projects.id = developers_projects.project_id WHERE developers_projects.developer_id =#{id}' + :counter_sql => proc { "SELECT COUNT(*) AS count_all FROM projects INNER JOIN developers_projects ON projects.id = developers_projects.project_id WHERE developers_projects.developer_id =#{id}" } end class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase @@ -101,38 +101,6 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase assert_equal 't1', record[1] end - def test_should_record_timestamp_for_join_table - setup_data_for_habtm_case - - con = ActiveRecord::Base.connection - sql = 'select * from countries_treaties' - record = con.select_rows(sql).last - assert_not_nil record[2] - assert_not_nil record[3] - if current_adapter?(:Mysql2Adapter) - assert_match %r{\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}}, record[2].to_s(:db) - assert_match %r{\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}}, record[3].to_s(:db) - else - assert_match %r{\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}}, record[2] - assert_match %r{\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}}, record[3] - end - end - - def test_should_record_timestamp_for_join_table_only_if_timestamp_should_be_recorded - begin - Treaty.record_timestamps = false - setup_data_for_habtm_case - - con = ActiveRecord::Base.connection - sql = 'select * from countries_treaties' - record = con.select_rows(sql).last - assert_nil record[2] - assert_nil record[3] - ensure - Treaty.record_timestamps = true - end - end - def test_has_and_belongs_to_many david = Developer.find(1) @@ -218,43 +186,15 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase assert_equal 2, aredridel.projects(true).size end - def test_adding_uses_default_values_on_join_table - ac = projects(:action_controller) - assert !developers(:jamis).projects.include?(ac) - developers(:jamis).projects << ac - - assert developers(:jamis, :reload).projects.include?(ac) - project = developers(:jamis).projects.detect { |p| p == ac } - assert_equal 1, project.access_level.to_i - end - - def test_habtm_attribute_access_and_respond_to - project = developers(:jamis).projects[0] - assert project.has_attribute?("name") - assert project.has_attribute?("joined_on") - assert project.has_attribute?("access_level") - assert project.respond_to?("name") - assert project.respond_to?("name=") - assert project.respond_to?("name?") - assert project.respond_to?("joined_on") - # given that the 'join attribute' won't be persisted, I don't - # think we should define the mutators - #assert project.respond_to?("joined_on=") - assert project.respond_to?("joined_on?") - assert project.respond_to?("access_level") - #assert project.respond_to?("access_level=") - assert project.respond_to?("access_level?") - end - def test_habtm_adding_before_save no_of_devels = Developer.count no_of_projects = Project.count aredridel = Developer.new("name" => "Aredridel") aredridel.projects.concat([Project.find(1), p = Project.new("name" => "Projekt")]) - assert aredridel.new_record? - assert p.new_record? + assert !aredridel.persisted? + assert !p.persisted? assert aredridel.save - assert !aredridel.new_record? + assert aredridel.persisted? assert_equal no_of_devels+1, Developer.count assert_equal no_of_projects+1, Project.count assert_equal 2, aredridel.projects.size @@ -288,22 +228,22 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase assert_equal devel.projects.last, proj assert devel.projects.loaded? - assert proj.new_record? + assert !proj.persisted? devel.save - assert !proj.new_record? + assert proj.persisted? assert_equal devel.projects.last, proj assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated end def test_build_by_new_record devel = Developer.new(:name => "Marcel", :salary => 75000) - proj1 = devel.projects.build(:name => "Make bed") + devel.projects.build(:name => "Make bed") proj2 = devel.projects.build(:name => "Lie in it") assert_equal devel.projects.last, proj2 - assert proj2.new_record? + assert !proj2.persisted? devel.save - assert !devel.new_record? - assert !proj2.new_record? + assert devel.persisted? + assert proj2.persisted? assert_equal devel.projects.last, proj2 assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated end @@ -316,19 +256,19 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase assert_equal devel.projects.last, proj assert !devel.projects.loaded? - assert !proj.new_record? + assert proj.persisted? assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated end def test_create_by_new_record devel = Developer.new(:name => "Marcel", :salary => 75000) - proj1 = devel.projects.build(:name => "Make bed") + devel.projects.build(:name => "Make bed") proj2 = devel.projects.build(:name => "Lie in it") assert_equal devel.projects.last, proj2 - assert proj2.new_record? + assert !proj2.persisted? devel.save - assert !devel.new_record? - assert !proj2.new_record? + assert devel.persisted? + assert proj2.persisted? assert_equal devel.projects.last, proj2 assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated end @@ -343,7 +283,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase # in Oracle '' is saved as null therefore need to save ' ' in not null column another_post = categories(:general).post_with_conditions.create(:body => ' ') - assert !another_post.new_record? + assert another_post.persisted? assert_equal 'Yet Another Testing Title', another_post.title end @@ -425,38 +365,41 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase def test_removing_associations_on_destroy david = DeveloperWithBeforeDestroyRaise.find(1) assert !david.projects.empty? - assert_nothing_raised { david.destroy } + david.destroy assert david.projects.empty? assert DeveloperWithBeforeDestroyRaise.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = 1").empty? end - def test_additional_columns_from_join_table - assert_date_from_db Date.new(2004, 10, 10), Developer.find(1).projects.first.joined_on.to_date - end - def test_destroying david = Developer.find(1) - active_record = Project.find(1) + project = Project.find(1) david.projects.reload assert_equal 2, david.projects.size - assert_equal 3, active_record.developers.size + assert_equal 3, project.developers.size - assert_difference "Project.count", -1 do - david.projects.destroy(active_record) + assert_no_difference "Project.count" do + david.projects.destroy(project) end + join_records = Developer.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = #{david.id} AND project_id = #{project.id}") + assert join_records.empty? + assert_equal 1, david.reload.projects.size assert_equal 1, david.projects(true).size end - def test_destroying_array + def test_destroying_many david = Developer.find(1) david.projects.reload + projects = Project.all - assert_difference "Project.count", -Project.count do - david.projects.destroy(Project.find(:all)) + assert_no_difference "Project.count" do + david.projects.destroy(*projects) end + join_records = Developer.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = #{david.id}") + assert join_records.empty? + assert_equal 0, david.reload.projects.size assert_equal 0, david.projects(true).size end @@ -465,7 +408,14 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase david = Developer.find(1) david.projects.reload assert !david.projects.empty? - david.projects.destroy_all + + assert_no_difference "Project.count" do + david.projects.destroy_all + end + + join_records = Developer.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = #{david.id}") + assert join_records.empty? + assert david.projects.empty? assert david.projects(true).empty? end @@ -559,24 +509,12 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase def test_dynamic_find_should_respect_association_order # Developers are ordered 'name DESC, id DESC' - low_id_jamis = developers(:jamis) - middle_id_jamis = developers(:poor_jamis) high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis') assert_equal high_id_jamis, projects(:active_record).developers.find(:first, :conditions => "name = 'Jamis'") assert_equal high_id_jamis, projects(:active_record).developers.find_by_name('Jamis') end - def test_dynamic_find_order_should_override_association_order - # Developers are ordered 'name DESC, id DESC' - low_id_jamis = developers(:jamis) - middle_id_jamis = developers(:poor_jamis) - high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis') - - assert_equal low_id_jamis, projects(:active_record).developers.find(:first, :conditions => "name = 'Jamis'", :order => 'id') - assert_equal low_id_jamis, projects(:active_record).developers.find_by_name('Jamis', :order => 'id') - end - def test_dynamic_find_all_should_respect_association_order # Developers are ordered 'name DESC, id DESC' low_id_jamis = developers(:jamis) @@ -587,14 +525,9 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase assert_equal [high_id_jamis, middle_id_jamis, low_id_jamis], projects(:active_record).developers.find_all_by_name('Jamis') end - def test_dynamic_find_all_order_should_override_association_order - # Developers are ordered 'name DESC, id DESC' - low_id_jamis = developers(:jamis) - middle_id_jamis = developers(:poor_jamis) - high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis') - - assert_equal [low_id_jamis, middle_id_jamis, high_id_jamis], projects(:active_record).developers.find(:all, :conditions => "name = 'Jamis'", :order => 'id') - assert_equal [low_id_jamis, middle_id_jamis, high_id_jamis], projects(:active_record).developers.find_all_by_name('Jamis', :order => 'id') + def test_find_should_append_to_association_order + ordered_developers = projects(:active_record).developers.order('projects.id') + assert_equal ['developers.name desc, developers.id desc', 'projects.id'], ordered_developers.order_values end def test_dynamic_find_all_should_respect_association_limit @@ -625,11 +558,10 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase end def test_find_in_association_with_options - developers = projects(:active_record).developers.find(:all) + developers = projects(:active_record).developers.all assert_equal 3, developers.size - assert_equal developers(:poor_jamis), projects(:active_record).developers.find(:first, :conditions => "salary < 10000") - assert_equal developers(:jamis), projects(:active_record).developers.find(:first, :order => "salary DESC") + assert_equal developers(:poor_jamis), projects(:active_record).developers.where("salary < 10000").first end def test_replace_with_less @@ -693,25 +625,6 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase assert_respond_to categories(:technology).select_testing_posts.find(:first), :correctness_marker end - def test_updating_attributes_on_rich_associations - david = projects(:action_controller).developers.first - david.name = "DHH" - assert_raise(ActiveRecord::ReadOnlyRecord) { david.save! } - end - - def test_updating_attributes_on_rich_associations_with_limited_find_from_reflection - david = projects(:action_controller).selected_developers.first - david.name = "DHH" - assert_nothing_raised { david.save! } - end - - - def test_updating_attributes_on_rich_associations_with_limited_find - david = projects(:action_controller).developers.find(:all, :select => "developers.*").first - david.name = "DHH" - assert david.save! - end - def test_join_table_alias assert_equal 3, Developer.find(:all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL').size end @@ -729,12 +642,12 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase def test_find_grouped all_posts_from_category1 = Post.find(:all, :conditions => "category_id = 1", :joins => :categories) grouped_posts_of_category1 = Post.find(:all, :conditions => "category_id = 1", :group => "author_id", :select => 'count(posts.id) as posts_count', :joins => :categories) - assert_equal 4, all_posts_from_category1.size - assert_equal 1, grouped_posts_of_category1.size + assert_equal 5, all_posts_from_category1.size + assert_equal 2, grouped_posts_of_category1.size end def test_find_scoped_grouped - assert_equal 4, categories(:general).posts_grouped_by_title.size + assert_equal 5, categories(:general).posts_grouped_by_title.size assert_equal 1, categories(:technology).posts_grouped_by_title.size end @@ -858,10 +771,29 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase david = Developer.find(1) # clear cache possibly created by other tests david.projects.reset_column_information - assert_queries(0) { david.projects.columns; david.projects.columns } - # and again to verify that reset_column_information clears the cache correctly + + # One query for columns, one for primary key + assert_queries(2) { david.projects.columns; david.projects.columns } + + ## and again to verify that reset_column_information clears the cache correctly david.projects.reset_column_information - assert_queries(0) { david.projects.columns; david.projects.columns } + assert_queries(2) { david.projects.columns; david.projects.columns } + end + + def test_attributes_are_being_set_when_initialized_from_habm_association_with_where_clause + new_developer = projects(:action_controller).developers.where(:name => "Marcelo").build + assert_equal new_developer.name, "Marcelo" end + def test_attributes_are_being_set_when_initialized_from_habm_association_with_multiple_where_clauses + new_developer = projects(:action_controller).developers.where(:name => "Marcelo").where(:salary => 90_000).build + assert_equal new_developer.name, "Marcelo" + assert_equal new_developer.salary, 90_000 + end + + def test_include_method_in_has_and_belongs_to_many_association_should_return_true_for_instance_added_with_build + project = Project.new + developer = project.developers.build + assert project.developers.include?(developer) + end end |