LoginSignup
3
1

More than 5 years have passed since last update.

【Rails】カラム名変更でConstraintExceptionがでたときの対処法

Posted at

モデルのカラム名を変更しようとしたところ、"SQLite3::ConstraintException: FOREIGN KEY constraint failed:"というエラーが吐かれたので、その対処法を書いておきます。

確証を持ってやったというより、できそうだなと思ったらできてしまった感じなので、間違っている部分などあればぜひ教えてください!

rails db:migrateのかわりにrails db:migrate resetを実行する

結論からいうと、rails db:migrateではなくrails db:migrate resetをうつことで無事にエラーを回避してカラム名の変更を行うことができました。

ふつうはrails db:migrateなので、ちょっとイレギュラーな対応になるのかもしれません。

前提と実現したかったこと

Railsチュートリアルの拡張機能(リプライ機能)を実装していて、userモデルのカラム名を変更しようとした。

カラム名の変更方法については、以下の記事を参考にさせていただきました。
【備忘録】Rails-カラム名を変更する方法

ざっくりと説明すると、
rails g migraiton rename_カラム名_column_to_テーブル名でマイグレーションファイルを生成
②マイグレーションファイルにrename_column テーブル名, 変更前のカラム名, 変更後のカラム名を追記
rails db:migrateを実行
という流れです。

ここで、先述の"ConstraintException"なるエラーが発生しました。

外部キーによる他モデルとの関連づけが原因

エラーに"FOREIGN KEY"とあるとおり、外部キーをつかってrelationshipsテーブルと関連づけをしていたことが原因でした。

user.rb
class User < ApplicationRecord
  has_many :microposts, dependent: :destroy
  has_many :active_relationships, class_name:  "Relationship", foreign_key: "follower_id", dependent: :destroy
  has_many :passive_relationships, class_name:  "Relationship", foreign_key: "followed_id", dependent:   :destroy
  has_many :following, through: :active_relationships, source: :followed
  has_many :followers, through: :passive_relationships, source: :follower
...

以下の記事を参考にしたところ、
①外部キーをつかって他のテーブルと関連づけをしていた
②すでにDB内にデータが存在しており、キーによる紐付けがおこなわれていた
という状態だったので変更ができなかったらしい(変更してしまうとデータ整合性がとれなくなる)、ということが分かりました。

外部キー制約でハマったので(rails)

ちなみに上記記事では、has_manyにつづけてdependent: :destroyを指定することでこのエラーを解決しています。

変更したいカラムはキーとは無関係なので、DBをリセットすることで対処

ただし、今回変更したかったカラムは外部キーに設定したカラムではないので、単純にdependent: :destroyをつける対処はできません。

また、変更するカラムが外部キーとは直接関係ないことから、問題になるのは②の「すでにDBに存在していて、他のテーブルに紐づいているデータ」になりそうです。

もしそうであれば、この「すでにあるデータ」をいったん空にしてしまえばrails db:migrateが実行できるはず。...DBをリセットしてマイグレーションを実行って、rails db:migrate:resetそのものじゃん。

ということでやってみたら無事にマイグレーションが実行できました。schema.rbも意図したかたちになっています。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1