Edited at

【Rails】ridgepole導入


環境


migrationからridgepoleに移行を検討したほうがよい状況とは?


  • 多くの開発者がいて、migrationがコンフリクトする。

  • 複数システムで同じDBを見ており、それぞれのシステムで同じschema情報が必要。

  • 開発初期でschema情報がコロコロ変わる(※というわけで、はじめからridgepoleもお勧め)。


Gemのインストール


Gemfile

gem 'ridgepole'



現在のschema情報を元に、Schemafileを生成

bundle install ridgepole -c config/database.yml --export -o db/Schemafile

cat db/Schemafile


不要なファイルを削除


  • db/schema.rb

  • db/migrate/*

git rm db/schema.rb

git rm -r db/migrate/


rake taskを追加


lib/tasks/ridgepole.rake

# frozen_string_literal: true

namespace :ridgepole do
desc 'Apply database schema'
task apply: :environment do
ridgepole('--apply')
end

desc 'Export database schema'
task export: :environment do
ridgepole('--export')
end

private

def ridgepole(*options)
command = ['bundle exec ridgepole -f db/Schemafile', '-c config/database.yml', "-E #{Rails.env}"]
system((command + options).join(' '))

unless Rails.env.production?
Rake::Task['db:schema:dump'].invoke
Rake::Task['db:test:prepare'].invoke
Rails.root.join('db/schema.rb').delete
end
end
end


以下を参考にさせて頂きました。


rails_helper修正

このままでは、rspecコマンドを実行した際に、rails_helper内でActiveRecord::Migration.maintain_test_schema!が実行され、TEST環境のテーブルが全て削除される。

/Users/foo/src/github.com/bar/baz/db/schema.rb doesn't exist yet. 

Run `rails db:migrate` to create it, then try again.
If you do not intend to use a database,
you should instead alter /Users/foo/src/github.com/bar/baz/config/application.rb to limit the frameworks that will be loaded.

migrationは使わないので、rails_helperの以下の行をコメントアウト(または削除)する。


spec/rails_helper.rb

# ActiveRecord::Migration.maintain_test_schema!



rspec実行前に、db schemaが作成されるようにする(※任意)


spec/spec_helper.rb


require 'rake'
:
:

RSpec.configure do |config|
config.before(:suite) do
Rails.application.load_tasks
Rake.application['ridgepole:apply'].invoke
end
end



Circle CIの設定変更(※任意)

もし、↑の変更をしない場合は、Circle CIでdb schemaが作られるように以下の設定をする。


.circleci/config.yml

      - run:

name:
Database setup
command: bundle exec rails ridgepole:apply RAILS_ENV=test


以降、modelをgenerateする時は、--skip-migrationを付けるのを忘れずに。

rails g model Foo --skip-migration