🐥
RailsアプリへのRidgepoleの導入
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