結論:rake db:rollbackでマイグレーションファイルを1つ戻す →rails db:migrateを実行してエラーが出ないか確かめる。それを繰り返してエラーが出たマイグレーションファイルを削除し、新しくマイグレーションファイルを作成する。
環境
rails 6.0.2.1
ruby 2.6.3
大まかな状態
Facebookログイン機能を実装し終わり、確認をしようとrails sでサーバーを立てたところ以下のエラー文が表示。
上記画像の通りにrails db:migrate RAILS_ENV=developmentを実行したところ、
ターミナルには以下のように表示されました。
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
Index name 'index_users_on_email' on table 'users' already exists
~~~~~~~~~~~~~~~~~~省略~~~~~~~~~~~~~~~~~~
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
Index name 'index_users_on_email' on table 'users' already existsというエラー文を見てデータベースのカラムが重複しているというのは理解しました。
そこでrails db:migrate:statusでマイグレーションを実行しているデータ、していないデータを把握したところ、次のような結果になりました。
database: db/development.sqlite3
Status Migration ID Migration Name
--------------------------------------------------
up 20200128065728 Create users
up 20200128080052 Add index to users email
up 20200128081712 Add password digest to users
down 20200128125519 Add devise to users
down 20200128130822 Add columns to users
下2つがマイグレートされていないということを把握しました。
そこで下2つのマイグレーションファイルをそれぞれ以下のコマンドでマイグレートしました。
bundle exec rake db:migrate:up VERSION=20200128125519 RAILS_ENV=test
bundle exec rake db:migrate:up VERSION=20200128130822 RAILS_ENV=test
2つの結果、以下のようなエラーが出て、usersテーブルはないということでした。
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
SQLite3::SQLException: no such table: users
ctiverecord-6.0.2.1/lib/active_record/migration.rb:1223:in `run'
/Users/shogo/environment/insta-clone/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.2.1/lib/active_record/migration.rb:1075:in `run'
~~~~~~~~~~~~~~~省略~~~~~~~~~~~~~~~
/Library/Ruby/Gems/2.6.0/gems/bundler-2.1.4/exe/bundle:34:in `<top (required)>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Tasks: TOP => db:migrate:up
(See full trace by running task with --trace)
解決法
エラー文を検索しても解決策が見つからず詰んだ感じがしたので、とりあえず全てのマイグレーションファイルをrake db:rollbackを連続で実行して戻し、
bundle exec rake db:migrate:status で本当に戻したかを確認。
down 20200128065728 Create users
down 20200128080052 Add index to users email
down 20200128081712 Add password digest to users
down 20200129020923 Add devise to users
戻されてますね。
で、ここからどのマイグレーションファイルが犯人なのかを調べるために一番最新のデータであるマイグレーションファイル20200129020923 Add devise to usersを右クリック→ゴミ箱に入れるで削除。
その後、元々あった上3つのマイグレーションファイルをマイグレートした結果。うまくマイグレートが実行されました。
原因はマイグレーションファイルAdd devise to usersにあることがわかったので、元々作る予定だったファイルをもう一度作るため
rails g migration AddColumnsToUsers uid:string provider:stringをターミナルで実行。
invoke active_record
create db/migrate/20200129044021_add_columns_to_users.rb
新しく作られました。
で、rails db:migrateを実行したら、うまくマイグレートされました。
念の為bundle exec rake db:migrate:statusで確認をしたところ、
database: db/development.sqlite3
Status Migration ID Migration Name
--------------------------------------------------
up 20200128065728 Create users
up 20200128080052 Add index to users email
up 20200128081712 Add password digest to users
up 20200129044021 Add columns to users
できております。
私の場合はマイグレーションファイルが少なかったので一度全てロールバックしましたが、ファイルが多いのであれば新しく作成したマイグレーションファイルからrake db:rollback→rails db:migrateして、エラーが出たマイグレーションファイルを消して新しく作るのが良いかと思います。
なぐり書きなのでわからない部分があればコメントください。