From f0ae503d1931a2f269db3437550be3173ba06bce Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 29 Jan 2015 23:30:53 +0300 Subject: Add methods to get foreign key matching arguments --- .../abstract/schema_definitions.rb | 8 +++ .../abstract/schema_statements.rb | 68 +++++++++------------- 2 files changed, 36 insertions(+), 40 deletions(-) (limited to 'activerecord') 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 a70d93c28b..a9f276453e 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb @@ -50,6 +50,14 @@ module ActiveRecord options[:primary_key] != default_primary_key end + def defined_for?(options_or_to_table = {}) + if options_or_to_table.is_a?(Hash) + options_or_to_table.all? {|assoc| options[assoc[0]].to_s == assoc[1].to_s } + else + to_table == options_or_to_table.to_s + end + end + private def default_primary_key "id" 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 0ca8570d00..a740c53158 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -671,29 +671,6 @@ 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. @@ -771,29 +748,40 @@ module ActiveRecord # def remove_foreign_key(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 - - fk_name_to_delete = options.fetch(:name) do - fk_to_delete = foreign_keys(from_table).detect {|fk| fk.column == options[:column].to_s } - - if fk_to_delete - fk_to_delete.name - else - raise ArgumentError, "Table '#{from_table}' has no foreign key on column '#{options[:column]}'" - end - end - + + fk_name_to_delete = foreign_key_for!(from_table, options_or_to_table).try(:name) + at = create_alter_table from_table at.drop_foreign_key fk_name_to_delete execute schema_creation.accept(at) 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 = {}) + foreign_key_for(from_table, options_or_to_table).present? + end + + def foreign_key_for(from_table, options_or_to_table = {}) # :nodoc: + return unless supports_foreign_keys? + foreign_keys(from_table).detect {|fk| fk.defined_for? options_or_to_table } + end + + def foreign_key_for!(from_table, options_or_to_table = {}) # :nodoc: + foreign_key_for(from_table, options_or_to_table) or \ + raise ArgumentError, "Table '#{from_table}' has no foreign key for #{options_or_to_table}" + end + def foreign_key_column_for(table_name) # :nodoc: "#{table_name.to_s.singularize}_id" end -- cgit v1.2.3