ポイントを先に言いますと、action_view.renderの戻り値は文字列ではない、尚且つ、to_sしても文字列にならないこと です。

前提

  • Job処理の中、HTMLを生成したいので、ActionViewを直接に使う
def notification_body
  users = ...
  action_view = ActionView::Base.new(Rails.root.join('app', 'views'))
  action_view.assign users: users
  action_view.render(template: 'users/published.text.erb')
end

問題

  • 外部APIを呼び出す為notification_bodyをエスケープしようとするタイミングで、よく分からない下記のエラーになってしまった
NoMethodError: undefined method `each_byte' for nil:NilClass
from /Users/blueplanet/.rbenv/versions/2.1.5/lib/ruby/2.1.0/uri/common.rb:307:in `block in escape'

原因

  • 最初に書いたんですが、ActionView.render(...)の戻り値は文字列ではないからescapeがエラーになった
[23] pry(main)> result = action_view.render(template: 'users/published.text.erb')
...
[24] pry(main)> result.class
=> ActionView::OutputBuffer
[25] pry(main)> result.to_s.class
=> ActionView::OutputBuffer
[26] pry(main)>
  • さらに、result.to_sしても文字列にならない!!!

解決

  • to_strメソッドを使えば、文字列になります。
[27] pry(main)> result.to_str.class
=> String
[28] pry(main)>

参考記事

後で調査

  • [ ] ActionView::OutputBufferとは?
  • [ ] rakeの中でmailerを呼び出す際の処理はActionViewを使ってる?