すがブロ

sugamasaoのhatenablogだよ

Railsで定数を別ファイルで管理したい? よろしい、ならば Settingslogic だ。

ソースの中で定数として扱うのではなく、設定ファイル的に扱いたい

Rubyはそれなりに長い間使っていますが、Railsはメジャーバージョン毎にちょっと触るくらいで、まったくベストプラクティスとか知らないんですね。
で、いまは作る際のお手本として 日本Ruby会議 2010, 8月27日〜29日 のソースである ruby-no-kai/rubykaigi · GitHub を見てパクれそうなのはパクるというスタンスでやってます。

で、本題の設定ファイルの扱いについて

上記 rubykaigi の Gemfile を見ると 'configatron' っていうのがある。
なので、これが cool な設定ファイルを扱うライブラリなのかしら、と思ってたのですが、ちょうど id:ursm さんから

という助言を頂いたので、そっちで試してみることにしました。

Settingslogicの使い方

binarylogic/settingslogic · GitHub の README にある通りですが……

  • Gemfile に 'settingslogic' を追加
  • bundle update でインストール
設定ファイル用 model を作る

vim app/models/settings.rb

class Settings < Settingslogic
  source "#{Rails.root}/config/application.yml"
  namespace Rails.env
end

ただ、グローバルな設定をしたいなら namepsace は無くても良い(詳しくは後述)。

設定ファイルを作成する

上記の source で指定しているパスと合わせる必要があるので注意。

vim config/application.yml

# app/config/application.yml
defaults: &defaults
  cool:
    saweet: nested settings
  neat_setting: 24
  awesome_setting: <%= "Did you know 5 + 5 = #{5 + 5}?" %>

development:
  <<: *defaults
  neat_setting: 800

test:
  <<: *defaults

production:
  <<: *defaults

こうすることで、 Rails環境変数によって defaults + test などを変化させることができるので、環境によって値を変えたい場合でも特に余計な手順を踏むことなく、柔軟に対応できる。
また、 namespace で値を変える必要ないから不要だよ、という場合は namespace をコメントアウトして、 application.yml のほうで defaults などを記載せず直接 yml で値を書いてしまえば使える(逆に言えば、namespace を指定する場合は、対応する namespace の定義が無いと何も読み込んでくれない)。

読み出し方

app/controllers/hoge_controller.rb 内から普通に読み出すことができる。

logger.debug Settings.cool.saweet
#=> nested settings

Settingslogic 気に入った

model を挟むというのがユニークですけど、yml で書いたのが特に意識せずそのまま使えてラクで良いですね。これは良い!
enjoy!