目次
1.概要
2.原因
3.解決
4.反省
5.まとめ
1.概要
ItemsテーブルとUsersテーブルの2つが存在し、最初に作ったItemsテーブルにuser-idのカラムを追加する為、rails db:rollback
を2回実行した後に、rails db:migrate
を実行したところ、マイグレートキャンセル:外部キーが存在しない、ユーザーSQLが存在しないというエラーが発生しました。(本来はaddを使いカラムを追加すべきでした。)
2.原因
Usersテーブルを作成前に、Itemsテーブルを暫定的に作成していた為、Itemテーブルに紐付けたuser-idが存在しないというエラーが発生しました。
たとえば1つ目のItemsテーブルは9月1日時点で作成したとします。
class CreateItems < ActiveRecord::Migration[6.0]
def change
create_table :items do |t|
t.references :user, foreign_key: true
これがエラー原因に関連
t.string :name, null: false
t.timestamps
end
end
以下省略
2つ目のUsersテーブルは9月5日時点で作成したとします。
class DeviseCreateUsers < ActiveRecord::Migration[6.0]
def change
create_table :users do |t|
## Database authenticatable
t.string :name, null: false
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
以下は省略
データベースのファイルは、db/migrate/20200905052006_devise_create_users.rbのようになるかと思いますが、数字部分「20200905052006」はデータベースが作成された日時を示しています。
rails db:migrate
は古い日時の方から順番に1つずつデータベースをマイグレートしていくので、今回のケースでは9月1日に作成したItemsテーブルのデータベースのマイグレートが先に行われます。
つまり、Usersテーブルのマイグレートが未実施の状態でItemsテーブルをマイグレートしようとすれば、t.references :user,foreign_key: true
が有効であると判断されず、外部キーがない、ユーザーのSQLがないといったエラーメッセージが表示されます。
3.解決
日時部分の数字の名前を変更して時系列が逆になるようファイルを保存し直した上でrails db:migrate
を行うとUsersテーブルが先にマイグレートされて外部キーが存在しない、ユーザーSQLが存在しないといったエラーが解消されます。
4.反省
1.エラーに関する記録をしっかりと残していなかったので、正確なエラーメッセージを掲載できませんでした。投稿することも意識して緊張感持ってメモ等をしていこうと思います。
2.そもそも、addを使ってカラムを追加していれば時系列がおかしくなってエラーが発生することもなかった。
addにしていれば、Userテーブルをマイグレートした後にItemsテーブルのusser-idのカラムだけマイグレートすることができたはずでした。rails db:rollback
を2回行って直接Itemsテーブルのカラム名に変更を加えたことが間違えでした。
5.まとめ
1.カラムの追加はaddを使う方が良い。特に外部キーの追加だとrails db:migrate
でエラーになることがあります。
2.データベースファイルの数字部分は作成日時を示しています。
3.rails db:migrate
は古い日時から順番に行われます。(rails db:rollbackは直前1回分のマイグレートを取り消します。)
4.addを使わずカラムを追加して、外部キーが存在しないというエラーが発生した時は、データベースのファイル名の日時をマイグレートの都合が良いように変更します。