Rails データベース接続の動作
最終更新日 2019年12月02日(月)
Table of Contents
この記事では、さまざまな Active Record バージョンを特定のデータベースを参照するように設定する方法について説明します。
Rails 4.1 以上
Rails には DATABASE_URL
から読み取るためのサポートがある程度の期間ありましたが、Rails 4.1 までは、Heroku が Rails のコア動作を使用できなくなるエッジケースが常に存在していました。このプルリクエストで導入された機能として、どのような RAILS_ENV
環境で実行しているかには関係なく、システム上に ENV["DATABASE_URL"]
が設定されている場合はそれが正規の接続情報として使用されます。この考え方は、本番モードで動作するようにローカルマシンを設定している場合でも、config/database.yml
ファイルへのコミットされた接続情報が存在する可能性があるということです。
production:
database: example_production
adapter: postgresql
host: localhost
password:
これはローカルでは機能する可能性がありますが、Heroku は別のマシンで Postgres サーバーを実行するため、Heroku にデプロイするときにアプリが空のパスワードで localhost
に接続しようとしても機能しません。常に ENV['DATABASE_URL']
(存在する場合) に接続しておくと、このような問題は存在しません。
Rails 4.1+ での接続の設定
デフォルトの接続情報は DATABASE_URL
からプルされますが、config/database.yml
内の追加の設定オプションがすべてマージされます。この考え方は、DATABASE_URL
に保持されているのは接続情報のみであり、動作に関する情報は含まれないということです。引き続き pool
の設定などの Active Record の動作を設定できます。
production:
encoding: utf8
pool: 15
config/database.yml
を使用して ENV['DATABASE_URL']
にある値を設定することはできません。変更できない属性の一覧を次に示します。
- adapter
- database
- username
- password
- host
- port
ただし、その他の属性は変更できます。これは、次を実行することによって確認できます。
$ heroku run console
> config = ActiveRecord::Base.configurations[Rails.env] ||
Rails.application.config.database_configuration[Rails.env]
> puts config
# => { :pool => 15, # ... }
Active Record 4.1+ の安全弁
ENV['DATABASE_URL']
とは別のデータベースに接続する必要がある場合、Rails 4.1+ では、database.yml
ファイル内の優先される URL キーがサポートされています。
production:
url: <%= ENV["SOME_OTHER_URL"] %>
これを行うと、DATABASE_URL
からの情報はマージされず、接続先の URL を明示することにより、すべての暗黙的な動作がスキップされると見なされます。これを使用すると、たとえばアダプタとして PostGIS を指定するなど、DATABASE_URL
内の情報を変更できます。
production:
url: <%= ENV.fetch('DATABASE_URL', '').sub(/^postgres/, "postgis") %>
URL キーを使用する場合は、pool
などの、マージされる接続以外の情報を渡すこともできます。
production:
url: <%= ENV["SOME_OTHER_URL"] %>
pool: 15
この動作は、上記の内容と同じです。url
内のデータは優先されますが、他はすべてマージされます。
Rails 4.1 より前
Rails 4.1 (Active Record 4.1) より前、データベースへの接続を正しく設定するための唯一の方法は config/database.yml
ファイルの使用でした。顧客に自分の接続情報をプルダウンし、それをソースにコミットするよう依頼する代わりに、Heroku は、ENV["DATABASE_URL"]
から読み取る独自の database.yml ファイルを挿入しました。4.1 より前のバージョンの Rails を使用している場合は、これが引き続き適用されます。このファイルは、次を実行することによって確認できます。
$ heroku run bash
$ cat config/database.yml
データベース接続を設定する必要がある場合は、ローカルで database.yml
にコミットしたどの内容も (このファイルが上書きされるために) 本番環境では使用されないため、それは困難です。代わりに、イニシャライザを使用してデータベース動作を設定する方法がいくつかあります。
これは単純なアプローチでしたが、それにより問題が発生しました。行っている内容がまったく明確ではなく、エッジケースの問題につながったためです。ファイルを “魔法のように” 上書きする代わりに、Rails 4.1+ では、Rails に組み込まれた機能を直接使用する方法に切り替えました。