【Rails】マイグレーションで失敗した経験から学ぶ
はじめに
Rails開発において、データベースのマイグレーションはとても重要な要素のひとつです。
最初のうちはその重要性をあまり意識せずに学習を続けていました。
実際にマイグレーション関連のトラブルにぶつかってはじめて、「これって慎重に扱わなきゃいけないんだ」と実感しました。
現在、個人開発をしながら学習中をしております。失敗の経験から今後に活かしたいと思いました。
実際に起こした過去の失敗例
1. schema.rbの直接編集
# db/schema.rb
t.bigint "user_id", null: false
t.bigint "post_id", null: false
t.string "file_path", null: false # 削除したい ← 直接コメントアウト
t.text "memo" # 削除したい ← 直接コメントアウト
問題点:schema.rbはマイグレーション実行時に自動生成されるファイルのため、直接編集してはいけない!
正しい方法:マイグレーションファイルを作成して、カラムを削除する!
class RemoveUnnecessaryColumnsFromAttachments < ActiveRecord::Migration[8.0]
def change
remove_column :attachments, :file_path, :string
remove_column :attachments, :memo, :text
end
end
2. 存在しないカラムのremove_columnマイグレーション
class UpdatePostsTable < ActiveRecord::Migration[8.0]
def change
remove_column :posts, :author_name, :string
end
end
問題点:author_nameカラムを追加したマイグレーションが存在しないのに、削除マイグレーションだけが残っていました。これにより、他の開発者がマイグレーションを実行する際にエラーが発生する可能性があります。
3. 設定不要なconfig.active_record.schema_format指定
# config/application.rb
config.active_record.schema_format = :ruby
問題点:デフォルトで:rubyが設定されているため、明示的に指定する必要がありませんでした。
他チームメンバーとの環境差異問題
実際に発生し得る問題として、以下のような参考記事のシナリオ
典型的な失敗パターン
- 太郎さんがtypoを含むマイグレーションを作成・実行してGitHubにpush
- 花子さんがpullして同じマイグレーションを実行
- 太郎さんがtypoに気づき、過去のマイグレーションファイルを直接修正
- 太郎さんが新しいマイグレーションを追加してpush
- 花子さんがpullして新しいマイグレーションを実行しようとするとエラー
環境差異が生まれる理由
| アクション | 太郎さんのDB | 花子さんのDB | 状況 |
|---|---|---|---|
| 初回マイグレーション |
barthdayカラム |
barthdayカラム |
同期 |
| 太郎さんがrollback + 修正 |
birthdayカラム |
barthdayカラム |
差異発生 |
| 新しいマイグレーション実行 | 正常動作 | エラー発生 | 問題発生 |
正しいマイグレーションの扱い方
1. 過去のマイグレーションは修正しない
NG例:
# 既存のマイグレーションを直接修正
class AddBirthdayToUsers < ActiveRecord::Migration
def change
add_column :users, :birthday, :date # typoを直接修正
end
end
OK例:
# 修正用の新しいマイグレーションを作成
class RenameBarthdayToBirthdayInUsers < ActiveRecord::Migration
def change
rename_column :users, :barthday, :birthday
end
end
2. 一括置換時の注意
プロジェクト全体でリファクタリングを行う際も、マイグレーションファイルは除外する必要がある
安全な手順
- 「すべてを置換」ではなく「置換、次へ」を1件ずつ実行
- マイグレーションファイルやschema.rbに遭遇したら置換をスキップ
- コミット前にdiffを確認
- 変更ファイルにマイグレーション関連が含まれていないことを確認してからコミット
3. 整合性確認のためのdb:migrate:reset
マイグレーションの整合性に不安がある場合は、以下のコマンドで確認
bin/rails db:migrate:reset
注意:既存データは削除されるため、開発環境でのみ実行
まとめ
マイグレーションで失敗しないための要点
行うこと
- 新しいマイグレーションファイルで修正をする
- コミット前にdiffを必ず確認する
- 不安な場合は
db:migrate:resetで整合性をチェックする - デフォルト値の設定は省略する
いけないこと
- 過去のマイグレーションファイルを直接修正
- schema.rbを直接編集
- 存在しないカラムに対するremove_column
- 一括置換でマイグレーションファイルも変更