🐥

RailsアプリへのRidgepoleの導入

2025/03/12に公開

Ridgepoleとは

Ridgepoleは、DBスキーマを「DDL(CREATE TABLE文)」ではなく「RubyのDSLファイル」で管理するツール です。

通常、Railsは「マイグレーション(差分)」を積み重ねてスキーマを管理しますが、Ridgepoleは「現在のスキーマ状態(全体)」を1つのファイルで管理します。

動作環境

Rails7 + MySQL8.0の開発環境をdocker compose で開発する で構築した環境を使います。
Ruby: 3.2.2
Rails: 7.1.5
MySQL: 8.0

導入手順

Ridgepoleをインストール

Gemfileに追加します。

gem 'ridgepole'

コンテナにインストールします。

docker-compose exec web bundle install

スキーマファイルのエクスポート(初回)

現在のデータベースにすでにテーブルが存在する場合、スキーマ情報をエクスポートします。

docker compose exec web bundle exec ridgepole --export -c config/database.yml -e development -o db/Schemafile

スキーマの編集

db/Schemafileを編集し、テーブル・カラム・インデックスなどを自由に設計します。

create_table "users", force: :cascade do |t|
    t.string "name", null: false
    t.string "email:
    t.timestamp
end

スキーマの適用

変種したSchemafileをデータベースに反映します。

docker compose exec web bundle exec ridgepole --apply --config config/database.yml --env development --file db/Schemafile

差分の確認

「何が変わるのか」を事前に確認したい場合には、 --dry-run オプションをつけます。
この時、実際のSQLは実行されず、変更予定のSQLが表示されます。

docker compose exec web bundle exec ridgepole --apply --dry-run --config config/database.yml --env development --file db/Schemafile

スキーマ情報のアノテーション(任意)

annotaterb というgemを使うと、テーブル定義のコメントがモデルファイルに自動で付与されます。

annotaterbのインストール

Gemfileに追加します。

gem 'annotaterb'

コンテナにインストールします。

docker compose exec web bundle install

.annotaterb.ymlを作成

.annotaterb.ymlというファイルを作成することで、アノテーションを細かく設定することができる。

# 実装例
header: true       # "== Schema Info ==" のヘッダーを付けるかどうか
sort: true         # カラムをアルファベット順に並べる
index: true        # インデックス情報も表示する

アノテーションの実行

以下のコマンドを実行します。

docker compose exec web bundle exec annotaterb models

Appendix: rakeタスクで実行できるようにする

いちいちコマンドを打つのが面倒な時は、rakeタスクを定義することで簡潔なコマンドでridgepoleを実行することができます。

タスクの作成

docker compose exec web rails g task ridgepole

作成したタスクを、以下のように編集します。

lib/tasks/ridgepole.rake
namespace :ridgepole do
  desc 'Apply database schema'
  task apply: :environment do
    exit! unless Rails.env.local?
    # developmentのSchemaを更新する
    ridgepole('--apply', "-E development", '-s primary', "-f #{schema_file}", '--drop-table')
    # testのSchemaを更新する
    ridgepole('--apply', "-E test", '-s primary', "-f #{schema_file}", '--drop-table')

    system('bundle exec annotaterb models') if Rails.env.development?
  end

  desc 'Export database schema'
  task export: :environment do
    ridgepole('--export', "-E #{Rails.env}", "-o #{schema_file}")
  end

  private

  def schema_file
    Rails.root.join('db/Schemafile')
  end

  def config_file
    Rails.root.join('config/database.yml')
  end

  def ridgepole(*options)
    command = ['bundle exec ridgepole', "-c #{config_file}"]
    system [command + options].join(' ')
  end
end

タスクの実行

以下のように、すっきりしたコマンドで作成することができます!

docker compose exec web rails ridgepole:apply

Discussion