aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Kemper <jeremy@bitsweat.net>2009-09-02 13:55:02 -0700
committerJeremy Kemper <jeremy@bitsweat.net>2009-09-02 13:55:47 -0700
commit3b6a9a020e7e6f71ab6f9ffcf1ef59c57437ca69 (patch)
tree90df5808a8788bf48c1079989d0171495a75e0d6
parent723a47bfb3708f968821bc969a9a3fc873a3ed58 (diff)
downloadrails-3b6a9a020e7e6f71ab6f9ffcf1ef59c57437ca69.tar.gz
rails-3b6a9a020e7e6f71ab6f9ffcf1ef59c57437ca69.tar.bz2
rails-3b6a9a020e7e6f71ab6f9ffcf1ef59c57437ca69.zip
Revert "Assert primary key does not exist in habtm when the association is defined, instead of doing that everytime a record is inserted."
Test failures on PostgreSQL. [#3128 state:open] This reverts commit da636809daca9c338200811d3590e446f57c8e81.
-rwxr-xr-xactiverecord/lib/active_record/associations.rb22
-rw-r--r--activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb16
-rw-r--r--activerecord/test/cases/associations/habtm_join_table_test.rb16
-rw-r--r--activerecord/test/fixtures/edges.yml3
-rw-r--r--activerecord/test/schema/schema.rb2
5 files changed, 44 insertions, 15 deletions
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index 1c20af9adb..02dfb7b400 100755
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -60,12 +60,6 @@ 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.")
@@ -1658,19 +1652,16 @@ 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
- if connection.supports_primary_key? &&
- (connection.primary_key(reflection.options[:join_table]) rescue false)
- raise HasAndBelongsToManyAssociationWithPrimaryKeyError.new(reflection)
- end
+ reflection.options[:join_table] ||= join_table_name(undecorated_table_name(self.to_s), undecorated_table_name(reflection.class_name))
reflection
end
@@ -1679,6 +1670,15 @@ 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),
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 fd23e59e82..d91c555dad 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
@@ -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
@@ -17,6 +22,12 @@ 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
@@ -29,6 +40,11 @@ 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!
diff --git a/activerecord/test/cases/associations/habtm_join_table_test.rb b/activerecord/test/cases/associations/habtm_join_table_test.rb
index 745f169ad7..bf3e04c3eb 100644
--- a/activerecord/test/cases/associations/habtm_join_table_test.rb
+++ b/activerecord/test/cases/associations/habtm_join_table_test.rb
@@ -36,9 +36,21 @@ 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::HasAndBelongsToManyAssociationWithPrimaryKeyError do
- MyReader.has_and_belongs_to_many :my_books
+ assert_raise ActiveRecord::ConfigurationError do
+ jaime = MyReader.create(:name=>"Jaime")
+ jaime.my_books << MyBook.create(:name=>'Great Expectations')
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
diff --git a/activerecord/test/fixtures/edges.yml b/activerecord/test/fixtures/edges.yml
index b804f7b6a6..c16c70dd2f 100644
--- a/activerecord/test/fixtures/edges.yml
+++ b/activerecord/test/fixtures/edges.yml
@@ -1,5 +1,6 @@
<% (1..4).each do |id| %>
edge_<%= id %>:
+ id: <%= id %>
source_id: <%= id %>
sink_id: <%= id + 1 %>
-<% end %>
+<% end %> \ No newline at end of file
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index 5c12cb1a0c..9ab4cf6f43 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -159,7 +159,7 @@ ActiveRecord::Schema.define do
t.integer :access_level, :default => 1
end
- create_table :edges, :force => true, :id => false do |t|
+ create_table :edges, :force => true do |t|
t.column :source_id, :integer, :null => false
t.column :sink_id, :integer, :null => false
end