Techioz Blog

Ruby: 移行時の add_reference でエラーがスローされる: テーブルに外部キーがありません

概要

この移行があります:

class AddNotificationSettingToHistoricals < ActiveRecord::Migration[6.1]
  def change
    unless foreign_key_exists?(:sms_historicals, column: :notification_setting_id)
      add_reference :sms_historicals, :notification_setting, foreign_key: true
    end
    unless foreign_key_exists?(:email_historicals, column: :notification_setting_id)
      add_reference :email_historicals, :notification_setting, foreign_key: true
    end
  end
end

しかし、実行すると、次のエラーがスローされます。

Table 'email_historicals' has no foreign key for notification_settings

私が理解できないのは、移行に次のものがあるということです。

unless foreign_key_exists?(:email_historicals, column: :notification_setting_id)

false をスローするのはどれですか。はい、外部キーはありません。それが、外部キーを追加しようとしている理由です。ええ、なぜこれを行うのかわかりません。何かアイデアはありますか?

解決策

https://gitlab.com/gitlab-org/gitlab/-/issues/394760 に基づくと、foreign_key_exists のように見えますか? postgres_foreign_keys に正しい列が含まれる前に移行で実行すると、エラーがスローされる可能性があります。彼らが提案する回避策は、column_exists? を使用することです。その代わり

class AddNotificationSettingToHistoricals < ActiveRecord::Migration[6.1]
  def change
    unless column_exists?(:sms_historicals, :notification_setting_id)
      add_reference :sms_historicals, :notification_setting, foreign_key: true
    end
    unless column_exists?(:email_historicals, :notification_setting_id)
      add_reference :email_historicals, :notification_setting, foreign_key: true
    end
  end
end