Heroku
PostgreSQL
Rails5

rails5 on herokuでPostgreSQLのレコードをすべて消したい時の方法

背景

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