(3) Url項目はそのURLへリンクさせる
一覧表示ページでリンクを張る
- ビュー list.rhtml
- app/views/softwares/list.rhtml
一覧表示の描画はlist.rhtmlの中で完結している。その中の該当箇所を見つけて...
<h1>Listing softwares</h1>
<table>
<tr>
<% for column in Software.content_columns %>
<th><%= column.human_name %></th>
<% end %>
</tr>
<% for software in @softwares %>
<tr>
<% for column in Software.content_columns %>
<td><%=h software.send(column.name) %></td>......[1]
<% end %>
<td><%= link_to 'Show', :action => 'show', :id => software %></td>
<td><%= link_to 'Edit', :action => 'edit', :id => software %></td>
...(以下省略)...
これは既に利用しているlink_toで実現できると思い、[1]の部分をifを使ってこんなコードで置き換えた。
<% if column.name == 'url' %>
<td><%= link_to software.send(column.name), software.send(column.name) %></td>
<% else %>
<td><%= software.send(column.name) %></td>
<% end %>
ところが、link_to_ifを使えば、この1メソッドで済んでしまうことに気づいた!1メッソドで済むというのは良いことだ!分かりやすい。
<td><%= link_to_if column.name == 'url',
software.send(column.name),
software.send(column.name) %></td>
個別表示ページでリンクを張る
- ビュー show.rhtml
- app/views/softwares/show.rhtml
個別表示もUrl項目を表示している箇所を見つけて...
<% for column in Software.content_columns %>
<p>
<b><%= column.human_name %>:</b> <%=h @software.send(column.name) %>......[2]
</p>
<% end %>
<%= link_to 'Edit', :action => 'edit', :id => @software %> |
<%= link_to 'Back', :action => 'list' %>
同じく、変更してみた。
<%= link_to_if column.name == 'url', @software.send(column.name), @software.send(column.name) %>
hの問題
べつにスケベなことが問題なのではない。(分かっていると思いますが...)
満足しかけたが、一つ些細なことに気が付いた。
<%=h software.send(column.name) %>
<%=h @software.send(column.name) %>
上記は修正前のコードだが、どちらも<%=h %>で囲まれている...。
それなら修正後も<%=h %>で囲んでしまえばいいじゃないかとやってみると、これが良くない。
hを付けると、このようにHTMLのソースとして表示されてしまい、リンク機能が発揮されないのだ。
それなら「hのことは忘れよう、たった1文字なのだから」と思いかけたが、なぜ、わざわざ二つの書き方があるのか調べてみた。
HTMLタグを利用して新規登録してみる
- Title
<h1>TEST</h1>
- Description
<table border="5" cellspacing="15" cellpadding="10"> <tr> <td>こんな</td><td>表現も</td><td>可能</td> </tr> </table>
セキュリティ対策
表現の幅が広がっていいじゃないかと思うのだが、実は良いことばかりではないらしい...。
もしも、良くないことを考える人がいて、そこに悪意のあるJavaScriptなんかが書かれてしまうと...。どんな事が起きるか想像もつかないが、何かの悪事に利用されるのはご免だ。
ネットワークに繋がっている環境では、誰もが接続できる環境にあるので、一握りの悪意かもしれないが、注意しておく必要があるらしい。webアプリケーション開発の習慣として身に付けたいので、hを付けるべきところにはちゃんと付ける事にした。
調べてみれば簡単なことで、h(対象文字列)のように、対象文字列を囲ってあげれば良いだけだ。最終的には以下のようにした。これでHTMLタグを付けて入力しても、表示されるだけで機能しないはず。
- list.rhtml
<td><%= link_to_if column.name == 'url', h(software.send(column.name)), software.send(column.name) %></td>
- show.rhtml
<%= link_to_if column.name == 'url', h(@software.send(column.name)), @software.send(column.name) %>
-
-
- 厳密にはurlの入力内容も検証する必要があるかも...。きっと、便利なvalidateを使って上手いやり方があるんだろうなー。
-
link_to_ifメッソドの構文
link_to_if リンクタグを付ける条件, 表示文字列, URL文字列
- リンクタグを付ける条件が満たされていれば、表示文字列はURLへリンクする。
- さもなければ、表示文字列だけ表示する。