RailsのViewテンプレート内でself.output_buffer.gsub!するとCould not concatenate to the buffer because it is not html safe.って勢いよく怒られるので回避する。
おつかれさまです。8月から無職です(どうしよう)。
さて
様々な名状しがたい事情により、テンプレート内で上部の文字列を置換したいと思いました。
<h1>メッセージ</h1>
<p>:message:</p>
<% self.output_buffer.gsub!(':message:', @message.content) %>
<footer><%= @message.author %></footer>
すると
ActiveSupport::SafeBuffer::SafeConcatError
# Could not concatenate to the buffer because it is not html safe.
いただきました。
これはActionView::OutputBuffer
のスーパークラスであるところのActiveSupport::SafeBuffer
の機能で、特定のメソッドを介した変更は!html_safe?
化させ、!html_safe?
に対してさらにsafe_concat
で文字列を追加していこうとすると例外が出るというやつです。
UNSAFE_STRING_METHODS = %w(
capitalize chomp chop delete downcase gsub lstrip next reverse rstrip
slice squeeze strip sub succ swapcase tr tr_s upcase
)
safe_concatを避ける
というわけで、gsub!
後にsafe_concat
が呼ばれなければこの例外は生じないので、
<h1>メッセージ</h1>
<p>:message:</p>
<footer><%= @message.author %></footer>
<% self.output_buffer.gsub!(':message:', @message.content) %>
最終行に持っていくと怒られません。
UNSAFE_STRING_METHODSを避ける
あるいはUNSAFE_STRING_METHODS
を回避するために
class String
alias :gsub_not_safety! :gsub!
end
して
<h1>メッセージ</h1>
<p>:message:</p>
<% self.output_buffer.gsub_not_safety!(':message:', @message.content) %>
<footer><%= @message.author %></footer>
HTML素通し
いずれもhtml_safe
という概念を完全に無視っているので、HTMLエスケープなどはされず、全部素通しです。さすがにこれはよくなさそうだなぁと思ったので、置換できるgemにまとめました。
https://github.com/mmmpa/kaizan