こんにちは!kossyです!
今回は1対多の関係を実現させる際に必要な外部キーを
設定し忘れた時の対処法をブログに残したいと思います。
ってかそんな大事なこと、設計の段階から気づけよって話なんですけど、人間忘れる生き物ですからね。(正当化)
環境
Rails 5.1.6
Ruby 2.5.1
MacOS Yosemite
状況はこうです。
(例)
1. userモデル、reviewモデル、commentモデル作成(user 1対多 review, review 1対多 comment)
2. マイグレファイル編集の際に、commentモデルに外部キーであるreview_idを記載するのを忘れる
3. rails db:migrateコマンドを実行。 その後忘れたことに気づく。
まぁrake db:rollbackで元に戻してもいいんですけど、後からいろいろマイグレファイルを実行した後に気がつくパターンもありますからね。
この場合は、普通にadd_columnで追加しようとしても、referencesが効きません。
(rails g migration Add_Review_id_To_Commentコマンドでできたマイグレファイルの中身) 以下の記述を追加 add_column :comment, :review_id, :references, foreign_key: true $ rails db:migrate rails aborted! StandardError: An error has occurred, all later migrations canceled:~~~(エラー文が続く)
そういうときは、
rails g migration ファイル名(キャメルorスネークケース) モデル名:references (例) rails g migration Add_Review_id_To_Comment review:references
コマンドを実行しましょう。
すると、新たにマイグレファイルが生成されて、
(新しく作ったマイグレファイル) def change add_reference :comment, :review, index: true end
中身が上記のような記述になってます。
しかしこの記述のままrails db:migrateをしても外部キー制約が効かないらしいので、
def change add_reference :comment, :review, foreign_key: true(ここを変更) end
これでrails db:migrateが通り、外部キー制約のついたカラムの生成に成功します。
参考にさせて頂いた記事
Railsの外部キー制約とreference型について - Qiita
add_reference来てた - 飲んだり寝たり
外部キーをreferences型カラムで保存する - Qiita
Ruby on Rails カラムの追加と削除 - Qiita