この記事を書いた背景
いつもAWSでデプロイをしていて、スクールの最終課題ではチームの中でデプロイを担当させてもらってました。ですが、herokuを使ったことがなかったので、一度は使ってみようと思い、ポートフォリオはherokuを使っています。
デプロイをしている中で「heroku」のコマンドはAWSでデプロイするときとコマンドがかなり違う!(当たり前…)
AWSでDB:resetをしていた僕もherokuで少し調べてやってみたので、その方法を書いていきたいと思います。
db:resetをするまでの現状
- MySQLを使用
- ItemsテーブルにネストされたQuestionsテーブルがある
- Itemsテーブルの中の「quiz_typeカラム」をQuestionsに移行したい
- DB構造が代わりseedデータの中身も変更したので、本番でもdb:resetしたい
という流れです。
#実際にherokuでdb:resetやってみた
試しに一度AWS風にやってみたところ…
$ heroku run rake db:migrate:reset RAILS_ENV=production
途中までは実行されているけど、どうやらActiveRecordのエラーが出ているみたいですね。
##エラー内容と原因
rake aborted!
ActiveRecord::ProtectedEnvironmentError: You are attempting to run a destructive action against your 'production' database.
If you are sure you want to continue, run the same command with the environment variable:
DISABLE_DATABASE_ENVIRONMENT_CHECK=1
(意訳)
「あなた本番のDB壊そうとしてるけど、Railsに搭載されている防御シールドで撃退されているよ。もし続けたいのなら、”DISABLE_DATABASE_ENVIRONMENT_CHECK=1”の環境変数を使えばいけるはずだよ!」
ということで再トライ
$ heroku run rake db:migrate:reset DISABLE_DATABASE_ENVIRONMENT_CHECK=1
左の方に注目してもらえるとDBがdropされ、再度createされているのがわかりますね。そして、その後itemsテーブルがcreateされていることがわかると思います。
seedファイルをアップロード
ここまでくれば、簡単。あとはseedを入れるだけ。
$ heroku run bundle exec rake db:seed:item RAILS_ENV=production
気持ちよく入っていきますね。
なぜRAILS_ENV=productionが使えなかったのか
Railsのgithubにて「本番環境の破壊的アクションへの防止」が、その背景と対策について書かれています。
Prevent destructive action on production database #22967
要するに「本番環境でうっかりDBを壊しちゃったから、本番環境でDBを破壊するようなタスクには環境変数をつけたよ」ということですね。
Rails5系から本番環境でDBを破壊するタスクに防止機能が追加されていたようです。僕はRails5系からRailsを触り始めたので、RAILS_ENV=productionなどと、本番やテストなどでは環境を指定しなければいけないといった背景に、このようなことがあったと勉強になりました。