Skip to content

Commit

Permalink
raises an exception on habtm join table inserts if join table contain…
Browse files Browse the repository at this point in the history
…s a primary key. Caches this check to save time on subsequent inserts.

[#2086 state:committed]

Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
  • Loading branch information
bellmyer authored and jeremy committed Aug 10, 2009
1 parent 9a3a798 commit 9d51f62
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 3 deletions.
@@ -1,6 +1,11 @@
module ActiveRecord
module Associations
class HasAndBelongsToManyAssociation < AssociationCollection #:nodoc:
def initialize(owner, reflection)
super
@primary_key_list = {}
end

def create(attributes = {})
create_record(attributes) { |record| insert_record(record) }
end
Expand All @@ -17,6 +22,12 @@ def reset_column_information
@reflection.reset_column_information
end

def has_primary_key?
return @has_primary_key unless @has_primary_key.nil?
@has_primary_key = (ActiveRecord::Base.connection.supports_primary_key? &&
ActiveRecord::Base.connection.primary_key(@reflection.options[:join_table]))
end

protected
def construct_find_options!(options)
options[:joins] = @join_sql
Expand All @@ -29,8 +40,9 @@ def count_records
end

def insert_record(record, force = true, validate = true)
if ActiveRecord::Base.connection.supports_primary_key? && ActiveRecord::Base.connection.primary_key(@reflection.options[:join_table])
raise ActiveRecord::ConfigurationError, "Primary key is not allowed in a has_and_belongs_to_many join table (#{@reflection.options[:join_table]})."
if has_primary_key?
raise ActiveRecord::ConfigurationError,
"Primary key is not allowed in a has_and_belongs_to_many join table (#{@reflection.options[:join_table]})."
end

if record.new_record?
Expand Down
13 changes: 12 additions & 1 deletion activerecord/test/cases/associations/habtm_join_table_test.rb
Expand Up @@ -8,7 +8,7 @@ class MyBook < ActiveRecord::Base
has_and_belongs_to_many :my_readers
end

class JoinTableTest < ActiveRecord::TestCase
class HabtmJoinTableTest < ActiveRecord::TestCase
def setup
ActiveRecord::Base.connection.create_table :my_books, :force => true do |t|
t.string :name
Expand Down Expand Up @@ -42,4 +42,15 @@ def test_should_raise_exception_when_join_table_has_a_primary_key
end
end
end

uses_transaction :test_should_cache_result_of_primary_key_check
def test_should_cache_result_of_primary_key_check
if ActiveRecord::Base.connection.supports_primary_key?
ActiveRecord::Base.connection.stubs(:primary_key).with('my_books_my_readers').returns(false).once
weaz = MyReader.create(:name=>'Weaz')

weaz.my_books << MyBook.create(:name=>'Great Expectations')
weaz.my_books << MyBook.create(:name=>'Greater Expectations')
end
end
end

0 comments on commit 9d51f62

Please sign in to comment.