背景
rails5開発中、テーブルを追加してアソシエーション後、herokuにデプロイしたりすると、アソシエーションキーとなるカラムがnulのためNo Method Errorが発生したりする。
このエラーをどうやってクリアすべきか、質問されたので、その時の解決方法を記載します。
解決方針
開発中でテストデプロイ段階だったてめ、レコードの全消去は悪影響がない。
そのため、heroku環境でレコード全消去する方針で進める。
heroku run rails db:reset
ローカル開発環境では、rails db:resetでレコード全消去が可能。
heroku環境の場合、頭にheroku runをつけると良いので、以下のコマンドを実行。
$ heroku run rails db:reset
Rails5本番環境でのコマンド誤操作機能
しかし、Rails5から本番環境では、削除系コマンドの誤操作を防止する機能が追加されたようで、下記エラーが発生。
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
DISABLE_DATABASE_ENVIRONMENT_CHECK=1を付与してコマンドを実行すればよいようなので、
以下のコマンドを実行。
$ heroku run DISABLE_DATABASE_ENVIRONMENT_CHECK=1 rails db:reset
heroku環境での権限問題
しかし、heroku環境ではrails db:resetの権限がなく以下のエラーが発生。
FATAL: permission denied for database "postgres"
DETAIL: User does not have CONNECT privilege.
Couldn't drop database 'XXXXXXXXXXXXXXX'
rails aborted!
PG::ConnectionBad: FATAL: permission denied for database "postgres"
DETAIL: User does not have CONNECT privilege.
heroku pg:reset DATABASE_URL
そこでrails経由ではなく直接PostgreSQLにアクセスする形で以下のコマンドを実行。
$ heroku pg:reset DATABASE_URL
※ここでDATABASE_URLは既に変数が組み込まれているはずなので、そのままheroku pg:reset DATABASE_URLとコマンド実行してOKです。
※特に不要ですが、DATABASE_URL内に組み込まれている値が知りたい方はheroku configを実行して確認してみてください。
heroku pg:reset DATABASE_URLを実行するとすると、以下のような出力がある。
$ heroku pg:reset DATABASE_URL
▸ WARNING: Destructive action
▸ postgresql-〇〇〇-△△△ will lose all of its data
▸
▸ To proceed, type ●●● or re-run this
▸ command with --confirm ●●●
>
指示通り、以下のように>の後ろにタイプ。
$ heroku pg:reset DATABASE_URL
▸ WARNING: Destructive action
▸ postgresql-〇〇〇-△△△ will lose all of its data
▸
▸ To proceed, type ●●● or re-run this
▸ command with --confirm ●●●
> ●●●
Resetting postgresql-〇〇〇-△△△... doneと出力されればpg:reset成功です。
その後、heroku run rails db:migrateを実行すればテーブルが再作成される。
まとめ
長々と書いてしまったが、レコードを消去したいときは、
$ heroku pg:reset DATABASE_URL
▸ WARNING: Destructive action
▸ postgresql-〇〇〇-△△△ will lose all of its data
▸
▸ To proceed, type ●●● or re-run this
▸ command with --confirm ●●●
> ●●●
Resetting postgresql-〇〇〇-△△△... done
$ heroku run rails db:migrate
でOKです。