如果外键存在于 Rails 的 Ruby 中,我该如何删除它?
How do I drop a foreign key if it exists in Ruby on Rails?
ActionRecord 中有一个名为 index_exists?
的函数,但 Rails 4.2.7 中没有 foreign_key_exists?
。
因此,当我在某些数据库上调用 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'
but no foreign_key_exists?
There is foreign_key_exists?
:)
Checks to see if a foreign key exists on a table for a given foreign
key definition.
# 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?"(Rails4.2.6),所以我用的是Array#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
在Rails 4上没有foreign_key_exists所以我想出了以下解决方案:
remove_foreign_key :events, column: :subscribers_selector_id if foreign_keys(:events).map(&:column).include?("subscribers_selector_id")
Rails 7+ if_exists / if_not_exists 选项
Rails 7 将 if_exists
选项添加到 remove_foreign_key
以便在外键已被删除时不引发错误。
Rails 7 将 if_not_exists
选项添加到 add_foreign_key
以便在已添加外键时不引发错误。
因此,迁移可以这样写:
class RemoveFranchiseGroupForeignKeysFromParties < ActiveRecord::Migration
def up
remove_foreign_key :parties, :franchise_groups, if_exists: true
end
def down
add_foreign_key :parties, :franchise_groups, if_not_exists: true
end
end
来源:
ActionRecord 中有一个名为 index_exists?
的函数,但 Rails 4.2.7 中没有 foreign_key_exists?
。
因此,当我在某些数据库上调用 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'
but no
foreign_key_exists?
There is foreign_key_exists?
:)
Checks to see if a foreign key exists on a table for a given foreign key definition.
# 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?"(Rails4.2.6),所以我用的是Array#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
在Rails 4上没有foreign_key_exists所以我想出了以下解决方案:
remove_foreign_key :events, column: :subscribers_selector_id if foreign_keys(:events).map(&:column).include?("subscribers_selector_id")
Rails 7+ if_exists / if_not_exists 选项
Rails 7 将 if_exists
选项添加到 remove_foreign_key
以便在外键已被删除时不引发错误。
Rails 7 将 if_not_exists
选项添加到 add_foreign_key
以便在已添加外键时不引发错误。
因此,迁移可以这样写:
class RemoveFranchiseGroupForeignKeysFromParties < ActiveRecord::Migration
def up
remove_foreign_key :parties, :franchise_groups, if_exists: true
end
def down
add_foreign_key :parties, :franchise_groups, if_not_exists: true
end
end
来源: