3
0

More than 1 year has passed since last update.

ridgepoleを導入したのに、" Migrations are pendding "とはドユコト? のときに見る記事

Last updated at Posted at 2022-03-02

はじめに

今更ながら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に記載されているので、確認。

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ファイルの指定。(※ただしコマンドを打つ場所からの相対パスで指定
-Edatabase.ymlに記載のどの環境のDB情報か。

ridgepoleコマンド
$ bundle exec ridgepole -c ./config/database.yml -E development --apply --file ./db/Schemafile

たが長いし、覚えられないし、ということでrakeタスクファイルを作成し、アプリ内(/lib/tasks)に配置。

ridgepole.rake
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!」

3
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0