0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Error】`rails db:migrate` コマンドを実行した際に発生したエラー。タイムスタンプについて知る

Last updated at Posted at 2024-08-30

はじめに

今回は久しぶりのErrorが起こったので何が原因だったのか、そしてどのような解決方法があり、実際どうしたのか、についての記事になります。マイグレーション実行する際について学んだことをアウトプットしたいと思います。

環境

  • Windows, WSL
  • Docker
  • Ruby 3.2.3
  • Rails 7.1.3

エラー内容

# rails db:migrate
== 20240830014857 CreatePosts: migrating ======================================
-- create_table(:posts)
bin/rails aborted!
StandardError: An error has occurred, this and all later migrations canceled: (StandardError)

PG::UndefinedTable: ERROR:  relation "prefectures" does not exist
/myapp/db/migrate/20240830014857_create_posts.rb:3:in `change'

Caused by:
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR:  relation "prefectures" does not exist (ActiveRecord::StatementInvalid)
/myapp/db/migrate/20240830014857_create_posts.rb:3:in `change'

Caused by:
PG::UndefinedTable: ERROR:  relation "prefectures" does not exist (PG::UndefinedTable)
/myapp/db/migrate/20240830014857_create_posts.rb:3:in `change'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)  

・上記エラー文から、マイグレーションが正常に完了しなかったことを示しています
・エラーメッセージに「relation prefectures does not exist」とあるように、prefectures テーブルが存在しないため、posts テーブルの作成時にエラーが発生しています。

このエラーが起きた原因

posts テーブルのマイグレーションファイルで、prefecture_id という外部キーを設定しているため、prefectures テーブルが存在する必要があります。しかし、prefectures テーブルがまだ作成されていないためにエラーが発生しました。
Prefecture, Station, Line,Post テーブルなど、すべてのマイグレーションファイルとモデルファイルへの編集を一度に行ってからまとめてマイグレーションを実行しようとしたことが原因です(タイムスタンプの順番という概念が皆無)

対処法(提案されたもの)

  1. 関連モデルのマイグレーションを先に実行:
    • prefectures, stations, lines, および favorites テーブルを作成するマイグレーションファイルを先に実行する必要があります。これらのテーブルが存在しないと、posts テーブルの作成時に参照できず、エラーになります。
  2. 順序を確認:
    • マイグレーションファイルの実行順序を確認し、まず Prefecture, Station, Line, User テーブルを作成してから Post テーブルを作成するようにします。

提案された対処法に対しすべて作成済みなので時すでに遅し

・すでにすべてのファイル等は作成していたのでその旨を伝えたところ次の対処法が提案

対処法2(新たな提案)

1. マイグレーションのリセット (オプション)

まず、すべてのマイグレーションをリセットして、最初から再実行する方法があります。この方法はテスト環境や開発環境で推奨されますが、実際のデータがある本番環境では注意が必要です。

rails db:migrate:reset

このコマンドは、すべてのデータベースをリセットしてから、すべてのマイグレーションを再実行します。

2. マイグレーションを個別に実行

もしリセットが適さない場合は、問題が発生している順にマイグレーションを個別に実行していくことができます。

個別マイグレーションの手順

  1. Prefecture, Station, Line テーブルを作成:
    まず、prefectures, stations, lines, users テーブルを作成するマイグレーションファイルを手動で実行します。例えば、CreatePrefectures マイグレーションが db/migrate/20240830014857_create_prefectures.rb にあるとします。

    rails db:migrate:up VERSION=20240830014857
    

    この手順を、stations, lines, users の各マイグレーションファイルについても繰り返します。

  2. Post テーブルの作成:
    関連するテーブルがすべて作成された後に、Post テーブルを作成するマイグレーションを実行します。

    rails db:migrate:up VERSION=20240830014858
    
  3. 残りのマイグレーションを実行:
    他のマイグレーションファイルが残っている場合は、rails db:migrate コマンドを使って残りを一括で実行します。

    rails db:migrate
    

実際にしたこと

都道府県
rails db:migrate:up VERSION=20240830025850

路線
rails db:migrate:up VERSION=20240830030833


rails db:migrate:up VERSION=20240830044413

最後にポスト
rails db:migrate:up VERSION=20240830014857

・リセットするには正直これまで頑張って作ったのに、という思いが強かったので一つずつ実行することに。
・Versionの入力間違いには注意!!

おまけ:マイグレーションの順番を確認する

マイグレーションが正しい順序で実行されるように、ファイルの名前とタイムスタンプを確認が必要。db/migrate/ ディレクトリ内のファイルはタイムスタンプ順に実行されるためです!!

ついでに、マイグレーションファイルのタイムスタンプは、ファイル名の先頭部分に含まれています。Railsでは、マイグレーションファイル名が次の形式で命名されます。

YYYYMMDDHHMMSS_create_table_name.rb

ここで、YYYYMMDDHHMMSS の部分がタイムスタンプになります!このタイムスタンプにより、マイグレーションが実行される順序が決まります。

例えば、以下のようなファイルがあるとします。

20240830014857_create_prefectures.rb
20240830014858_create_stations.rb
20240830014859_create_lines.rb
20240830014860_create_posts.rb

この場合、ファイル名のタイムスタンプ部分 (20240830014857, 20240830014858, など) を見れば、どの順番で実行されるかがわかります。Railsは、このタイムスタンプの順序でマイグレーションを自動的に実行します。

さいごに

タイムスタンプを確認したい場合は、db/migrate/ ディレクトリ内のファイル名を見ることがいいということ、タイムスタンプ順に実行されること、順番の概念がないとこの先ひどい間違いを起こしてしまうかもしれないという事。を学びました。
今回の記事が何か参考になれば幸いです。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?