Как удалить внешний ключ, если он существует в Ruby on Rails?

есть функция под названием index_exists? в ActionRecord, но нет foreign_key_exists? на рельсы 4.2.7.

поэтому, когда я называю remove_foreign_key :parties, :franchise_groups на некоторых базах он ломается.

что я должен использовать?


обновление

код

class RemoveForeignKey < ActiveRecord::Migration
  def up
    if foreign_key_exists?(:parties, :franchise_groups)
      remove_foreign_key :parties, :franchise_groups
    end
  end
end

выдает ошибку

== 20161107163800 RemoveForeignKey: migrating =================================
-- foreign_key_exists?(:parties, :franchise_groups)
rake aborted!
An error has occurred, all later migrations canceled:

undefined method `foreign_key_exists?' for #<RemoveForeignKey:0x00000007ea0b58>
/home/rje/.rvm/gems/ruby-2.3.0/gems/activerecord-4.2.7/lib/active_record/migration.rb:664:in `block in method_missing'

5 ответов


а не foreign_key_exists?

здесь foreign_key_exists? :)

проверяет, существует ли внешний ключ в таблице для данного внешнего ключа ключевое определение.

# Checks to see if a foreign key exists.
  foreign_key_exists?(:accounts, :branches)

# Checks to see if a foreign key on a specified column exists. foreign_key_exists?(:accounts, column: :owner_id)

# Checks to see if a foreign key with a custom name exists. foreign_key_exists?(:accounts, name: "special_fk_name")

кроме того, вы можете использовать foreign_keys:

if foreign_keys(:table_name).include?(foreign_key_name)
  # do stuff
end

Я думаю, что вы можете использовать что-то вроде этого

def up
  remove_foreign_key :parties, column: :franchise_groups
end

def down
  add_foreign_key :parties, :franchise_groups
end

он работает при подключении:

ActiveRecord::Base.connection.foreign_key_exists?(:parties, :franchise_groups) 

моя версия Rails, похоже, не имеет "foreign_key_exists?"(Rails 4.2.6), поэтому я использую массив#any? чтобы выполнить поиск по результатам из "foreign_keys" и определить, существует ли данный внешний ключ:

foreign_keys("parties").any?{|k| k[:to_table] == "franchise_groups"}

Вы можете использовать его как таковой:

if foreign_keys("parties").any?{|k| k[:to_table] == "franchise_groups"}
remove_foreign_key :parties, column: :franchise_group_id
end

на рельсах 4 нет foreign_key_exists поэтому я придумал следующее решение:

remove_foreign_key :events, column: :subscribers_selector_id if foreign_keys(:events).map(&:column).include?("subscribers_selector_id")