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】migrateがうまくいかずusersテーブルにnameだけ登録できない問題

Last updated at Posted at 2024-08-16

はじめに&状況

アプリ開発の課題においてなぜかわかりませんがマイグレーションファイルで認証機能に関するコードを入力してmigrateをしたのにusersテーブルのnameだけがうまくいっていなくて相当悩んでいましたが無事解決できたのでアウトプットの為にも記事にしておこうかと思います。

環境

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

私がしたこと

解決までの流れをそのまま記載しておきます

ローカルはOKだがデプロイでFailed

StandardError: An error has occurred, this and all later migrations canceled: (StandardError)
PG::DuplicateColumn: ERROR:  column "name" of relation "users" already exists
ActiveRecord::StatementInvalid: PG::DuplicateColumn: ERROR:  column "name" of relation "users" already exists (ActiveRecord::StatementInvalid)
PG::DuplicateColumn: ERROR:  column "name" of relation "users" already exists (PG::DuplicateColumn)

上記4つのエラーがデプロイ先で表示されていました。どういうエラーかというと「PostgreSQLデータベースに対して、「users」テーブルに「name」カラムを追加しようとしたが、そのカラムがすでに存在しているよ!」という内容でした。

当時のマイグレーションファイルとスキーマファイルはこんな感じ

マイグレーションファイル1つ目
class SorceryCore < ActiveRecord::Migration[7.1]
  def change
    create_table :users do |t|
      t.string :name,             null: false
      t.string :email,            null: false, index: { unique: true }
      t.string :crypted_password
      t.string :salt

      t.timestamps                null: false
    end
  end
end

マイグレーションファイル2つ目
class AddNameToUsers < ActiveRecord::Migration[7.1]
  def change
    add_column :users, :name, :string, null: false
  end
end

スキーマファイルのusersテーブル
  create_table "users", force: :cascade do |t|
    t.string "email", null: false
    t.string "crypted_password"
    t.string "salt"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "name", null: false
    t.index ["email"], name: "index_users_on_email", unique: true
  end

なぜusersテーブルのnameに関するマイグレーションが二つあるかというと、1つめのマイグレーションファイルだけではなぜかusersテーブルにt.string "name", null: falseが登録?されなかったので2つ目のマイグレーションファイルを作成

つまり、この2つ目のマイグレーションファイルを削除すれば解決なのか?

とりあえず不要なマイグレーションファイルを削除してみる

1.不要?なマイグレーションファイルの削除

$ docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED      STATUS                    PORTS                    NAMES
bb578bd2bdf3   sotu_app-web   "bash -c 'bundle ins…"   3 days ago   Up 15 minutes             0.0.0.0:3000->3000/tcp   sotu_app-web-1
b63bae0c1bd7   postgres       "docker-entrypoint.s…"   3 days ago   Up 15 minutes (healthy)   0.0.0.0:5432->5432/tcp   sotu_app-db-1
  • コンテナ内に入る(コンテナ名はご自身のものに変えてください)
docker exec -it sotu_app-web-1 /bin/bash
  • マイグレーションファイルの状況確認
rails db:status

もしくはこちらのコード

rails db:migrate:status
  • 次のような状態で3つ目のupを削除することで解決したい
# rails db:migrate:status

database: myapp_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20240710044807  Create tasks
   up     20240806045143  Sorcery core
   up     20240810051914  Add name to users
  • 具体的な手順
# rails db:rollback
== 20240810051914 AddNameToUsers: reverting ===================================
-- remove_column(:users, :name, :string, {:null=>false})
   -> 0.0084s
== 20240810051914 AddNameToUsers: reverted (0.0176s) ==========================

# rails db:migrate:status
database: myapp_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20240710044807  Create tasks
   up     20240806045143  Sorcery core
  down    20240810051914  Add name to users

# rm db/migrate/20240810051914_add_name_to_users.rb

2. マイグレーションファイルの編集

次に、元々存在していた最初のマイグレーションファイル(SorceryCore)を編集して、name カラムが確実に含まれているか確認します。

  • 20240806045143 Sorcery coreのusersテーブルにname入っているの確認して再度マイグレーションを実行するがスキーマファイルのusersにname関連が追加されない:scream:

次の方法で解決しました!

  • マイグレーションファイルの適応?がうまくいっていなさそう
  • upの残り二つも一度ロールバックして再度migrateしたほうがよさそう
# rails db:migrate:status

database: myapp_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20240710044807  Create tasks
   up     20240806045143  Sorcery core
# rails db:rollback
== 20240806045143 SorceryCore: reverting ======================================
-- drop_table(:users)
   -> 0.0192s
== 20240806045143 SorceryCore: reverted (0.0316s) =============================

# rails db:rollback
== 20240710044807 CreateTasks: reverting ======================================
-- drop_table(:tasks)
   -> 0.0067s
== 20240710044807 CreateTasks: reverted (0.0183s) =============================

# rails db:migrate
== 20240710044807 CreateTasks: migrating ======================================
-- create_table(:tasks)
   -> 0.0225s
== 20240710044807 CreateTasks: migrated (0.0228s) =============================

== 20240806045143 SorceryCore: migrating ======================================
-- create_table(:users)
   -> 0.0148s
== 20240806045143 SorceryCore: migrated (0.0150s) =============================
  • 無事usersテーブルにnameが追加された!最後にpushとかしておく
  create_table "users", force: :cascade do |t|
    t.string "name", null: false
    t.string "email", null: false
    t.string "crypted_password"
    t.string "salt"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["email"], name: "index_users_on_email", unique: true
  end

さいごに

データベース周りは後々エラーが起こると大変、という事なので。まだ初めの段階だから2回のロールバックで済んでよかった。
ローカルでOKでもデプロイでのFailedは逐一確認して進めていきたいと思います!
今回の記事が何か参考になれば幸いです

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?