ЯoomeR

プログラミング~実装とエラー解決と、時々、AI~

rails:db migrateに失敗するときの対処法

パターン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

これでうまく行かない場合、出力されるエラー文に従って原因を探るほかない。