🌟

Ridgepoleの導入と使い方

に公開

Ridgepoleとは

Ridgepoleは DBスキーマを管理するツールで、Rails DSLを利用してDBスキーマを定義し、DSLに従ってDBスキーマを更新することができます。

動作環境

Rails 7 +MySQLのDocker環境構築 で構築した環境を使います。
Ruby 3.2.2
Rails 7.0.8
MySQL 8.0

インストール

Gemfileに gem 'ridgepole'を追加してbundle installを実行します。
dockerで環境構築していますので、docker buildでイメージを再構築します。

api/Gemfile
gem 'ridgepole'
ターミナル
docker compose run --rm api bundle install
docker compose build api

使い方

Schemafileの作成

ターミナル
mkdir -p api/db/schemas
touch api/db/schemas/Schemafile
touch api/db/schemas/users.schema.rb
api/db/schemas/users.schema.rb
create_table :users, force: :cascade, charset: 'utf8mb4', collation: 'utf8mb4_bin', options: 'ENGINE=InnoDB ROW_FORMAT=DYNAMIC' do |t|
  t.string  :name, null: false, default: ''
  t.integer :age,  null: false, default: 20

  t.index :name, name: 'index_users_on_name'
end
api/db/schemas/Schemafile
require 'users.schema.rb'

ridgepoleコマンドの実行

ターミナル
docker compose run --rm api bundle exec ridgepole --config config/database.yml --env development --file db/schemas/Schemafile --apply

# 実行結果
Apply `db/schemas/Schemafile`
-- create_table("users", {:charset=>"utf8mb4", :collation=>"utf8mb4_bin", :options=>"ENGINE=InnoDB ROW_FORMAT=DYNAMIC"})
  -> 0.0542s
-- add_index("users", ["name"], {:name=>"index_users_on_name"})
  -> 0.0404s

コマンドオプションの説明

オプション 省略形 引数 説明
--config -c config/database.yml DBのconfigファイルのパスを指定
--env -E development, test, production 実行環境を指定
--file -f db/schemas/Schemafile スキーマファイルのパスを指定
--apply -a Schemafileに記述されたスキーマの定義をDBに適用
--export -e DBの現在のスキーマをSchemafileにエクスポート

created_atupdated_at の追加

api/db/schemas/users.schema.rb
create_table :users, force: :cascade, charset: 'utf8mb4', collation: 'utf8mb4_bin', options: 'ENGINE=InnoDB ROW_FORMAT=DYNAMIC' do |t|
  t.string  :name, null: false, default: ''
  t.integer :age,  null: false, default: 20

+ t.timestamps
  t.index :name, name: 'index_users_on_name'
end
ターミナル
docker compose run --rm api bundle exec ridgepole --config config/database.yml --env development --file db/schemas/Schemafile --apply

# 実行結果
Apply `db/schemas/Schemafile`
-- add_column("users", "created_at", :datetime, {:null=>false, :after=>"age"})
  -> 0.0888s
-- add_column("users", "updated_at", :datetime, {:null=>false, :after=>"created_at"})
  -> 0.0798s

rake で実行できるようにする

タスクの作成

ターミナル
docker compose run --rm api bundle exec rails g task db_migration
api/lib/tasks/db_migration.rake
namespace :db_migration do
  desc 'Ridgepole Apply'
  task apply: :environment do
    run('--apply')
  end

  private

  def run(*options)
    config = 'config/database.yml'
    schema = 'db/schemas/Schemafile'
    rails_env   = ENV['RAILS_ENV'] || Rails.env

    command = "bundle exec ridgepole --config #{config} --env #{rails_env} --file #{schema}"
    command = [command, *options].join(' ')

    puts '=== run ridgepole... ==='
    puts "[Running] #{command}"
    system command
  end
end

タスクの実行

ターミナル
docker compose run --rm api bundle exec rails db_migration:apply

# 実行結果
=== run ridgepole... ===
[Running] bundle exec ridgepole --config config/database.yml --env development --file db/schemas/Schemafile --apply
Apply `db/schemas/Schemafile`
No change

Discussion