From efd9e9e0b1d65c1fffb19ee0884577e903530c5d Mon Sep 17 00:00:00 2001 From: Jaime Bellmyer Date: Tue, 24 Feb 2009 23:57:56 -0600 Subject: [PATCH] primary keys on join tables no longer break habtm relationships --- .../has_and_belongs_to_many_association.rb | 4 ++- .../has_and_belongs_to_many_associations_test.rb | 36 ++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletions(-) diff --git a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb index a5cc3bf..931ea01 100644 --- a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb +++ b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb @@ -46,6 +46,8 @@ module ActiveRecord attrs[column.name] = owner_quoted_id when @reflection.association_foreign_key.to_s attrs[column.name] = record.quoted_id + when @owner.connection.primary_key(@reflection.options[:join_table]) + # skip # else if record.has_attribute?(column.name) value = @owner.send(:quote_value, record[column.name], column) @@ -57,7 +59,7 @@ module ActiveRecord sql = "INSERT INTO #{@owner.connection.quote_table_name @reflection.options[:join_table]} (#{@owner.send(:quoted_column_names, attributes).join(', ')}) " + - "VALUES (#{attributes.values.join(', ')})" + "VALUES (#{attributes.values.join(', ')}); #{[@reflection.primary_key_name, @reflection.association_foreign_key, record.has_attribute?('id')].join(',')}" @owner.connection.insert(sql) end 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 0f43d97..fb3358c 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 @@ -166,6 +166,42 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase assert_equal 2, aredridel.projects.size assert_equal 2, aredridel.projects(true).size end + + uses_transaction :test_adding_a_collection_when_join_table_has_primary_key + def test_adding_a_collection_when_join_table_has_primary_key + jaime = Developer.create(:name => "Jaime") + weaz = Developer.create(:name => "Weaz") + + # temporarily add a primary key to developers_projects table # + Developer.connection.drop_table :developers_projects + Developer.connection.create_table :developers_projects, :force => true do |t| + t.integer :developer_id, :null => false + t.integer :project_id, :null => false + t.date :joined_on + t.integer :access_level, :default => 1 + end + + assert_equal 0, jaime.projects.size + assert_equal 0, weaz.projects.size + + begin + jaime.projects << projects(:active_record) + weaz.projects << projects(:active_record) + rescue ActiveRecord::StatementInvalid + end + + assert_equal 1, jaime.projects.size + assert_equal 1, weaz.projects.size + + # remove temporary primary key # + Developer.connection.drop_table :developers_projects + Developer.connection.create_table :developers_projects, :force => true, :id => false do |t| + t.integer :developer_id, :null => false + t.integer :project_id, :null => false + t.date :joined_on + t.integer :access_level, :default => 1 + end + end def test_adding_uses_default_values_on_join_table ac = projects(:action_controller) -- 1.5.4.3