Rubyの変数DATABASE_URLでハマった話

あらすじ

  • 一台のサーバーに複数のRailsアプリケーションがある
  • 新しく一つRailsアプリケーションを作成した
  • config/database.yml を見るとこんなコメントアウトがあった
# On Heroku and other platform providers, you may have a full connection URL
# available as an environment variable. For example:
#
#   DATABASE_URL="mysql2://myuser:mypass@localhost/somedatabase"
#
# You can use this database configuration with:
#
#   production:
#     url: <%= ENV['DATABASE_URL'] %>
#
  • こんな変数があるのね。 database.yml で使ってみた
production:
  url: <%= ENV['DATABASE_URL'] %>
  • 変数を .bash_profile あたりに定義
export DATABASE_URL="mysql2://myuser:mypass@localhost/somedatabase"
  • 結果、同じサーバーに存在している全部のRailsアプリケーションが上記の接続先を見に行った!

原因

コメントでも DATABASE_URL を使用してね、とあるが、環境変数に ENV['DATABASE_URL'] が存在すると active_record/connection_handling.rbDATABASE_URL がマージされてしまう模様。

以下、引用。

config/database.ymlファイルと環境変数ENV[‘DATABASE_URL’]が両方存在する場合、両者の設定はマージして使用されます。以下のいくつかの例を参照して理解を深めてください。

提供された接続情報が重複している場合、環境変数が優先されます。

提供された複数の情報が重複しておらず、競合している場合も、常に環境変数の接続設定が優先されます。

poolはENV[‘DATABASE_URL’]で提供される情報に含まれていないので、マージされています。adapterは重複しているので、ENV[‘DATABASE_URL’]の接続情報が優先されています。

ENV[‘DATABASE_URL’]の情報よりもdatabase.ymlの情報を優先する唯一の方法は、database.ymlで”url”サブキーを使用して明示的にURL接続を指定することです。

マージしているのは、このあたりかな。 ./vendor/bundle/ruby/2.1.0/gems/activerecord-4.1.15/lib/active_record/connection_handling.rb

66       # Returns fully resolved connection hashes.
67       # Merges connection information from `ENV['DATABASE_URL']` if available.
68       def resolve
69         ConnectionAdapters::ConnectionSpecification::Resolver.new(config).resolve_all
70       end
71
72       private
73         def config
74           @raw_config.dup.tap do |cfg|
75             if url = ENV['DATABASE_URL']
76               cfg[@env] ||= {}
77               cfg[@env]["url"] ||= url
78             end
79           end
80         end

まあ影響範囲を考えて使いましょうという話。

関連記事(この記事の初版より古い記事はリンクがグレーで表示されます)

  1. 2016/06/05 [Ruby] Rubyで自然言語っぽくcrontab管理できるwheneverを使う
  2. 2016/02/17 [Ruby] [Mac] El Capitan上に古いpumaをインストールすると失敗する
  3. 2017/03/30 [Ruby] rbenvを最新にして新しいバージョンのRubyをインストールできるようにする
  4. 2015/02/28 [Ruby] rubyXLを使ってExcelを操作したい
  5. 2014/08/28 [Sphinx] [Ruby] [イベント] kawasaki.rb #015 でSphinx導入事例の発表をしてきました #kwskrb #sphinxjp
  6. 2014/07/13 [Sphinx] [Ruby] [イベント] kawasaki.rb #013 でSphinx導入事例の発表をしてきました と #011 #012 参加記録 #kwskrb #sphinxjp
  7. 2014/04/01 [Ruby] [Jekyll] [イベント] kawasaki.rb #010 で発表してきました #kwskrb
  8. 2014/01/28 [Jekyll] [GitHub] [Ruby] Jekyllプロジェクトへpull requestを行う手順(したとは言っていない)
  9. 2013/12/24 [Ruby] RubyでQRコードを生成してみる
  10. 2013/09/07 [Ruby] [Git] [Jekyll] Jekyllバージョンアップの際に思いのほか手こずった話 てっく煮さん製プラグインの更新に追従したい編
  11. 2013/09/03 [Ruby] [Rails] Ruby1.9.3のWebrickで出るCould not determine content-length...エラーを消す方法(2.0.0では解決済)
  12. 2013/08/26 [Ruby] ソースコード中に0xC2A0(UTF-8のNO-BREAK SPACE)が混ざり実行できなくて困った話
  13. 2013/08/20 [Ruby] [Rails] [Redmine] Rails3のログ出力にANSIカラーコードを使用しない設定
  14. 2013/08/09 [Ruby] [Redmine] [MySql] [StartUp] WindowsにRedmine2.3をインストールする手順と、プラグイン作成用メモ
  15. 2013/08/07 [Ruby] [Jekyll] [Git] Jekyllバージョンアップの際に思いのほか手こずった話 Jekyll Bootstrapの更新に追従したい編