mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Assert primary key does not exist in habtm when the association is defined, instead of doing that everytime a record is inserted.
[#3128 state:committed] Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
This commit is contained in:
parent
c5f6e038da
commit
da636809da
5 changed files with 16 additions and 45 deletions
|
@ -60,6 +60,12 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
class HasAndBelongsToManyAssociationWithPrimaryKeyError < ActiveRecordError #:nodoc:
|
||||
def initialize(reflection)
|
||||
super("Primary key is not allowed in a has_and_belongs_to_many join table (#{reflection.options[:join_table]}).")
|
||||
end
|
||||
end
|
||||
|
||||
class HasAndBelongsToManyAssociationForeignKeyNeeded < ActiveRecordError #:nodoc:
|
||||
def initialize(reflection)
|
||||
super("Cannot create self referential has_and_belongs_to_many association on '#{reflection.class_name rescue nil}##{reflection.name rescue nil}'. :association_foreign_key cannot be the same as the :foreign_key.")
|
||||
|
@ -1652,16 +1658,19 @@ module ActiveRecord
|
|||
|
||||
def create_has_and_belongs_to_many_reflection(association_id, options, &extension)
|
||||
options.assert_valid_keys(valid_keys_for_has_and_belongs_to_many_association)
|
||||
|
||||
options[:extend] = create_extension_modules(association_id, extension, options[:extend])
|
||||
|
||||
reflection = create_reflection(:has_and_belongs_to_many, association_id, options, self)
|
||||
|
||||
reflection.options[:join_table] ||= join_table_name(undecorated_table_name(self.to_s), undecorated_table_name(reflection.class_name))
|
||||
|
||||
if reflection.association_foreign_key == reflection.primary_key_name
|
||||
raise HasAndBelongsToManyAssociationForeignKeyNeeded.new(reflection)
|
||||
end
|
||||
|
||||
reflection.options[:join_table] ||= join_table_name(undecorated_table_name(self.to_s), undecorated_table_name(reflection.class_name))
|
||||
if connection.supports_primary_key? &&
|
||||
(connection.primary_key(reflection.options[:join_table]) rescue false)
|
||||
raise HasAndBelongsToManyAssociationWithPrimaryKeyError.new(reflection)
|
||||
end
|
||||
|
||||
reflection
|
||||
end
|
||||
|
@ -1670,15 +1679,6 @@ module ActiveRecord
|
|||
[ associations ].flatten.collect { |association| reflect_on_association(association.to_s.intern) }
|
||||
end
|
||||
|
||||
def guard_against_unlimitable_reflections(reflections, options)
|
||||
if (options[:offset] || options[:limit]) && !using_limitable_reflections?(reflections)
|
||||
raise(
|
||||
ConfigurationError,
|
||||
"You can not use offset and limit together with has_many or has_and_belongs_to_many associations"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def select_all_rows(options, join_dependency)
|
||||
connection.select_all(
|
||||
construct_finder_sql_with_included_associations(options, join_dependency),
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
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
|
||||
|
@ -22,12 +17,6 @@ module ActiveRecord
|
|||
@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
|
||||
|
@ -40,11 +29,6 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def insert_record(record, force = true, validate = true)
|
||||
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?
|
||||
if force
|
||||
record.save!
|
||||
|
|
|
@ -36,21 +36,9 @@ class HabtmJoinTableTest < ActiveRecord::TestCase
|
|||
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')
|
||||
assert_raise ActiveRecord::HasAndBelongsToManyAssociationWithPrimaryKeyError do
|
||||
MyReader.has_and_belongs_to_many :my_books
|
||||
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
|
||||
|
|
3
activerecord/test/fixtures/edges.yml
vendored
3
activerecord/test/fixtures/edges.yml
vendored
|
@ -1,6 +1,5 @@
|
|||
<% (1..4).each do |id| %>
|
||||
edge_<%= id %>:
|
||||
id: <%= id %>
|
||||
source_id: <%= id %>
|
||||
sink_id: <%= id + 1 %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
|
|
@ -159,7 +159,7 @@ ActiveRecord::Schema.define do
|
|||
t.integer :access_level, :default => 1
|
||||
end
|
||||
|
||||
create_table :edges, :force => true do |t|
|
||||
create_table :edges, :force => true, :id => false do |t|
|
||||
t.column :source_id, :integer, :null => false
|
||||
t.column :sink_id, :integer, :null => false
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue