くりにっき

ドリコムのプリキュアの人です

Padrinoでアプリ作る時もdatabase.ymlを作った方がよかった

よく忘れるのでメモ

Padrino でアプリを作ると config/database.rb に

##
# You can use other adapters like:
#
#   ActiveRecord::Base.configurations[:development] = {
#     :adapter   => 'mysql2',
#     :encoding  => 'utf8',
#     :reconnect => true,
#     :database  => 'your_database',
#     :pool      => 5,
#     :username  => 'root',
#     :password  => '',
#     :host      => 'localhost',
#     :socket    => '/tmp/mysql.sock'
#   }
#
ActiveRecord::Base.configurations[:development] = {
  :adapter => 'sqlite3',
  :database => Padrino.root('db', 'ccc_privacy_crawler_development.db')

}

ActiveRecord::Base.configurations[:production] = {
  :adapter => 'sqlite3',
  :database => Padrino.root('db', 'ccc_privacy_crawler_production.db')

}

ActiveRecord::Base.configurations[:test] = {
  :adapter => 'sqlite3',
  :database => Padrino.root('db', 'ccc_privacy_crawler_test.db')

}

のようにデータベースの設定がベタ書きされますが、それを

ActiveRecord::Base.configurations = YAML.load(ERB.new(File.read(Padrino.root('config', 'database.yml'))).result).with_indifferent_access

のように config/database.yml から読み込むようにするといろいろ便利になります

実際の修正

https://github.com/sue445/ccc_privacy_crawler/commit/3d776c0fc89be25ff06c473b494941ba0e720ebd

理由1: 環境依存の設定をリポジトリにコミットしなくてよくなる

データベースのユーザ名やパスワードは個々の環境によって割と異なるので、ソースコードではなく設定ファイルに外出ししていると複数人開発がやりやすくなります

Railsだと config/database.yml はリポジトリにコミットせず(.gitignoreに追加)

# テンプレをコピー
cp config/database.yml{.example,}

# ローカルの設定を書く
vi config/database.yml

のようにすることが多いです*1

理由2: config/database.yml があるとHerokuデプロイ時によしなに上書きしてくれる

config/database.ymlがあると(厳密にはRubyアプリだと?) Herokuにデプロイする時にHeroku用のdatabase.ymlが上書きされるので便利です

f:id:sue445:20150124121026p:plain

ActiveRecord::Base.configurations = YAML.load_file(Padrino.root('config', 'database.yml')).with_indifferent_access

ではなく

ActiveRecord::Base.configurations = YAML.load(ERB.new(File.read(Padrino.root('config', 'database.yml'))).result).with_indifferent_access

なのがポイントで、Herokuで上書きされるdatabase.ymlはerb形式なので YAML.load_file だとerbを評価しないのでエラーになります

Herokuで使われるdatabase.ymlはこういう形式らしい

*1:少なくとも自分の周りでは