Ruby on Rails ステップ・バイ・ステップ
STEP 5: レコードの新規追加
今回は、タスクの追加機能を実装しましょう。
大まかな作業手順は次の通りです。
- 入力フォームのテンプレートを作ります。
- Tasks コントローラに new アクションを追加します。
- タスク一覧ページに「新規タスクの追加」リンクを設置します。
- Tasks コントローラに create アクションを追加します。
- Task モデルに、値の検証(validation)を行うコードを追加します。
- 入力フォームのテンプレートにエラーメッセージを表示するコードを追加します。
- Task モデルに、値の初期化コードを追加します。
入力フォームのテンプレートを作ります。
$ edit app/views/tasks/new.html.erb
<h1>新規タスクの追加</h1>
<% form_for @task do |f| %>
<table class="attributes">
<tr>
<th>件名</th>
<td><%= f.text_field :subject %></td>
</tr>
<tr>
<th>期日</th>
<td><%= f.date_select :due_date %></td>
</tr>
<tr>
<th>完了</th>
<td>
<%= f.radio_button :done, true %> Yes
<%= f.radio_button :done, false %> No
</td>
</tr>
<tr>
<th>注記</th>
<td><%= f.text_area :note, :size => '40x5' %></td>
</tr>
</table>
<div class="submit">
<%= f.submit '追加' %>
</div>
<% end %>
Tasks コントローラに new アクションを追加します。
$ edit app/views/tasks/new.html.erb
class TasksController < ApplicationController
(省略)
def show
@task = Task.find(params[:id])
end
def new
@task = Task.new
end
(省略)
end
アクションを定義する順番はアプリケーションの動作に影響を与えませんが、普通は index, show, new, edit, create, update, destroy の順で記述します。
タスク一覧ページに「新規タスクの追加」リンクを設置します。
$ edit app/views/tasks/index.html.erb
<h1>タスク一覧</h1> <div class="commands"> <%= link_to '新規タスクの追加', [ :new, :task ] %> </div> <table class="list"> (省略)
ここでは link_to の第2引数に [ :new, :task ] というシンボルの配列を指定しています。このように書くと、/tasks/new というURLパスへのリンクが生成されます。
詳しいことはいずれ説明しますので、今のところはこのまま納得してください。
なお、:task が「単数形」である点に注意してください。
では、ここで表示を確認してみましょう。
データベースの状態をリセットするため、テストフィクスチャをロードし直します。
$ rake db:fixtures:load
ブラウザでタスク一覧のページを表示し直します。

新たに設置された「新規タスクの追加」リンクをクリックすると、入力フォームが表示されます。

日付を選択するセレクトボックスが英語表記になっている点については気にしないでください。アプリケーションの日本語化は、後回しにします。
続いて、Tasks コントローラに create アクションを追加します。
$ edit app/controllers/tasks_controller.rb
class TasksController < ApplicationController
(省略)
def new
@task = Task.new
end
def create
@task = Task.new(params[:task])
if @task.save
redirect_to :tasks
else
render :action => 'new'
end
end
(省略)
end
入力フォームに適当な値を入力して、「追加」ボタンをクリックします。

タスク一覧に新しいタスクが追加されています。

次に、「件名」フィールドの値が空であった場合に、エラーメッセージとともに入力フォームが再表示されるようにします。
データベーステーブルに格納されるレコードの値が正しいかどうか確かめることを値の検証と呼びます。
Task モデルに、値の検証を行うコードを追加します。
$ edit app/models/task.rb
class Task < ActiveRecord::Base validates_presence_of :subject end
値の検証はコントローラのアクションの中で行うのではなく、モデルの中で行います。
これは、Ruby on Railsプログラミングの最も重要な原則の1つです。
入力フォームのテンプレートにエラーメッセージを表示するコードを追加します。
$ edit app/views/tasks/new.html.erb
<h1>新規タスクの追加</h1> <% form_for @task do |f| %> <%= f.error_messages %> <table class="attributes"> (省略)
CSSファイルに設定を追加します。
$ edit public/stylesheets/application.css
(省略)
div.errorExplanation {
background-color: #fcc;
border: 1px solid #f00;
padding: 3px;
}
div.errorExplanation h2 {
color: #f00;
padding: 3px;
margin: 0;
border: none;
}
div.errorExplanation p {
padding: 3px;
}
.fieldWithErrors {
background-color: #fcc;
color: #000;
padding: 2px;
}
入力フォームの「件名」フィールドを空にしたまま、「追加」ボタンをクリックすると、次のような画面になります。

エラーメッセージが英語表記になっていますが、「件名(subject)は空ではダメ」と正しい判定を行っています。
続いて「件名」に何か文字を入力して「追加」ボタンをクリックすると、タスクが追加されます。値の検証は正しく動いているようですね。
これでだいたいOKですが、1つ気になる点があります。
入力フォームの初期状態で、完了フィールドの値を選ぶ2つのラジオボタンのいずれもチェックされていない、ということです。
常識的には「No」が選ばれている状態で始まるべきです。
そうするためには、Task モデルに次のような初期化コードを追加します。
class Task < ActiveRecord::Base
validates_presence_of :subject
protected
def after_initialize
self.done = false if self.done.nil?
end
end
after_initialize メソッドは、モデルクラスが「インスタンス化」された直後に実行されるメソッドです。このように、何かのきっかけで実行されるメソッドをコールバックと呼びます。
コールバックメソッドの可視性は public ではなく protected にします。
ところで、Tasksコントローラのnewアクションの中で @task = Task.new(:done => false) のように書いても同じ効果が得られます。しかし、モデルオブジェクトに初期値を与える仕事はコントローラの領域とは言い難いので、モデルに記述した方が好ましいと思われます。
では、タスク一覧ページに戻って「新規タスクの追加」リンクをクリックしてみましょう。

初めから、完了フィールドの「No」が選択された状態になっている点を確認してください。
(2010/02/01)
記事に関するご質問は、 hermes@oiax.jp までメールでお送りください。
ウェブサイト構築の発注先を検討されているお客様は、ご相談フォームをご利用ください。
- はじめに
- STEP 1: アプリケーションの作成からトップページの表示まで (2010/01/26)
- STEP 2: レイアウト (2010/01/27)
- STEP 3: レコードの一覧 (2010/01/29)
- STEP 4: レコードの詳細表示と削除 (2010/01/30)
- STEP 5: レコードの新規追加 (2010/02/01)
- STEP 7: 基本7アクション (2010/02/02)
- STEP 6: レコードの編集 (2010/02/02)
- STEP 8: 未完了タスクの一覧 (2010/02/03)
- STEP 9: タスクの簡易表示 (2010/02/12)
- STEP 10: finishアクションの実装 (2010/02/13)
- STEP 11: 確認画面(1) (2010/02/14)
- STEP 13: 確認画面(3) (2010/02/25)
- STEP 12: 確認画面(2) (2010/02/25)
- STEP 14: 確認画面(4) (2010/02/26)

