Permalink
Browse files

fk: `add_foreign_key` and `remove_foreign_key` for PostgreSQL adapter.

  • Loading branch information...
senny committed Jun 6, 2014
1 parent 5add8b8 commit e2ef25710682d884b2e6f5e99d47f18eb7083c68
@@ -233,6 +233,11 @@ def supports_indexes_in_create?
false
end
+ # Does this adapter support creating foreign key constraints?
+ def supports_foreign_keys?
+ false
+ end
+
# This is meant to be implemented by the adapters that support extensions
def disable_extension(name)
end
@@ -448,6 +448,33 @@ def rename_index(table_name, old_name, new_name)
execute "ALTER INDEX #{quote_column_name(old_name)} RENAME TO #{quote_table_name(new_name)}"
end
+ def add_foreign_key(from_table, to_table, options = {})
+ foreign_key_column = options.fetch(:column)
+ referenced_column = "id"
+ foreign_key_name = foreign_key_name(from_table, options)
+ execute <<-SQL
+ALTER TABLE #{quote_table_name(from_table)}
+ADD CONSTRAINT #{foreign_key_name}
+ FOREIGN KEY (#{quote_column_name(foreign_key_column)})
+ REFERENCES #{quote_table_name(to_table)} (#{quote_column_name(referenced_column)})
+ SQL
+ end
+
+ def remove_foreign_key(from_table, options = {})
+ foreign_key_name = foreign_key_name(from_table, options)
+ execute <<-SQL
+ALTER TABLE #{quote_table_name(from_table)}
+DROP CONSTRAINT #{foreign_key_name}
+ SQL
+ end
+
+ def foreign_key_name(table_name, options)
+ options.fetch(:name) do
+ column_name = options.fetch(:column)
+ "#{table_name}_#{column_name}_fk"
+ end
+ end
+
def index_name_length
63
end
@@ -159,6 +159,10 @@ def supports_transaction_isolation?
true
end
+ def supports_foreign_keys?
+ true
+ end
+
def index_algorithms
{ concurrently: 'CONCURRENTLY' }
end
@@ -0,0 +1,49 @@
+require 'cases/helper'
+
+if ActiveRecord::Base.connection.supports_foreign_keys?
+module ActiveRecord
+ class Migration
+ class ForeignKeyTest < ActiveRecord::TestCase
+ class Rocket < ActiveRecord::Base
+ end
+
+ class Astronaut < ActiveRecord::Base
+ end
+
+ setup do
+ @connection = ActiveRecord::Base.connection
+ @connection.create_table "rockets" do |t|
+ t.string :name
+ end
+
+ @connection.create_table "astronauts" do |t|
+ t.string :name
+ t.references :rocket
+ end
+ end
+
+ def test_add_foreign_key
+ @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id"
+
+ assert_raises ActiveRecord::InvalidForeignKey do
+ Astronaut.create rocket_id: 33
+ end
+ end
+
+ def test_remove_foreign_key
+ @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id"
+ @connection.remove_foreign_key :astronauts, column: "rocket_id"
+
+ Astronaut.create rocket_id: 33
+ end
+
+ def test_remove_foreign_key_by_name
+ @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", name: "fancy_named_fk"
+ @connection.remove_foreign_key :astronauts, name: "fancy_named_fk"
+
+ Astronaut.create rocket_id: 33
+ end
+ end
+ end
+end
+end

0 comments on commit e2ef257

Please sign in to comment.