RESTful なインターフェースを備えた Web アプリケーション(その 3)
これでおしまいだと思った ? 残念さやかちゃんでした ! w
せっかくだからアプリケーションっぽくどんどん作り込みましょう。今度は新規登録フォームを作ります。その前に、自動生成されたテストコード用のファイルを修正しておきます。
sample/test/functional/customers_controller_test.rb
require 'test_helper' class CustomersControllerTest < ActionController::TestCase test "should get index" do get :index assert_response :success end test "should get show" do get :show assert_response :success end test "should get new" do get :new assert_response :success end test "should get create" do post :create assert_response :success end end
index と show に関する部分は既に出来上がっているはずですので new と create に関する部分を追加してください。もっとも今回はテストコードは書かないので、あまり気にしなくてもいいです(最悪修正しなくても大丈夫かも)。
View の修正と新規作成
既存の View も少し修正します。
sample/app/views/customers/index.html.erb
<h1>顧客一覧</h1> <table border> <thead> <tr> <th>顧客 ID</th> <th>顧客名</th> <th></th> </tr> </thead> <tbody> <% @customers.each { |c| %> <tr> <td><%= c.id %></td> <td><%= c.name %></td> <td><%= button_to '詳細', customer_path(c.id), :method => :get %></td> </tr> <% } %> </tbody> </table> <%= button_to '新規登録', new_customer_path, :method => :get %>
一番下に新規登録用のボタンを付けました。ここでも Url Helper をつかって /customers/new へのリンクを付けています。new アクションには GET メソッドでアクセスするのでしたね。
sample/app/views/customers/show.html.erb (再掲)
<h1>顧客詳細</h1> <table border> <tr><th>顧客 ID</th><td><%= @customer.id %></td></tr> <tr><th>顧客名</th><td><%= @customer.name %></td></tr> <tr><th>連絡先</th><td><%= @customer.phone %></td></tr> </table> <p><%= link_to '一覧に戻る', customers_path %></p>
sample/app/assets/stylesheets/customers.css.scss
h1 { text-align : center; font-size : x-large } table { margin : 2em auto } p, div { text-align : center }
ここまでできたら、新たに sample/app/views/customers 直下に new.html.erb と create.html.erb を作ります。
sample/app/views/customers/new.html.erb
<h1>新規登録</h1> <%= form_for(@customer) { |f| %> <table> <tr> <th>顧客名</th> <td><%= f.text_field :name, { :size => 20, :required => true } %></td> </tr> <tr> <th>連絡先</th> <td><%= f.text_field :phone, { :size => 20, :required => true } %></td> </tr> </table> <p><%= f.submit '登録' %></p> <% } %> <p><%= link_to '一覧に戻る', customers_path %></p>
Model に対応したフォームを作る Form Helper である form_for を使います。action の URL は Model オブジェクトの状態で自動で判断されるので省略できます。また、未入力の項目が残っている場合は送信ができないようにしています*1。
sample/app/views/customers/create.html.erb
<p><%= @msg %></p> <table border> <tr><th>顧客名</th><td><%= @customer.name %></td></tr> <tr><th>連絡先</th><td><%= @customer.phone %></td></tr> </table> <p><%= link_to '一覧に戻る', customers_path %></p>
@msg は後で Controller から送られてくるメッセージの表示用の変数です。メッセージと登録した内容の確認画面になっています。
Controller の修正
sample/app/controllers/customers_controller.rb
# coding: utf-8 class CustomersController < ApplicationController layout 'customers' def index @customers = Customer.all end def show @customer = Customer.find(params[:id]) end def new @customer = Customer.new end def create @customer = Customer.create(params[:customer]) if !@customer.new_record? @msg = '登録されました' else @msg = '登録に失敗しました' end end end
新たに new アクションと create アクションの動作を定義します。マルチバイト文字も含まれているので先頭のマジックコメントを忘れずに。
create アクションの Customer.create メソッドに対して渡している引数に注目してください。params で引き渡されたパラメータを受け取れるのですが、params[:customer] と書くことで、Model に紐づいているフォームの入力内容をまとめて受け取ることができます。create メソッドは引数を受け取って新しい Model オブジェクトを作り、データベースに格納します。登録に成功したかどうかを new_record? メソッドの返り値で判断させています(登録に成功すると new_record? は false を返す)。さてどんな出来になるのかな ? それはまた後程。
*1:Validation のチェックはしないのか、というツッコミが来そうですが、それは複雑になるので今回はパスということでw