第6回: タスクの一覧

2010/05/02

前回は、タスクを記録するデータベース周りの土台を作りました。

今回は、実際にタスクの一覧を表形式で表示してみましょう。

index アクション

エディタで app/controllers/tasks_controller.rb を開いて、次のように修正してください。

class TasksController < ApplicationController
  def index
    @tasks = Task.all(:conditions => { :done => false }, :order => "due_date")
  end
end

done カラムが false であるレコード群を due_date で昇順にソートして変数 @tasks にセットしています。

HTML テンプレート本体の修正

エディタで app/views/tasks/index.html.erb を開いて、次のように修正してください。

<h1>タスクの一覧</h1>

<table class="tasks">
  <col class="name" />
  <col class="due_date" />
  <% @tasks.each do |task| %>
    <%= render 'task', :task => task %>
  <% end %>
</table>

配列 @tasks の各要素をブロック変数 task にセットして do から end までを繰り返します。ループの内部では部分テンプレート 'task' にローカル変数 task を渡しています。

Rails 2.x では(正確に言うと、Rails 2.2 までは)

    <%= render :partial => 'task', :locals => { :task => task } %>

のように記述する必要がありました。簡単になりましたね。

[訂正] この記事を最初に発表した時は、render 'task', :locals => { :task => task } と書いてしまい、読者の方から「エラーになる」とご指摘いただきました。この書き方では task オブジェクトが部分テンプレートに渡りません。Rails 2.x での書き方は Rails 3.0 でも有効です(2010年5月11日)。

実は、もっと記述を簡潔にすることが可能です。

  <% @tasks.each do |task| %>
    <%= render 'task', :task => task %>
  <% end %>

のように部分テンプレート名、ローカル変数名、オブジェクトのクラス名が一致する場合、

  <%= render @tasks %>

と書くことができます。この書き方も Rails 2.3 で導入されました。

[訂正] 「実は」以降の文は、この記事の発表後に追加されました(2010年5月11日)。

部分テンプレートの作成

エディタで app/views/tasks/_task.html.erb を作成します。

<tr>
  <td><%= task.name %></td>
  <td><%= task.due_date %></td>
</tr>

ローカル変数 task は、テンプレート本体から渡された Task オブジェクトです。その name と due_date カラムの値を埋め込んでいます。

Rails 2.3 までは、セキュリティの観点から <%= h(task.name) %> のように h メソッドでエスケープする必要がありました。task.name の値に、危険な JavaScript コードが埋め込まれているかもしれないからです。しかし、Rails 3.0 では、文字列をテンプレート中に埋め込む際にデフォルトでエスケープしてくれるので h メソッドは不要になりました。なお、エスケープしたくない場合は、<%= raw(task.name) %> のように raw メソッドを使用します。

スタイルシートの作成

新しいスタイルシート public/stylesheets/tasks.css を作成してください。

table.tasks {
  width: 560px;
  margin: 5px auto;
  background-color: #eee;
  border-collapse: collapse;
  border-spacing: 0;
}

table.tasks tr {
  border: solid 1px #ccc;
}

table.tasks td {
  padding: 5px;
}

table.tasks col.name {
  width: 400px;
}

table.tasks col.due_date {
  background-color: #ddd;
}

レイアウト application.html.erb に stylesheet_link_tag :all という記述があるおかげで、public/stylesheets ディレクトリにある .css ファイルはすべてスタイルシートとして読み込まれます。

ブラウザで http://localhost:3000/tasks を開くと、次のような画面が現れます。

画面キャプチャ1