パターン1.外部キーの見直し
アプリ例
例えば、ユーザーが商品を出品するアプリを考える。
ユーザーは商品を所有し(has_many)、商品はユーザーに属する。(belongs_to)
よって、商品テーブルにはユーザーの外部キーが存在する。
#user.rb class DeviseCreateUsers < ActiveRecord::Migration[6.0] def change create_table :users do |t| ## Database authenticatable t.string :nickname, null: false, default: "" t.string :email, null: false, default: "" t.string :encrypted_password, null: false, default: "" ## Recoverable t.string :reset_password_token t.datetime :reset_password_sent_at ## Rememberable t.datetime :remember_created_at t.timestamps null: false end add_index :users, :email, unique: true add_index :users, :reset_password_token, unique: true end end
#item.rb class CreateItems < ActiveRecord::Migration[6.0] def change create_table :items do |t| t.string :name, null: false t.integer :price, null: false t.references :user, foreign_key: true t.timestamps end end end
ファイルの作成順に注意!
ファイルを作成するとき、「外部キーの相手先」の存在が前提となる。
つまり、items.rbより先にusers.rbが作成されていなければならない。
逆にしてしまった場合、「user_databaseはありません」といったエラーが発生し、migrateが実行できない。
対処法
その1.素直にファイルを作り直す
先にitems.rbを作ってしまった場合、素直にitems.rbを削除し、再作成する。
この際に、マイグレーションファイル、モデルファイルのどちらも削除する必要があるので注意。
その2.ファイル名を変更する
マイグレーションファイルの前後関係はファイル名で決まる。
例えば、以下のようなファイル名になっていたとする。
#間違えてitemのマイグレーションファイルを先に作ってしまった場合 20211010074650_create_items.rb 20211011065624_devise_create_users.rb
よく見ると、最初の数列は作成した日時になっている。
よって、items.rbのファイル名を以下のように変更すれば良い。
#「20211010」を「20211012」に変更した。 20211012074650_create_items.rb
こうすれば前後関係が入れ替わり、migrateできるようになる。
パターン2.「No file」が表示される場合
「rails db:migrate:status」を実行したときに以下のように表示される場合。
Status Migration ID Migration Name -------------------------------------------------- up 20200511065624 Devise create users up 20200511074650 Create items up 20200512064218 ********** NO FILE ********** up 20200522025754 Create phones up 20200524071927 Create addresses
原因は、downにしないままマイグレーションファイルを削除してしまったことである。
解決方法
以下のコマンドを実行する。
rails db:migrate:reset
全てのテーブルの中身(登録したuserやitemの情報)が消えてしまうことに注意!
※削除してしまったマイグレーションのダミーファイルを作成し、downにしてから改めて削除するという手順もあるが、「rails db:migrate:reset」の方が早いので割愛する。
パターン3.その他の場合
パターン2と同様、以下のコマンドを実行する。
rails db:migrate:reset
これでうまく行かない場合、出力されるエラー文に従って原因を探るほかない。