背景
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です。