diff options
Diffstat (limited to 'activerecord')
3 files changed, 65 insertions, 7 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb index 0867e5ef54..724e3fa1ee 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb @@ -89,6 +89,20 @@ module ActiveRecord 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 diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb index f09ce113d6..b87fb85ae2 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb @@ -448,6 +448,30 @@ module ActiveRecord 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" diff --git a/activerecord/test/cases/migration/foreign_key_test.rb b/activerecord/test/cases/migration/foreign_key_test.rb index 978d1a8cf1..9c804c12d1 100644 --- a/activerecord/test/cases/migration/foreign_key_test.rb +++ b/activerecord/test/cases/migration/foreign_key_test.rb @@ -22,26 +22,46 @@ module ActiveRecord 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 |