MySQL を利用する Rails プロジェクトを起動しようとしたところ、下記のエラーが発生しました。

bin/rails s
# データベースアダプターには mysql2 を選択している状態なのに postgresql で接続しようとしている
Error loading the 'postgresql' Active Record adapter. Missing a gem it depends on? pg is not part of the bundle. Add it to your Gemfile. (LoadError)
# config/database.yml ファイルの中身一部抜粋

# mysql2 をデータベースアダプターとして利用しているため、
# PostgreSQL 接続のための pg ライブラリの追加を求めるエラーが発生しているのは何かおかしい。。
default: &default
  adapter: mysql2
#...

何でや、、と思い Rails のドキュメントを読んでいた所、公式サイトに Connection Preference に関する記述を見つけました。

Since pool is not in the ENV[‘DATABASE_URL’] provided connection information its information is merged in. Since adapter is duplicate, the ENV[‘DATABASE_URL’] connection information wins.

どうやら config/database.yml と ENV['DATABASE_URL'] の両方が設定されている場合、設定値に重複がある項目については ENV['DATABASE_URL'] の値が優先されるようでした。

今回は DATABASE_URL に下記の PostgreSQL URL が設定されてしまっていたため、config/database.yml では MySQL を利用していたのにも関わらず、データベースアダプターに PostgreSQL が使われてしまっていたようです。

env | grep DATABASE_URL
# 環境変数 DATABASE_URL に PostgreSQL の URL が設定されている
DATABASE_URL=postgresql://user:password@localhost:5432/something_development

そのため、DATABASE_URL の中身を空にすることで、本来の意図通りに config/database.yml の設定を反映させることができました。

# 筆者は fish を利用しているので set -e で環境変数を空にした
set -e DATABASE_URL

# 何も出力されないことを確認し DATABASE_URL が空であることを確認する
env | grep DATABASE_URL

# Rails サーバーが正常に起動するか再度確認する
bin/rails s

#...
# 無事アプリケーションサーバーが起動すること確認できれば OK
=> Booting Puma
=> Rails 6.0.3.6 application starting in development
=> Run `rails server --help` for more startup options
Puma starting in single mode...
* Version 4.3.7 (ruby 2.6.1-p33), codename: Mysterious Traveller
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://127.0.0.1:3000
* Listening on tcp://[::1]:3000
Use Ctrl-C to stop

今回はたまたま別プロジェクトでゴニョゴニョ作業をしていた名残で環境変数 DATABASE_URL が設定されてしまっていて、かつそのままの流れで Rails プロジェクトで作業していたため遭遇してしまいました。。

ローカル環境で変数を設定する際は direnv や dotenv 等を利用して極力手動では環境変数をいじらないようにしようと思いました (所感)

参考リンク