diff options
3 files changed, 48 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb index 7eaa89c9a7..a70d93c28b 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb @@ -650,6 +650,10 @@ module ActiveRecord def foreign_key(*args) # :nodoc: @base.add_foreign_key(name, *args) end + + def foreign_key_exists?(*args) # :nodoc: + @base.foreign_key_exists?(name, *args) + end private def native diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index f905669a24..0ca8570d00 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -671,6 +671,29 @@ module ActiveRecord def foreign_keys(table_name) raise NotImplementedError, "foreign_keys is not implemented" end + + # Checks to see if a foreign key exists on a table for a given foreign key definition. + # + # # Check a foreign key exists + # foreign_key_exists?(:accounts, :branches) + # + # # Check a foreign key on specified column exists + # foreign_key_exists?(:accounts, column: :owner_id) + # + # # Check a foreign key with a custom name exists + # foreign_key_exists?(:accounts, name: "special_fk_name") + # + def foreign_key_exists?(from_table, options_or_to_table = {}) + return unless supports_foreign_keys? + + if options_or_to_table.is_a?(Hash) + options = options_or_to_table + else + options = { column: foreign_key_column_for(options_or_to_table) } + end + + foreign_keys(from_table).any? {|fk| options.keys.all? {|key| fk.options[key].to_s == options[key].to_s } } + end # Adds a new foreign key. +from_table+ is the table with the key column, # +to_table+ contains the referenced primary key. diff --git a/activerecord/test/cases/migration/foreign_key_test.rb b/activerecord/test/cases/migration/foreign_key_test.rb index 78d9dd90a3..8cf2ead661 100644 --- a/activerecord/test/cases/migration/foreign_key_test.rb +++ b/activerecord/test/cases/migration/foreign_key_test.rb @@ -145,6 +145,27 @@ module ActiveRecord fk = foreign_keys.first assert_equal :nullify, fk.on_update end + + def test_foreign_key_exists + @connection.add_foreign_key :astronauts, :rockets + + assert @connection.foreign_key_exists?(:astronauts, :rockets) + assert_not @connection.foreign_key_exists?(:astronauts, :stars) + end + + def test_foreign_key_exists_by_column + @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id" + + assert @connection.foreign_key_exists?(:astronauts, column: "rocket_id") + assert_not @connection.foreign_key_exists?(:astronauts, column: "star_id") + end + + def test_foreign_key_exists_by_name + @connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", name: "fancy_named_fk" + + assert @connection.foreign_key_exists?(:astronauts, name: "fancy_named_fk") + assert_not @connection.foreign_key_exists?(:astronauts, name: "other_fancy_named_fk") + end def test_remove_foreign_key_inferes_column @connection.add_foreign_key :astronauts, :rockets |