scaffoldの中身を理解するためにMVCコンポーネントと7つのアクションを個別で自作する開発現場でちゃんと使えるRails 4入門(2)(3/3 ページ)

» 2014年03月28日 18時00分 公開
[著:林慶、監修:山根剛司,株式会社アジャイルウェア]
前のページへ 1|2|3       

「new」「create」アクションを実装し、ブラウザーでデータを登録できるようにする

 indexアクションが完成したら、次はコンソールではなくブラウザーでデータを登録できるようにしましょう。

要求仕様

 ここでは冒頭で紹介した7つのアクションのうち、フォームを表示するための「new」と、フォームから投稿されたデータを登録する「create」を用意します。

 ただし、ビューを用意するのはnewアクションだけです。createアクションは実行後、データの登録が成功したらindexアクションにリダイレクトし、失敗したらnewアクションのビューを再レンダリングするようにします。

「form_for」メソッドを使いフォームを含むビューの実装

 以下にnewアクションのビューを示します。

<h1>新規利用者</h1>
 
<%= form_for(@user) do |f| %>
  <div class="field">
    <%= f.label :name %><br>
    <%= f.text_field :name %>
  </div>
  <div class="field">
    <%= f.label :department %><br>
    <%= f.text_field :department %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>
 
<%= link_to 'Back', users_path %>

 「form_for」メソッドは引数に取ったモデルオブジェクトのための<form>タグを生成します。このメソッドはモデルオブジェクトが未保存のデータであれば、createアクションに向けた宛先の情報を生成し、保存済みのデータであればその更新のためのアクションに向けた宛先の情報を生成してくれます。

 さらにform_forはブロックを取り、そのブロック変数(ここでは「f」)は第1引数に渡したオブジェクトの属性への<input>タグを生成するメソッドを呼び出せます。

「new」「create」アクションの実装

 次に、コントローラーでアクションのメソッドを定義します。

class UsersController < ApplicationController
  def index
    @users = User.all
  end
 
  def new
    @user = User.new
  end
 
  def create
    @user = User.new(user_params)
 
    if @user.save
      redirect_to users_url
    else
      render 'new'
    end
  end
 
  private
  def user_params
    params.require(:user).permit(:name, :department)
  end
end

 コントローラーのnewメソッドではインスタンス変数@userに引数なしで初期化したUserオブジェクトを代入しておきます。これはビューのform_forメソッドの引数となります。

Rails 4の新機能、Strong Parametersとは

 コントローラーのcreateメソッドはやや複雑ですが、モデルの各メソッドは「『rails console』コマンドで各コンポーネントの連携を切り離して機能を確認」節で説明したものと同じものです。

 ここで注目すべきものはUserモデルのnewメソッドに返り値を渡している「user_params」メソッド(上記コード21行目)です。

 form_forからモデルに基づくデータがパラメーターに与えられたとき、例えば「params[:user]」というオブジェクトがパラメーターをハッシュとして保持しています。

 しかし、このままだと「mass assignment脆弱性」といって、悪意のユーザーによるパラメーターの改ざんによる攻撃を受ける危険性があります。

 それを防止するために、Rails 3まではモデル属性へ一括代入する要素はモデル内で宣言するようになっていましたが、柔軟性がなく扱いづらいものでした。しかし、Rails 4からはコントローラでフィルタリングして許可したキーの「ハッシュ」だけを返す「Strong Parameters」という仕組みがコントローラーに導入されました。

 具体的には、フォームから投稿されたデータはリクエストパラメーターの"user"キーの値としてハッシュになっています。「params.require(:user)」は、そのハッシュを参照しており、そのハッシュに含まれていて良いキーだけを「permit」メソッドの引数として、指定した要素だけを持つハッシュを取り出します。

 そしてsaveメソッドを呼び出してデータベースに保存します。ただし、保存前に値が適切かどうかのバリデーションチェックが行われますので、不適切な値が含まれているとsaveメソッドの返り値はfalseとなり、未保存のデータを@userに格納したままnewアクションのビューをレンダリングします。つまり、ユーザーに入力をやり直すよう促せます。

「new」「create」アクションのルーティング設定と実行確認

 作成したアクションに対するルーティングを準備しましょう。「config/routes.rb」の「:user」を引数に取る「resources」メソッドのonlyオプションにnewとcreateを追加します。

resources :users, only: %i(index new create)

 このようにして「rake routes」コマンドを実行すると新しく以下のルーティングが追加されています。

          POST   /users(.:format)          users#create
 new_user GET    /users/new(.:format)      users#new

 これに従い、「http://localhost:3000/users/new」にアクセスすると、新規ユーザー登録のためのフォームを含むページが表示されています。そのフォームを埋め、投稿ボタンを押すと、createアクションにPOSTリクエストし、ユーザーが登録されます。

特定のレコードを指定する「show」「edit」「update」「destroy」アクションの実装

 今回からscaffoldの機能を自分たちの手で作り始めました。長くなりましたので、残念ながら今回は特定のレコードを指定しないアクションの実装までとします。

 次回はscaffoldのshow、edit、update、destroyといった特定のレコードを指定する機能のアクションを実装します。

著者プロフィール

林 慶(Rails技術者認定シルバー試験問題作成者)

平成2年大阪生まれ。2006年から高専で情報工学を学んでいたが当時は所謂プログラミングができない工学生だった。卒業後、高専の専攻科に上がったもののマンネリ化したキャンパスライフに飽きたため休学して渡豪。そこでプログラミングに対するコンプレックスを克服するためにRuby on Railsなどでアプリケーションを作ることを覚える。

帰国後から現在までは復学し推薦システムに関する研究を行いながら、アジャイルウェアでRuby on Railsアプリケーションの開発業務に従事している。

好きなメソッドはinject。


監修者プロフィール

山根 剛司(Ruby業務開発歴7年)

兵庫県生まれ。1997年からベンチャー系のパッケージベンダーで10年間勤務。当時、使用していた言語はJavaとサーバーサイドJavaScript。

2007年よりITコンサル会社に転職し、Rubyと出会って衝撃を受ける。基幹システムをRuby on Railsで置き換えるプロジェクトに従事。それ以来Ruby一筋で、Ruby on Railsのプラグインやgemも開発。

2013年より、株式会社アジャイルウェアに所属。アジャイルな手法で、Ruby on Railsを使って企業向けシステムを構築する業務に従事。

Ruby関西所属。好きなメソッドはtap。

Twitter:@spring_kuma、Facebook:山根 剛司


前のページへ 1|2|3       

Copyright © ITmedia, Inc. All Rights Reserved.

スポンサーからのお知らせPR

注目のテーマ

AI for エンジニアリング
「サプライチェーン攻撃」対策
1P情シスのための脆弱性管理/対策の現実解
OSSのサプライチェーン管理、取るべきアクションとは
Microsoft & Windows最前線2024
システム開発ノウハウ 【発注ナビ】PR
あなたにおすすめの記事PR

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。