# はじめに
Rails 6 に追加された新機能を試す第115段。 今回は、PostgreSQL データベース存在チェック
編です。
Rails 6 では、PostgreSQLのデータベースを存在するかどうかをチェックする方法が少し変わりました。
データベースが存在しないときに、 bin/rails db:migrate
を実行した場合、 PostgreSQLのロケールが英語以外でも、 ActiveRecord::NoDatabaseError
が発生するようになりました。
Ruby 2.6.5, Rails 6.0.2.1, Rails 5.2.4.1 PostgreSQL 12.1 で確認しました。 (Rails 6.0.0 でこの修正が入っています。)
$ rails --version
Rails 6.0.2.1
今回は、PostgreSQL を日本語ロケール (ja_JP.UTF8
) で、Docker環境で起動し、 bin/rails db:migrate
コマンドを使って Rails 6.0.2.1 と Rails 5.2.4.1 の違いを確認してみます。
日本語ロケールの PostgreSQL の Docker環境の作成については、 PostgreSQL を Docker 環境で日本語ロケールで動作させる を参照してください。
PostgreSQL 側で直接、データベースが存在しないことを確認する
psql コマンドでデータベースが存在しないことを確認します。
$ psql app_development -U postgres
psql: エラー: サーバに接続できませんでした: FATAL: データベース"app_development"は存在しません
db:migrate を実行する
エラーを確認するために、 db:create
しないで db:migrate
を実行すると ActiveRecord::NoDatabaseError
が発生します。
$ bin/rails db:migrate
rails aborted!
ActiveRecord::NoDatabaseError: FATAL: データベース"app_development"は存在しません
/usr/local/bundle/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:50:in `rescue in postgresql_connection'
ちなみに PostgreSQL のロケールが英語 (en_US.UTF-8
) の場合も ActiveRecord::NoDatabaseError
となります。
$ bin/rails db:migrate
rails aborted!
ActiveRecord::NoDatabaseError: FATAL: database "app_development" does not exist
/usr/local/bundle/gems/activerecord-6.0.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:50:in `rescue in postgresql_connection'
Rails 5 では
PostgreSQL が ja_JP.UTF-8
の場合は、 PG::ConnectionBad
となります。 en_US.UTF-8
の場合は、 ActiveRecord::NoDatabaseError
になります。
ja_JP.UTF-8
の場合:
$ bin/rails db:migrate
rails aborted!
PG::ConnectionBad: FATAL: データベース"app_development"は存在しません
/usr/local/bundle/gems/pg-1.1.4/lib/pg.rb:56:in `initialize'
en_US.UTF-8
の場合
$ bin/rails db:migrate
rails aborted!
ActiveRecord::NoDatabaseError: FATAL: database "app_development" does not exist
/usr/local/bundle/gems/activerecord-5.2.4.1/lib/active_record/connection_adapters/postgresql_adapter.rb:696:in `rescue in connect'`
何が変わったのか
Rails 5 までは、 PG::ConnectionBad
が発生したときに、エラーメッセージに does not exist
が含まれた場合に ActiveRecord::NoDatabaseError
を発生させていました。
Rails 6 では、 PG::ConnectionBad
が発生したときに、エラーメッセージにデータベース名 (今回では、 app_development
) が含まれた場合に、 ActiveRecord::NoDatabaseError
を発生させるようにしています。
正確な判定ではないですが、データベース名による判定の方が誤判定が減るだろうという判断のようです。
試したソース