From c896d56c6e5520346c260477f7d7f8bf951e72cc Mon Sep 17 00:00:00 2001 From: Tom Lea Date: Fri, 6 Mar 2009 18:26:34 +0000 Subject: [PATCH] Ensure self referential HABTM associations raise an exception if association_foreign_key is missing. [#1252 state:resolved] Signed-off-by: Pratik Naik --- activerecord/lib/active_record/associations.rb | 10 ++++++++++ .../has_and_belongs_to_many_associations_test.rb | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 6e88c89737..80b3e23026 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -51,6 +51,12 @@ module ActiveRecord 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.") + end + end + class EagerLoadPolymorphicError < ActiveRecordError #:nodoc: def initialize(reflection) super("Can not eagerly load the polymorphic association #{reflection.name.inspect}") @@ -1526,6 +1532,10 @@ module ActiveRecord options[:extend] = create_extension_modules(association_id, extension, options[:extend]) reflection = create_reflection(:has_and_belongs_to_many, association_id, options, self) + + 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)) 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 0f43d97f4a..9f5f34306d 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 @@ -740,6 +740,14 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase assert_equal developer, project.developers.find(:first) assert_equal project, developer.projects.find(:first) end + + def test_self_referential_habtm_without_foreign_key_set_should_raise_exception + assert_raise(ActiveRecord::HasAndBelongsToManyAssociationForeignKeyNeeded) { + Member.class_eval do + has_and_belongs_to_many :friends, :class_name => "Member", :join_table => "member_friends" + end + } + end def test_dynamic_find_should_respect_association_include # SQL error in sort clause if :include is not included