コメントにてご指摘をいただきました
HTMLタグを動的に生成する必要がある場合も、content_tagや(aタグでは)link_toなど、Railsの用意しているヘルパーを使えば、HTMLとして出力するかエスケープするかを適宜判断してくれます(自分でhやhtml_safeしなくて問題ありません)。
def return_url2(text)
link_to text, 'http://google.com/'
end
純粋な文字列リテラルを.html_safeするのはありかもしれませんが、どこから来るかわからない入力で、テキストからHTMLを生成するのは、(ユーザーからHTMLを受け付けることが本当に必要な場合など)よほどの場合をのぞいて避けるべきでしょう。
Rails3からはHTMLタグが自動エスケープする
Rails3からの機能らしいんですが、
ERBで
<%= @text %>
とかやって@text
内の文字列をHTMLに変換するときにHTMLタグ等を自動でエスケープするようになってます。
これはユーザーに任意で文字列を入力してもらうときのセキュリティ対策として必須です。
けどHTMLタグをHelperとかで作成したい場合とか困ります。
def return_url
return "<a href="http://google.com">http://google.com</a>"
end
<%= return_url %>
↓こうHTML出力される
<a href="http://google.com">http://google.com</a>
html_safeメソッドを使おう
そんなときは html_safe
メソッドを使う
<%= return_url.html_safe %>
とすると、http://google.com がこちらで意図したとおりaタグで出力されます。
けどセキュリティ的に心配
さっきのHelperメソッドレベルであればhtml_safeメソッドを使うだけで問題ないんですが、ユーザーが任意で入力できるテキストにこちらが意図してHTMLタグを埋め込みたい場合に困ります。
例えばメッセージ等の中にURLが組み込まれている場合、それをaタグで囲ってブラウザ上でクリックできる状態(=有効化)にしたい。。
けどメッセージはユーザーが任意で入力できるため、ユーザーが入力したHTMLタグ等はエスケープ(=無効化)したい。。
という割とよくある?ケースにはこうしたほうが良いです。
<%= return_url2(h(@test_text)).html_safe %>
ちょっとわかりづらいので順を追って。。
1.controllerから取得したテキストをhメソッドでエスケープ(無効化)します。
h(@test_text)
2.エスケープした後の@test_text
をHelperメソッドのreturn_url2
に渡します。
(return_url2
メソッドは任意)
return_url2(h(@test_text))
3.return_url2
メソッドの結果をhtml_safeにする
(こちらが意図して付けたHTMLタグは有効化する)
return_url2(h(@test_text)).html_safe
4.完成。
<%= return_url2(h(@test_text)).html_safe %>
まとめ
html_safeメソッド(HTMLタグの有効化)とhメソッド(HTMLタグのエスケープ=無効化)をきちんと使い分ければHTMLタグエスケープもあなたのもの!
※もうちょっといい書き方あるよってひとは是非教えて下さい!!