はじめに
今更ながらrailsアプリケーションにridgepoleを導入してみました。
その際にrails migrate
とは別れたはずなのですが、railsのエラー画面で"Migrations are pendding"
というmigrationファイルと付き合っていたころの見慣れたエラーに出くわしてしまいました。
別れた次の日にばったりいつもの公園で出会ってしまったカップルのように・・・
どうやら復縁を迫られているみたいです。
そこで、そんな人がそんなときに見る用の記事(migrationと未練を残さずお別れする方法)として、やったことをまとめました。
「そもそもridgepoleとはなんぞ?」
という方は、偉大な先人たちがたくさん知恵を残してくれているのでそちらをご参照ください!
(導入まで簡単にできます)
原因調査
1. railsの見ているDBと実際のDBが異なるのでは?と疑う
これまではmigrationファイルでの管理だったため、railsの参照先としているDBが古い方のDBを参照したままなのではないかという、憶測を立てたので確認。
まずは、ActiveRecordで使用しているDBの接続情報を調べてみる。
[1] pry(main)> ActiveRecord::Base.connection_config
# => 接続しているDBの情報
{:adapter=>"XXX",
:encoding=>"XXX",
:charset=>"XXX",
:collation=>"XXX",
:reconnect=>false,
:pool=>5,
:database=>"XXX",
:username=>"XXX",
:password=>"XXX",
:host=>"XXX"
次に、環境ごとに設定している、railsのDB情報は、アプリ名/config/database.yml
に記載されているので、確認。
development:
<<: *default
database: <%= XXX %>
username: <%= XXX %>
password: <%= XXX %>
host: <%= XXX %>
socket: <%= XXX %>
staging: ~~~
production: ~~~
ちゃんと同じDBを参照していた。
結論: これではない
2. そーいえば、migrationファイル消してなくない?
当たり前のことだったが、migrationファイルを消し忘れていた😭
(正確には消さなくてもいけるんじゃないかという、migrationに対する未練があった)
ridgepoleはアプリ名/db/Schemafile
を参照しているので、当たり前だが、ここにmigrationファイルが残っていたらそれはお別れできないですな!
# 未練残さずきっぱりと削除
$ rm -rf db/migrate
$ rm db/schema.rb
これで無事エラーは解決!
だがこれで終わってしまうのも、情けないので追加情報
おまけ
ridgepoleコマンドをrakeタスク化
通常ridgepoleは以下のようなコマンドで流す
-c
はconfigファイルの指定。(※ただしコマンドを打つ場所からの相対パスで指定)
-E
はdatabase.yml
に記載のどの環境のDB情報か。
$ bundle exec ridgepole -c ./config/database.yml -E development --apply --file ./db/Schemafile
たが長いし、覚えられないし、ということでrakeタスクファイルを作成し、アプリ内(/lib/tasks
)に配置。
namespace :ridgepole do
schema = Rails.root.join('db', 'Schemafile')
config = Rails.root.join('config', 'database.yml')
environment = ENV['RAILS_ENV'] || 'development'
desc 'apply schema migration'
task apply: :environment do
result = `bundle exec ridgepole --apply --env #{environment} --file #{schema} --config #{config}`
puts result
end
desc 'dry run'
task dry_run: :environment do
result = `bundle exec ridgepole --apply --env #{environment} --file #{schema} --config #{config} --dry-run`
puts result
end
end
これで次回以降は、↓だけで済む!
$ bundle exec rake ridgepole:apply
メリットでもありデメリットでもあるが、
ridgepoleではSchemafileを直接編集するので、CREATE TABLE ~
の文を削除するだけで、DBを簡単にDROPできてしまう。
そんな時のためにも、テーブルDROPのリスク管理を行うようなrakeタスクを作成しておくとより安心だと思う。(↓参考記事)
運用方法
今回のようなことがまた起きないためにも確認してみる。
例えば、rails g コマンドでモデルを新規作成したときを見ると・・・
$ rails c
$ rails g model Test
=> db/migrate ファイルが作られてしまう
なのでrails g modelを使用する際にはオプションで --skip-migration を指定
$ rails g model Test --skip-migration
ちなみに・・・↓で rails g model で作られてしまったファイルを全て削除できる
$ rails d model Test
おそらくrailsコマンドの使用した際には、migrationファイルが自動で作られるようになっている。
なので、モデルを作成するときには、--skip-migration
をつけるか、手動でモデルファイルを作成しましょう!
という結論も一つあるが、
もしくは↓記事にあるように、application.rbに書くことによって解決できそうです。
さいごに
ridgepoleに変えてみて、migrationファイルの管理(束縛)から解放されすごく楽になりました。
男ならいさぎよく未練なくきっぱりとお別れすることが大事だと学びました。
「今までありがとうmigration、これからよろしくrigepole!」