html_safe よりも raw
RailsGuidesの「5.1 Output Safety」に「To insert something verbatim use the raw helper rather than calling html_safe」とある。
<%= @cms.current_template.html_safe %>
ではなく:
<%= raw @cms.current_template %>
を使えということだが、これはなぜだろうか。RailsGuides には理由が書かれてない。
まず「@cms.current_template が nil だった場合に例外が起きないから」という理由が考えられる。nil には html_safe メソッドが存在しないため、例外が起きてしまう。「When to use raw() and when to use .html_safe」で指摘されている通りだ。
また、raw ヘルパーを使うことで、エスケープ処理の回避が明確になるのも利点の一つと考えられる。
<%= @safe_content %> <%# @safe_content = unsafe_content.safe_html %>
よりも:
<%= raw @safe_content %>
のほうが分かりやすい。
やはり RailsGuides に従って、html_safe ではなく raw を使うのが適切だろう。
raw よりも「<%==」
raw の他に RailsGuides で推奨されているのが「<%==」を使う方法である。
<%== @cms.current_template %>
この方法でも nil の例外は起きない。また、エスケープ処理の回避が明確になる。html_safe ではなく、raw あるいは「<%==」を使うべきだ。
さらに「<%==」には、raw と比べてもパフォーマンス上のメリットが少々ある。
handler = ActionView::Template::Handlers::ERB.new
handler.call ActionView::Template.new('<p><%= raw val %></p>', '', handler, {})
# => "@output_buffer = output_buffer || ActionView::OutputBuffer.new;@output_buffer.safe_append='<p>';@output_buffer.append=( raw val );@output_buffer.safe_append='</p>';@output_buffer.to_s"
handler = ActionView::Template::Handlers::ERB.new
handler.call ActionView::Template.new('<p><%== val %></p>', '', handler, {})
# => "@output_buffer = output_buffer || ActionView::OutputBuffer.new;@output_buffer.safe_append='<p>';@output_buffer.safe_append=( val );@output_buffer.safe_append='</p>';@output_buffer.to_s"
「@output_buffer.append=( raw val )
」より「@output_buffer.safe_append=( val )
」のほうが、ほんの少々速いはずだ。前者では val#html_safe? メソッドが呼ばれるのに対し、後者では呼ばれないからだ。