More than 1 year has passed since last update.

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? メソッドが呼ばれるのに対し、後者では呼ばれないからだ。