Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

[Rails5] Active Support Core ExtensionsのStringクラス(2)html_safe

こんにちは、hachi8833です。今回はRails 5 Active SupportのString#html_safeを見てみます。

今回のメソッド

条件

ソースのコメント等は適宜省略します。

html_safeは「安全」であるとマーキングする

今回取り上げるString#html_safeについては、TechRachoの以前の記事『RailsビューのHTMLエスケープは#link_toなどのヘルパーメソッドで解除されることがある』も合わせてお読みいただくことをおすすめします。

html_safeメソッドは対象が安全であることをマーキングし、以後エスケープを行わないようにするメソッドなので、安全であることが間違いなく確認できてから呼び出す必要があります。安全でないオブジェクトを安全にするものではありません

また、ソースのコメントでも「このメソッドよりもsanitizeメソッドをおすすめする」と記載されています。

output_safety.rbの構成

output_safety.rbでは以下をrequireしています。

require 'erb'
require 'active_support/core_ext/kernel/singleton_class'

output_safety.rbは大きく分けて以下のような構成になっています。html_safeは最後のStringクラスで定義されています。

  • ERBクラス内でUtilモジュールを定義
  • Objectクラス(html_safe?を定義)
  • Numericクラス(html_safe?を定義)
  • ActiveSupportモジュールでSafeBufferクラスを定義
  • Stringクラス(html_safeを定義)
class ERB
  module Util
    ...
  end
end
class Object
  def html_safe?
    false
  end
end
class Numeric
  def html_safe?
    true
  end
end
module ActiveSupport #:nodoc:
  class SafeBuffer < String
    class SafeConcatError < StandardError
      ...
    end
    ...
  end
end
class String
  def html_safe
    ActiveSupport::SafeBuffer.new(self)
  end
end

html_safe

html_safeのコードそのものは以下の1行だけであり、ActiveSupport::SafeBufferオブジェクトを作成して返しています。ActiveSupport::SafeBufferクラスは同じファイルにあります。

class String
  def html_safe
    ActiveSupport::SafeBuffer.new(self)
  end
end

ActiveSupport::SafeBufferは同じoutput_safety.rbファイルにあり、以下のメソッドがあります。

インスタンスメソッド

ここがhtml_safeの中心となるメソッド群です。

  • initializeメソッド
  • []メソッド
  • safe_concatメソッド
  • initialize_copyメソッド
  • clone_emptyメソッド
  • concatメソッド
  • prependメソッド
  • +メソッド
  • %メソッド
  • html_safe?メソッド
  • to_sメソッド
  • to_paramメソッド
  • encode_withメソッド

たとえばconcatメソッドは以下のように式展開のみエスケープして親クラスに渡しています。

def concat(value)
  super(html_escape_interpolated_argument(value))
end

プライベートメソッド

  • html_escape_interpolated_argumentメソッド

html_escape_interpolated_argumentは、html_safeでない式展開をエスケープします。

関連記事

Rails: ビューのHTMLエスケープは#link_toなどのヘルパーメソッドで解除されることがある


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。