状況
-
フォームで改行を入力
-
出力時に改行が反映されない
環境
-
macOS Catalina 10.15.6
-
ruby 2.6.5
-
Rails 6.0.3.4
-
MySQL : 5.6.47
-
Bootstrap : 4.3.1
学んだコード
-
simple_format : ヘルパーメソッド。改行をpタグやbrタグで表現
-
hオプション : XSS対策。simple_formatにエスケープ機能を付与
【参照】
今回のコード
def show
@task = Task.find(params[:id])
@commits = @task.commits
end
<% @commits.each do |commit| %>
<%= commit.content %>
<% end %>
この表示の仕方だと、commit.contentの改行が反映されません。
これはsimple_formatを使うことで解決できます。実際にやってみましょう。
simple_formatを使う
<!-- simple_formatを使う -->
<% @commits.each do |commit| %>
<%= simple_format(commit.content) %>
<% end %>
simple_formatは、改行をpタグやbrタグで表現してくれるヘルパーメソッドです。
出力したいテキストをsimple_formatに入れるだけで完了します。
さて、とりあえず目標達成です。
しかし、この実装には問題があります。それは「エスケープ」ができていないということです。
詳しく見ていきましょう。
エスケープできるようにする
エスケープは、セキュリティ対策で使われる技術です。簡単に言うと「意味がある文字の意味をなくす」役割があります。
具体的に見ていきます。
例えばこんな入力をしたとします。
この値をエスケープしないまま表示すると、こんな感じで「HTMLタグ」として認識されてしまいます。
HTMLでは "<" を「タグが始まりますよ!」という意味で認識します。よってエスケープしない場合はh1要素として表示してしまいます。
このエスケープ機能は、Railsのビューで用いる<%= %>を使うことで付与されます。
しかし、simple_formatを使ってしまうと、この機能が失われます。
よって、simple_formatを使う際は、hオプションを使います。これはsimple_formatにエスケープ機能を付与してくれる優れものです。
<%# hオプションを使う %>
<% @commits.each do |commit| %>
<%= simple_format(h(commit.content)) %>
<% end %>
こうすると、表示が下記のように変化します。
"<"などから意味が奪われ、ただの記号や文字として表示されています。それに伴い文字も小さくなりました!(pタグで囲まれた)
まとめ
-
formの改行を反映させたい
-
simple_formatで可能!
-
セキュリティ対策のため h を使うとベター
simple_formatは使う機会が多そうですが、セキュリティ対策を怠ると怖いヘルパーメソッドでもあります。使う際は頭に入れて使っていきます。