Rails開発を面白くするアクションコントローラーの5大機能とルーティングの基本開発現場でちゃんと使えるRails 4入門(7)(2/3 ページ)

» 2014年07月30日 18時00分 公開
[著:林慶、監修:山根剛司株式会社アジャイルウェア]

Rails 4から導入された「Strong Parameter」

 Rails 4から導入されたStrong Parameterはリクエストに含まれていてもよいパラメーターをコントローラーで指定する機能です。悪意のあるユーザーがフォームに存在していない属性の入力欄を追加してPOSTリクエストしてきても、その属性を弾くことができます。

 Strong Parameterの挙動を理解するために前節のPOSTデータパラメーターを使って実験してみましょう。

 まず「new」メソッドに「params」が持つパラメーターをHashオブジェクトのように渡すRails 4より前のやり方を試してみます。

  1. params[:book] => {
  2. "title" => "新しい本",
  3. "author" => "新しい作者"
  4. }
  5. Book.new(params[:book])
  6. => ActiveModel::ForbiddenAttributesError: ActiveModel::ForbiddenAttributesError

 このように「params」をHashオブジェクトと同じようにモデルの複数属性の初期化に使うとエラーが発生します。

 それでは、「params」とは何でしょうか。

  1. params[:book].class
  2. => ActionController::Parameters < ActiveSupport::HashWithIndifferentAccess
  3. params[:book].class.superclass
  4. => ActiveSupport::HashWithIndifferentAccess < Hash

 「params」はHashクラスを継承していますが、Hashではありません。これを用いて複数属性の初期化に用いるには次のようにメソッドチェインの返り値を使います。

  1. Book.new(params.require(:book).permit(:title))
  2. => #<Book:0x007fc8d8781088>
  3. => Unpermitted parameters: author

 「permit」メソッドの引数には初期化する複数の属性名を渡せます。そこに含まれていない属性がparamsに含まれていると上のようなログが出力されます。

  1. Book.new(params.require(:book).permit(:title, :author))
  2. => #<Book:0x007fc8d8781088>

 上記のように、作成・更新に使いたいパラメーターだけをpermitし、paramsからBookクラスのインスタンスを生成します。

【2】リクエスト間でデータを保存する「クッキーとセッション」

 クッキーとセッションはリクエストの間でデータを保存する方法で、ログイン状態の管理などに使われます。

クッキー

 クッキーはユーザー側で一時的に保存されるデータです。セッションを使う上でもセッションIDをユーザー側で保存するために使われます。クッキーを保存するには次のように操作します。

  1. # クッキーの値だけを保存(この値はブラウザーを閉じると消去されます)
  2. cookies[:condition] = good
  3. # オプションを付けて保存
  4. cookies[:condition] = {
  5. value: soso’, # クッキーの値
  6. expires: 1.day.from_now # クッキーの有効期限
  7. }

 またクッキーを読み出すときはハッシュと同じようにします。

  1. cookies[:condition] # => ‘soso’
  2. # 設定されていなければ
  3. cookies[:hoge] # => nil

セッション

 セッション、データをサーバーで保持し、そのデータを取り出すセッションIDをクッキーとしてユーザー側で保存します。セッションは次のように保存します。

session[:user_id] = @user.id

 取り出すときはクッキーと同様です。

session[:user_id] # => 1

【3】簡単なメッセージを表示する「フラッシュ」

 フラッシュはデータの保存成功などの簡単なメッセージを表示する仕組みです。フラッシュはセッションに保存され、リダイレクトした先でも設定したメッセージを表示できます。

  1. def index
  2. flash[:notice] = “現在時刻:#{Time.now}”
  3. end

 表示するにはビューで次のようにして設定したキーで呼び出します。

  1. <div id=”flash”>
  2. <%= flash[:notice] %>
  3. </div>

 フラッシュはアクションが終了する際に削除されるため、以降のリクエストでは表示されません。

【4】アクションを実行する前後に処理を挟む「フィルター」

 「ActionController」には、アクションを実行する前後に前処理や後処理を挟むフィルターが用意されています。アクションの前に実行される「before_action」フィルター、後に実行される「after_action」フィルター、アクションの前後にまたがって実行される「around_filter」フィルターがあります。

 「scaffold」で作成したコントローラーでは次のようなフィルターが実装されています。

  1. class BooksController < ApplicationController
  2. before_action :set_book, only: [:show, :edit, :update, :destroy]
  3. (略)
  4. private
  5. # Use callbacks to share common setup or constraints between actions.
  6. def set_book
  7. @book = Book.find(params[:id])
  8. end

 このように「before_action」の宣言にフィルターの処理を行うメソッド名を渡して使用できます。またメソッド名ではなくフィルター処理のブロックや、フィルターオブジェクトを渡すこともできます。

 フィルターオブジェクトは「before_action」に渡す場合であれば「before」メソッドか「filter」メソッド、「after_action」に渡す場合であれば「after」メソッドか「filter」メソッドにフィルターの処理を実装しておく必要があります。

 「around_filter」に渡す場合は「filter」メソッドまたは「around」メソッドにアクションの処理を埋め込む「yield」を含めて実装します。

  1. class TransactionWrap
  2. def filter(controller, &action)
  3. ActiveRecord::Base.transaction do
  4. yield
  5. raise ActiveRecord::Rollback if @book.errors.present?
  6. end
  7. end
  8. end
  9. class BooksController < ApplicationController
  10. around_action TransactionWrap.new, only: [:create, :update]
  11. (以下略)

 また、フィルターの宣言時に「only」オプションでフィルターを実行するアクションを指定でき、「except」オプションで全てのアクションからフィルターを実行しないアクションを指定することもできます。

Copyright © ITmedia, Inc. All Rights Reserved.

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

Coding Edge 鬮ォ�ェ陋滂ソス�ス�コ闕オ譁溷クキ�ケ譎「�ス�ウ驛「�ァ�ス�ュ驛「譎「�ス�ウ驛「�ァ�ス�ー

髫エ蟷「�ス�ャ髫エ魃会スス�・髫エ蟶キ�」�ッ闖ォ�」

注目のテーマ

4AI by @IT - AIを作り、動かし、守り、生かす
Microsoft & Windows最前線2025
AI for エンジニアリング
ローコード/ノーコード セントラル by @IT - ITエンジニアがビジネスの中心で活躍する組織へ
Cloud Native Central by @IT - スケーラブルな能力を組織に
システム開発ノウハウ 【発注ナビ】PR
あなたにおすすめの記事PR

RSSについて

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

メールマガジン登録

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