Permalink
Browse files

fk: add `foreign_keys` for PostgreSQL adapter.

  • Loading branch information...
1 parent e2ef257 commit 09b3a2847ca51d0e5dcebcb636d8770b19c397a7 @senny senny committed Jun 10, 2014
@@ -89,6 +89,20 @@ class ColumnDefinition < ActiveRecord::ConnectionAdapters::ColumnDefinition
attr_accessor :array
end
+ class ForeignKeyDefinition < Struct.new(:from_table, :to_table, :options)
+ def name
+ options[:name]
+ end
+
+ def column
+ options[:column]
+ end
+
+ def primary_key
+ options[:primary_key]
+ end
+ end
+
class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
include ColumnMethods
@@ -448,6 +448,30 @@ 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 foreign_keys(table_name)
+ fk_info = select_all <<-SQL
+SELECT t2.relname AS to_table, a1.attname AS column, a2.attname AS primary_key, c.conname AS name, c.confdeltype AS dependency
+FROM pg_constraint c
+JOIN pg_class t1 ON c.conrelid = t1.oid
+JOIN pg_class t2 ON c.confrelid = t2.oid
+JOIN pg_attribute a1 ON a1.attnum = c.conkey[1] AND a1.attrelid = t1.oid
+JOIN pg_attribute a2 ON a2.attnum = c.confkey[1] AND a2.attrelid = t2.oid
+JOIN pg_namespace t3 ON c.connamespace = t3.oid
+WHERE c.contype = 'f'
+ AND t1.relname = #{quote(table_name)}
+ AND t3.nspname = ANY (current_schemas(false))
+ORDER BY c.conname
+ SQL
+
+ fk_info.map do |row|
+ options = {
+ column: row['column'],
+ name: row['name'],
+ primary_key: row['primary_key'] }
+ ForeignKeyDefinition.new(table_name, row["to_table"], options)
+ end
+ end
+
def add_foreign_key(from_table, to_table, options = {})
foreign_key_column = options.fetch(:column)
referenced_column = "id"
@@ -22,26 +22,46 @@ class Astronaut < ActiveRecord::Base
end
end
+ def test_foreign_keys
+ foreign_keys = @connection.foreign_keys("fk_test_has_fk")
+ assert_equal 1, foreign_keys.size
+
+ fk = foreign_keys.first
+ assert_equal "fk_test_has_fk", fk.from_table
+ assert_equal "fk_test_has_pk", fk.to_table
+ assert_equal "fk_id", fk.column
+ assert_equal "id", fk.primary_key
+ assert_equal "fk_name", fk.name
+ 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
+ foreign_keys = @connection.foreign_keys("astronauts")
+ assert_equal 1, foreign_keys.size
+
+ fk = foreign_keys.first
+ assert_equal "astronauts", fk.from_table
+ assert_equal "rockets", fk.to_table
+ assert_equal "rocket_id", fk.column
+ assert_equal "id", fk.primary_key
+ assert_equal "astronauts_rocket_id_fk", fk.name
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
+ assert_equal 1, @connection.foreign_keys("astronauts").size
+ @connection.remove_foreign_key :astronauts, column: "rocket_id"
+ assert_equal [], @connection.foreign_keys("astronauts")
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
+ assert_equal 1, @connection.foreign_keys("astronauts").size
+ @connection.remove_foreign_key :astronauts, name: "fancy_named_fk"
+ assert_equal [], @connection.foreign_keys("astronauts")
end
end
end

0 comments on commit 09b3a28

Please sign in to comment.