Ridgepoleとは?Schemafileでスキーマを管理する使い方と落とし穴
Ridgepoleは、DBスキーマの「あるべき姿」をRailsのDSLで1ファイルに書き、その定義とデータベースの現状の差分だけを適用するRuby製のgemです。公式リポジトリは自身を「Rails DSLでDBスキーマを定義し、DSLに従ってDBスキーマを更新するツール(Chef/Puppetのような)」と説明しています。マイグレーションファイルを積み上げる標準のやり方とは発想が逆で、履歴ではなく現在の定義そのものを正とします。なお英単語のridgepole(棟木)とは無関係で、本記事はRuby gemの話です。
まとめ
- Ridgepoleは
Schemafileという単一ファイルにテーブル定義を宣言し、DBとの差分をDDLとして適用するgem。積み上げ式のマイグレーションファイルが不要になる。 - 最新は v3.2.2(2026年6月14日)。依存は activerecord 6.1以上 8.3未満、ライセンスはMIT。Rails 8.1対応は v3.1.0(2025年10月30日)から。
- 基本操作は3つ。既存DBから
--exportでSchemafileを起こし、--apply --dry-runで流れるDDLを確認し、--applyで適用する。 - 事故が起きやすい仕様が3つある。DROP TABLEは既定でスキップされる、リネームは
renamed_fromで明示しないと削除+追加になる、テーブル名変更と他の変更は同時に検出されない。 - データの移行(バックフィル)はRidgepoleの守備範囲外。SQLiteも公式には対象外で、この2点が採用可否の分かれ目になる。
以下、動作要件から日常運用のコマンド、既存プロジェクトからの移行手順、採用を見送るべき条件までを順に整理します。
Ridgepoleの基本 ── 宣言的スキーマ管理という考え方
マイグレーション履歴ではなく現在の定義を正とする
Rails標準のマイグレーションでは、db/migrate/配下に「カラムを追加する」「インデックスを張る」といった変更手順のファイルが時系列で積み上がり、その適用結果としてdb/schema.rbが生成されます。読みたいのは最終形なのに、変更履歴のほうが正本になっている構造です。
Ridgepoleはこれを反転させます。Schemafileに書かれたcreate_tableの集合が唯一の正本で、Ridgepoleは実行のたびに現在のDBスキーマを読み取り、Schemafileとの差分を計算してALTER文やCREATE文へ落とします。ファイルの中身はschema.rbとほぼ同じRails DSLなので、Active Record(アクティブレコード)とは?Railsを支える設計パターンと基本を実例で解説で扱っている型定義の書き方がそのまま通用します。
create_table "articles", force: :cascade do |t|
t.string "title"
t.text "text"
t.datetime "created_at"
t.datetime "updated_at"
end
カラムを1本増やしたいときは、新しいファイルを作らずこの定義にt.string "slug"を書き足します。プルリクエストの差分がそのままスキーマの差分になるため、レビューで「結局この変更でテーブルはどうなるのか」を追う手間が消えます。
動作要件とサポート範囲
2026年7月23日時点の最新版は3.2.2(2026年6月14日リリース、カラム削除時の制約削除順序の修正)です。RubyGemsに登録された実行時依存はactiverecordの6.1以上8.3未満、ライセンスはMIT、累計ダウンロードは約775万件です。Rails 8.1のサポートはv3.1.0(2025年10月30日)で入りました。
| 項目 | 内容 |
|---|---|
| 最新版 | 3.2.2(2026-06-14) |
| ActiveRecord | >= 6.1, < 8.3 |
| Rails 8.1対応 | v3.1.0(2025-10-30)以降 |
| Rails 8.0対応 | v3.0.0(2024-11-10)以降 |
| 対象DB | MySQL / PostgreSQL(SQLiteは公式に対象外) |
| ライセンス | MIT |
READMEは「SQLite does not support.」と明記しています。開発環境だけSQLiteで動かしている構成では、そこだけ標準のマイグレーションを併用するか、開発環境もMySQL/PostgreSQLへ寄せる判断が先に必要です。またv3.2.0(2026年3月28日)で差分表示のライブラリがdiffyからudiffへ置き換えられており、テーブル数の多いプロジェクトほどdiff計算のコストが体感に効きます。バージョンを上げずに「Ridgepoleは遅い」と判断するのは早計です。
Rails標準migrationとの違いと使い分け
両者は排他ではありません。DDL(テーブル・カラム・インデックスの構造変更)はRidgepoleに寄せ、データの書き換えは別手段に残す、という分担が実務上の落としどころです。Schemafileは構造の宣言しか表現できないため、「既存レコードのstatusカラムを一括で埋める」といった処理はRidgepoleでは書けません。
| 観点 | Rails標準migration | Ridgepole |
|---|---|---|
| 正本 | 変更履歴ファイル群 | Schemafile(現在の定義) |
| 差分の作り方 | 開発者が手で記述 | DBとの差分を自動計算 |
| ロールバック | down / revert | Schemafileをgitで戻して再適用 |
| ファイル数 | 変更のたび増加 | 増えない |
| データ移行 | 可能 | 不可(別スクリプト) |
| ブランチ間の競合 | ファイル名の衝突は稀 | 同一ファイルなのでコンフリクトしやすい |
ロールバックの考え方が変わる点は最初に共有しておくべきです。標準のマイグレーションはrollbackで1つ前の状態へ戻しますが、Ridgepoleでは「Schemafileを前のコミットに戻して再度applyする」のが復旧手順になります。逆に言えば、down方向の記述漏れでロールバックが失敗する事故はなくなります。ファイル生成のワークフローそのものが変わるため、Railsジェネレータ(rails generate)の使い方|モデル・scaffold・カスタム生成までで作られるrails g modelのマイグレーション生成は、Ridgepole導入後は使わない運用に切り替えることになります。
宣言的にスキーマを管理する発想はRuby固有のものではありません。PythonではAlembic(アレンビック)とは?Python/SQLAlchemyのDBマイグレーションツールの使い方を基礎から解説、PHPではLaravelにおけるマイグレーションの基本とその重要性のように履歴型が主流である一方、TypeScript圏ではDrizzle ORM(ドリズル)とは?使い方・Prismaとの比較・型安全な設計を解説【2026年版】のようにスキーマ定義から差分を生成する方式が広がっています。
導入からSchemafile出力までの手順
gemの追加と接続設定
GemfileにRidgepoleを追加してbundle installを実行します。CIやデプロイスクリプトから単体で叩きたい場合はgem install ridgepoleでも構いません。
# Gemfile
gem 'ridgepole'
接続先は-cで設定ファイルを渡します。Railsプロジェクトなら既存のconfig/database.ymlをそのまま指定でき、-E(--env)で環境を切り替えます。環境ごとに別ファイルを用意する必要はありません。
既存DBからSchemafileをエクスポートする
すでに動いているプロジェクトに導入する場合、Schemafileを手書きしてはいけません。現在のDBから吐き出させます。
$ ridgepole -c config/database.yml -E development --export -o Schemafile
出力されたSchemafileとdb/schema.rbを突き合わせ、想定外のテーブル(試験的に作って消し忘れたもの、他システムが同居しているもの)が混ざっていないかを確認します。ここで--export直後に--apply --dry-runを流し、差分が空になることを確認できて初めて「現状を正しく写し取れた」と言えます。差分が出るなら、Schemafileの表現力ではDBの現状を再現しきれていないということなので、その差分の中身を先に潰します。
日常運用のコマンド
覚えるコマンドは実質3つです。適用前の確認、適用、そして2つのSchemafile同士の比較です。
# 流れるDDLを確認する(DBは変更しない)
$ ridgepole -c config/database.yml --apply --dry-run
# 適用する
$ ridgepole -c config/database.yml --apply
# 2つのスキーマ定義を比較する
$ ridgepole --diff Schemafile.old Schemafile
--dry-runを挟まずに--applyする運用は避けてください。Ridgepoleは差分を自動計算するため、Schemafile側の記述ミス(型の書き換え、インデックス定義の消し忘れ)がそのままALTER文になります。手で書いたマイグレーションと違い、実行されるDDLは事前に目で見ないと分かりません。
主要なオプションは次のとおりです。対象を絞る-tと除外する--ignore-tablesは、他システムと同じDBを共有している環境では必須になります。
| オプション | 用途 |
|---|---|
-c, --config |
接続設定ファイルの指定 |
-E, --env |
環境の切り替え |
-f, --file |
Schemafileのパス指定 |
-e, --export |
現在のDBから定義を出力 |
-a, --apply |
Schemafileを適用 |
--dry-run |
DDLの表示のみ |
-d, --diff |
2つの定義を比較 |
-t, --tables |
対象テーブルを限定 |
--ignore-tables |
対象外テーブルを指定 |
--drop-table |
DROP TABLEを許可 |
--alter-extra |
ALTER文への追記 |
チームで使うならrakeタスク化してbundle exec rake db:applyのような入り口に統一しておくと、接続ファイルや環境の指定漏れがなくなります。
事故を防ぐために押さえる3つの仕様
DROP TABLEは既定でスキップされる
READMEは「DROP TABLE is skipped by default in v1.0 and later versions. If you want to DROP TABLE, please pass --drop-table.」と述べています。つまりSchemafileからテーブルの定義を消しても、v1.0以降のRidgepoleはそのテーブルを削除しません。安全側に倒した仕様ですが、副作用として「消したはずのテーブルが本番に残り続ける」状態が生まれます。
一方でカラムの削除はこの保護の対象外です。Schemafileからt.string "memo"を消せばDROP COLUMNが流れます。テーブル単位は守られるがカラム単位は守られない、という非対称を理解しておかないと、レビューで見落としたカラム削除がそのまま本番に届きます。--dry-runの出力にDROP COLUMNが含まれていないかは、機械的にgrepしてでも確認する価値があります。
リネームはrenamed_fromで明示する
カラム名やテーブル名を変えたいとき、Schemafileの文字列を書き換えるだけでは「古い名前の削除」と「新しい名前の追加」として扱われ、中のデータが失われます。Ridgepoleはリネーム専用の記法を用意しています。
create_table "user_comments", force: :cascade, renamed_from: "comments" do |t|
t.text "desc", renamed_from: "text"
end
ここに1つ制約があります。READMEの注記によれば、テーブルにrenamed_fromを使った場合、Ridgepoleはリネーム操作だけを実行し、そのテーブルに対する他の変更(カラム、インデックス、外部キーなど)は同じマイグレーション内では検出されません。テーブル名の変更とカラム追加を1回のapplyで済ませようとすると、カラム追加のほうが黙って無視されます。リネームは単独のプルリクエストに切り出し、適用してから次の変更を出す、という順序を運用ルールにしてください。
巨大テーブルのALTERはロック戦略を指定する
数千万行規模のテーブルにインデックスを追加すると、ALTER中に書き込みがブロックされてサービスが停止します。Ridgepoleは生成するALTER文へ任意の指定を追記する--alter-extraを持っており、READMEはMySQLでのオンラインDDL指定を例示しています。
$ ridgepole -a -c database.yml --alter-extra="LOCK=NONE" --debug
LOCK=NONEはMySQLに対して「ロックを取らずに実行できないなら失敗させろ」という指示であり、危険な変更を事前に弾くセーフティとしても機能します。本番適用のコマンドには常時付けておき、失敗したものだけを手動のオンラインDDLツールへ回す運用が現実的です。
既存Railsプロジェクトから移行する手順とCI運用
途中導入で失敗する典型は、Schemafileを作った直後に本番へ--applyしてしまうケースです。環境ごとにスキーマがずれている(本番だけ古いインデックスが残っている、検証環境に消し忘れのテーブルがある)のは珍しくなく、宣言的ツールはそのズレを一括で「正常化」しにいきます。次の順序を守ってください。
- 全環境で
--exportを実行し、出力されたSchemafileを相互にdiffする。ここで環境差を洗い出す。 - 環境差を標準のマイグレーションで先に解消し、全環境のexport結果が一致する状態を作る。
- Schemafileをリポジトリにコミットし、既存の
db/migrate/は削除せず凍結する(過去の履歴として残す)。 - CIに
--apply --dry-runを組み込み、プルリクエストで流れるDDLが見える状態にする。 - 本番適用はデプロイパイプラインの一段として、
--alter-extra付きで実行する。
CIでdry-runの結果をプルリクエストに出す仕組みは、導入効果がもっとも大きい部分です。スキーマ変更のレビューが「Schemafileの差分」と「実際に流れるDDL」の2段構えになり、DROP COLUMNのような破壊的変更をマージ前に指摘できます。テスト実行前にテスト用DBへSchemafileを適用しておけば、スキーマとテストのズレも同時に検出できます。導入企業の公開事例では、この2点をワークフローに組み込んだうえで、危険な変更をPR上で警告する運用が報告されています(SmartBank Tech Blog, 2025年8月1日)。
移行後もデータのバックフィルは残ります。カラムを追加して既存レコードを埋める処理は、ワンショットのrakeタスクかseed用のgemで実行し、Schemafileには構造だけを書く。この分離を最初に決めておかないと、「Ridgepoleに移行したのにdb/migrate配下が増え続ける」という中途半端な状態になります。
Ridgepoleを採用すべきでない場面
宣言的スキーマ管理は万能ではありません。次の条件に当てはまるなら、標準のマイグレーションを続けるほうが総コストは低くなります。
- SQLiteを本番または開発の主DBにしている:公式に対象外であり、回避策を自前で抱える負債に見合いません。
- スキーマ変更が年に数回しかない:Ridgepoleの利点はマイグレーションファイルの増殖を止めることなので、そもそも増えないプロジェクトでは導入と教育のコストが回収できません。
- データ移行を伴う変更が変更全体の大半を占める:Ridgepoleが担当できない領域が主戦場では、ツールを二重に運用する手間だけが残ります。
- スキーマ変更を含むブランチが常時5本以上並走している:全員が同じSchemafileを編集するため、コンフリクトの解消コストがマイグレーションファイル方式より確実に上がります。1テーブル1ファイルに分割して
Schemafileから読み込む構成で緩和できますが、それでも同一テーブルへの同時変更は衝突します。
逆に、テーブル数が多く変更頻度も高い、複数人が日常的にスキーマへ触れる、レビューで最終形を確認したい——この条件が揃うなら導入効果は明確です。判断材料は「変更頻度」と「データ移行の比率」の2つで足ります。
よくある質問
Ridgepoleはgemとしてどうインストールしますか
Gemfileにgem 'ridgepole'を追加してbundle installするか、gem install ridgepoleで直接入れます。Railsに依存せず単体のCLIとしても動作するため、デプロイ用のコンテナにだけ入れて使う構成も可能です。
Railsのどのバージョンまで対応していますか
v3.2.2の実行時依存はactiverecordの6.1以上8.3未満です。Rails 8.0のサポートはv3.0.0(2024年11月10日)、Rails 8.1はv3.1.0(2025年10月30日)で追加されました。Railsを上げる際は、先にRidgepole側の対応バージョンを確認してください。
db/schema.rbはどうなりますか
Ridgepoleに寄せた後はdb/schema.rbを正本として扱いません。Schemafileと二重管理になるため、生成を止めるか、参照しない運用ルールを明示します。中身の書式はほぼ同一なので、導入初期は両者をdiffして差がないことの確認に使えます。
Schemafileを間違えて適用した場合、元に戻せますか
Schemafileをgitで直前のコミットへ戻し、再度--applyすれば構造は復元されます。ただしDROP COLUMNで消えたデータは戻りません。構造のロールバックとデータの復旧は別問題なので、破壊的な変更の前にはバックアップを取ってください。
ridge poleやridgepoolで検索して来たのですが
本記事のRidgepoleはRuby製のDBスキーマ管理gemです。ridgepole(棟木)は建築で屋根の最上部に渡す横木を指す英単語で、内容としては無関係です。DBスキーマの使い方を探している場合は本記事の手順を、建築部材を調べている場合は英和辞典や建築系の資料をあたってください。