raises exception (ActiveRecord::ConfigurationError with message) on habtm association creation if join table contains a primary key
Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
This commit is contained in:
parent
d2d464e26e
commit
f0602214e0
@ -29,6 +29,10 @@ 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]})."
|
||||
end
|
||||
|
||||
if record.new_record?
|
||||
if force
|
||||
record.save!
|
||||
|
@ -56,6 +56,13 @@ def supports_migrations?
|
||||
false
|
||||
end
|
||||
|
||||
# Can this adapter determine the primary key for tables not attached
|
||||
# to an ActiveRecord class, such as join tables? Backend specific, as
|
||||
# the abstract adapter always returns +false+.
|
||||
def supports_primary_key?
|
||||
false
|
||||
end
|
||||
|
||||
# Does this adapter support using DISTINCT within COUNT? This is +true+
|
||||
# for all adapters except sqlite.
|
||||
def supports_count_distinct?
|
||||
|
@ -208,6 +208,10 @@ def supports_migrations? #:nodoc:
|
||||
true
|
||||
end
|
||||
|
||||
def supports_primary_key? #:nodoc:
|
||||
true
|
||||
end
|
||||
|
||||
def supports_savepoints? #:nodoc:
|
||||
true
|
||||
end
|
||||
@ -550,6 +554,12 @@ def pk_and_sequence_for(table) #:nodoc:
|
||||
keys.length == 1 ? [keys.first, nil] : nil
|
||||
end
|
||||
|
||||
# Returns just a table's primary key
|
||||
def primary_key(table)
|
||||
pk_and_sequence = pk_and_sequence_for(table)
|
||||
pk_and_sequence && pk_and_sequence.first
|
||||
end
|
||||
|
||||
def case_sensitive_equality_operator
|
||||
"= BINARY"
|
||||
end
|
||||
|
@ -250,6 +250,11 @@ def supports_migrations?
|
||||
true
|
||||
end
|
||||
|
||||
# Does PostgreSQL support finding primary key on non-ActiveRecord tables?
|
||||
def supports_primary_key? #:nodoc:
|
||||
true
|
||||
end
|
||||
|
||||
# Does PostgreSQL support standard conforming strings?
|
||||
def supports_standard_conforming_strings?
|
||||
# Temporarily set the client message level above error to prevent unintentional
|
||||
@ -811,6 +816,12 @@ def pk_and_sequence_for(table) #:nodoc:
|
||||
nil
|
||||
end
|
||||
|
||||
# Returns just a table's primary key
|
||||
def primary_key(table)
|
||||
pk_and_sequence = pk_and_sequence_for(table)
|
||||
pk_and_sequence && pk_and_sequence.first
|
||||
end
|
||||
|
||||
# Renames a table.
|
||||
def rename_table(name, new_name)
|
||||
execute "ALTER TABLE #{quote_table_name(name)} RENAME TO #{quote_table_name(new_name)}"
|
||||
|
@ -101,6 +101,10 @@ def supports_migrations? #:nodoc:
|
||||
true
|
||||
end
|
||||
|
||||
def supports_primary_key? #:nodoc:
|
||||
true
|
||||
end
|
||||
|
||||
def requires_reloading?
|
||||
true
|
||||
end
|
||||
|
@ -0,0 +1,45 @@
|
||||
require 'cases/helper'
|
||||
|
||||
class MyReader < ActiveRecord::Base
|
||||
has_and_belongs_to_many :my_books
|
||||
end
|
||||
|
||||
class MyBook < ActiveRecord::Base
|
||||
has_and_belongs_to_many :my_readers
|
||||
end
|
||||
|
||||
class JoinTableTest < ActiveRecord::TestCase
|
||||
def setup
|
||||
ActiveRecord::Base.connection.create_table :my_books, :force => true do |t|
|
||||
t.string :name
|
||||
end
|
||||
assert ActiveRecord::Base.connection.table_exists?(:my_books)
|
||||
|
||||
ActiveRecord::Base.connection.create_table :my_readers, :force => true do |t|
|
||||
t.string :name
|
||||
end
|
||||
assert ActiveRecord::Base.connection.table_exists?(:my_readers)
|
||||
|
||||
ActiveRecord::Base.connection.create_table :my_books_my_readers, :force => true do |t|
|
||||
t.integer :my_book_id
|
||||
t.integer :my_reader_id
|
||||
end
|
||||
assert ActiveRecord::Base.connection.table_exists?(:my_books_my_readers)
|
||||
end
|
||||
|
||||
def teardown
|
||||
ActiveRecord::Base.connection.drop_table :my_books
|
||||
ActiveRecord::Base.connection.drop_table :my_readers
|
||||
ActiveRecord::Base.connection.drop_table :my_books_my_readers
|
||||
end
|
||||
|
||||
uses_transaction :test_should_raise_exception_when_join_table_has_a_primary_key
|
||||
def test_should_raise_exception_when_join_table_has_a_primary_key
|
||||
if ActiveRecord::Base.connection.supports_primary_key?
|
||||
assert_raise ActiveRecord::ConfigurationError do
|
||||
jaime = MyReader.create(:name=>"Jaime")
|
||||
jaime.my_books << MyBook.create(:name=>'Great Expectations')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -98,4 +98,22 @@ def test_instance_update_should_quote_pkey
|
||||
def test_instance_destroy_should_quote_pkey
|
||||
assert_nothing_raised { MixedCaseMonkey.find(1).destroy }
|
||||
end
|
||||
|
||||
def test_supports_primary_key
|
||||
assert_nothing_raised NoMethodError do
|
||||
ActiveRecord::Base.connection.supports_primary_key?
|
||||
end
|
||||
end
|
||||
|
||||
def test_primary_key_returns_value_if_it_exists
|
||||
if ActiveRecord::Base.connection.supports_primary_key?
|
||||
assert_equal 'id', ActiveRecord::Base.connection.primary_key('developers')
|
||||
end
|
||||
end
|
||||
|
||||
def test_primary_key_returns_nil_if_it_does_not_exist
|
||||
if ActiveRecord::Base.connection.supports_primary_key?
|
||||
assert_nil ActiveRecord::Base.connection.primary_key('developers_projects')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user