ハッシュを ERB テンプレートとして使用する場合、Ruby は「エンコーディング」について不平を言います
概要
ただそれだけに
require 'erb'
a = "això és una merda <%=rand(1..20)%>"
c = {"id" => "això és una merda <%=rand(1..10)%>"}
ERB.new(a).result を実行すると、すべて問題ありません。
ERB.new(a).result
=> "això és una merda 3"
しかし、ERB.new(c).result を使用すると、Ruby はエンコーディングの問題を訴えます。
ERB.new(c).result
/usr/lib/ruby/3.0.0/erb/compiler.rb:315:in `compile': undefined method `encoding' for {"id"=>"això és una merda <%=rand(1..10)%>"}:Hash (NoMethodError)
from /usr/lib/ruby/3.0.0/erb.rb:351:in `initialize'
from (irb):57:in `new'
from (irb):57:in `<main>'
from /usr/lib/ruby/gems/3.0.0/gems/irb-1.4.2/exe/irb:11:in `<top (required)>'
from /usr/bin/irb:25:in `load'
from /usr/bin/irb:25:in `<main>'
私が期待した結果は次のとおりです。
{"id" => "això és una merda 3"}
c を文字列としてキャストすることもできますが、ハッシュとしてキャストしたいと考えています。
解決策
ERB は文字列に対してのみ機能します。文字列の配列や文字列のキーや値を含むハッシュなどの文字列を含む構造がある場合は、文字列を個別に処理する必要があります。
ハッシュ値を処理するには、transform_values を使用できます。これは各値をブロックに渡し、ブロックの結果で値を更新します。
require 'erb'
c = {"id" => "això és una merda <%=rand(1..10)%>"}
c.transform_values! { |str| ERB.new(str).result }
c #=> {"id"=>"això és una merda 7"}
(レシーバーを変更せずに新しいハッシュを返す非!バリアントもあります)