mmyoji's diary

プログラミングとか日々のどうでもいいこととか

rails runner実行時にちょっと困ったこと

追記

コメント欄にもあるように、どうやらアプリ起因のバグのようでした 😥

別のアプリケーション(Rails 4.2.5, Ruby 2.2.3)で同様のことをした際、環境変数が問題なく参照できました。

この現象が起きたアプリが Rails 4.1.6, ruby 2.1.4 なのでそのせいかな...うーん。

同じversionで検証しろ、という感じですが後ろは振り返らない主義なので←

(追記 🈁マデ)

普段ほとんど rails runner 使うことがないのですが、昨日仕事で使うことがあって謎の挙動に戸惑ったのでメモ。

config/initializers/ 下のファイルからRubyコードの入ったYAMLファイルを評価すると <%= %> 箇所のRubyコードが評価されず、すべて nil になってしまうという現象です。

具体例

config/foo.yml

development:
  host: "127.0.0.1"
  port: 6379
test:
  host: "127.0.0.1"
  port: 6379
production:
  host: <%= ENV["FOO_HOST"] %>
  port: <%= ENV["FOO_PORT"] %>

config/initializers/foo.rb

raw_file = File.read(Rails.root.join("config", "foo.yml"))
erb = ERB.new(raw_file).result
config = YAML.load(erb)[Rails.env]

# log に実行結果吐き出してみる
Rails.logger.info(config)

で適当に Bar クラスがあると仮定して, RAILS_ENV=production bundle exec rails runner "Bar.new" とかってやれば config/initializers/ の設定が読まれるはず...!

と期待して確かに読まれているのですが、logを見ると見事に host と port が nil になっていました...

ENV としていたところを単に 1 + 3 とかってしても nil になっててRubyコードが一切評価されないということに気づきました。

config/initializers/ 内で単に環境変数を参照することはできたりしたので、

gemで用意しろと言われて作成するyamlファイルの場合は大抵rubyコード書いても評価されるようになっているが(configとか), 自前でやる場合はYAMLである必要がないのであれば config/initializers/ に直接ENVなどを書いた方がよさそう

という結論に至りました。

もしくは rails runner 使わずに、 runner で実行したい処理を rake task に置き換えてあげれば動いてくれたので, 「runner 使うのやめな( ˘ω˘)」という感じでした。

今までは基本 rake task を作ってたのでこういう問題が(多分)起きなかったのですが、なんなんでしょう。もう少し詳しく調べたりしたいのですがあいにく時間がないので...英語でググってもヒットしないので(多分検索クエリがダメ)今回の事象よりもうちょっと深い部分の問題なのか、単に今触っているアプリケーションのどこかに変なことが書かれてるせいで起きているバグなのか...

Rails app を別で作ってみて、そこで検証する必要があると思いますが、とりあえずメモ程度に残しておきます。