5. Controller に関する変更点
2013/10/03 シナジーマーケティング(株) 鈴木 圭
[Rails 4.0] 第5章 Controller に関する変更点
- 5.1. フィルタメソッドの名称変更
- 5.2. 独自の Flash メッセージタイプ
- 5.3. セッション Cookie の内容がデフォルトで暗号化される
- 5.4. protect_from_forger でエラー時の挙動が指定可能
- 5.5. コントローラレベルの ETag
- 5.6. HTTP の PATCH メソッド
- 5.7. ルーティングの変更
- 5.7.1. concern による重複の排除
- 5.7.2. match の via オプションが必須
- 5.7.3. 非 ASCII 文字のルーティング
- 5.7.4. constraints に文字列や正規表現以外が指定可能
- 5.8. まとめ
5.1. フィルタメソッドの名称変更
Rails4.0 では before_filter などのフィルタメソッドの名称が xxx_filter から xxx_action に変更になりました。
- before_filter → before_action
- after_filter → after_action
- around_filter → around_action
現状では古い xxx_filter も使用することができ、特に警告なども出力されません。
5.2. 独自の Flash メッセージタイプ
Rails4.0 では独自の Flash メッセージタイプを追加することができるようになりました。
独自の Flash メッセージタイプは add_flash_types メソッドで追加することができます。
class ApplicationController add_flash_types :special_notice, :hyper_notice, :ultra_notice end
追加した独自の Flash タイプは、notice などのデフォルトのタイプと同様に扱うことができます。
redirect_to root_path, special_notice: '特別なお知らせ!'
5.3. セッション Cookie の内容がデフォルトで暗号化される
Rails4.0 ではセッション Cookie の内容がデフォルトで暗号化されるようになりました。具体的には config.secret_key_base が設定されている場合に、自動的に Cookie の内容が暗号化されます(プロジェクト生成時に config.secret_key_base は設定されています)。
Rails3 では BASE64 でエンコードされているだけだったため、比較的簡単に内容を確認することができました(Cookie には署名が含まれているので改ざんの検出は行われていました)。
5.4. protect_from_forger でエラー時の挙動が指定可能
protect_from_forgery でトークンエラー時の挙動を指定できるようになりました。
# InvalidAuthenticityToken を raise する. protect_from_forgery with: :exception # reset_session する. protect_from_forgery with: :reset_session # 空のセッションオブジェクトにすり替える protect_from_forgery with: :null_session
ちなみに Rails2 では InvalidAuthenticityToken が raise され、Rails3 では reset_session さるという具合に、バージョンがあがるたびにデフォルトの挙動が変更されています。
5.5. コントローラレベルの ETag
ETag の値生成に使用するデータをコントローラレベルで指定することができるメソッド etag が追加されました。
ETag とは HTTP のレスポンスヘッダの一つであり、コンテンツの更新確認に使用されるものです。クライアントはサーバから渡された ETag の値とコンテンツをキャッシュし、次に同じページにアクセスするときには ETag の値を If-None-Match ヘッダに指定してサーバにリクエストを送信します。サーバは If-None-Match ヘッダで指定された値をチェックすることで、クライアントが持つキャッシュが現在も有効であるか判断することができます。キャッシュが無効であればコンテンツを返しますが、キャッシュが有効であればステータスコード 304 Not Modified を返します。こうすることで通信量を抑えることが可能になります。
etag メソッドは次のように使用します。
class MessagesController < ApplicationController etag { current_user.try(:id) } def show @message = Message.find(params[:id]) fresh_when(@message) end end
etag はブロックの評価結果を ETag の値を算出する元データに追加します。ログインユーザごとに ETag の値を変更したい場合に有効でしょう。
5.6. HTTP の PATCH メソッド
Rails4.0 では HTTP の PATCH メソッドが使用されるようになりました。
今までリソースの更新には PUT メソッドが使用されていましたが、PATCH メソッドが使われるように変更されました。PUT と PATCH の違いを以下にまとめます。
- PUT – 送信した内容でリソースを置き換える。
- PATCH – リソースの一部を送信された内容で置き換える。
例としてユーザのプロフィールを編集する画面をイメージしていただきたいのですが、プロフィール編集画面ではユーザ情報の全てを書き換えるわけではなく、名前やメールアドレスなどの一部の情報だけを更新することがほとんどのはずです。つまり、更新処理では PUT ではなく PATCH を用いるほうがほとんどの場合に適切です。
そのため、Rails4.0 では更新処理には PATCH メソッドを使用するように変更されました。この変更に伴い、ルーティングに patch メソッドが追加されました。コントローラでは判定用の request.patch? メソッドが追加されました。
一点補足ですが、Rails では PUT や PATCH などのメソッドに対応していないブラウザに対応するために、オーバーロード POST という方法でそれらの HTTP メソッドを表現しています。
オーバーロード POST とは、PUT や PATCH を使いたい場合でも POST で送信し、リクエスト内に本来使いたかった PUT や PATCH などの情報を含めるやり方を言います。Rails では「_method」というパラメータで本来使いたかった HTTP メソッドを送信しています。
まとめると、
- Rails4.0 では更新処理に PUT ではなく PATCH を使うように変更された。
- ただし Rails はオーバーロード POST を使用しているため、実際の違いは POST 時のパラメータ「_method」の値が「put」から「patch」に変わった。
となります。
5.7. ルーティングの変更
5.7.1. concern による重複の排除
concern というメソッドが追加され、ルーティングを DRY (Don’t Repeat Yourself) に書くことができるようになりました。
以下のコードを見てください。
resources :users do post :confirm end resources :articles do post :confirm end
「post :confirm」という行が重複しています。
concern を使えば次のように書き換えることができます。
concern :confirmable do post :confirm end resources :users, concern: :confirmable resources :articles, concern: :confirmable
5.7.2. match の via オプションが必須
Rails4.0 では match の via オプションが必須になり、受け付ける HTTP メソッドの指定が必須になりました。
# GET のみ許可する場合. match 'hello', to: 'index#hello', via: :get # GET と POST を許可する場合. match 'hello', to: 'index#hello', via: %i(get post) # 全てのメソッドを許可する場合. match 'hello', to: 'index#hello', via: :all
許可する HTTP メソッドが一つだけの場合は次のように get や post などを使用すると良いでしょう。
# GET を許可する場合. get 'hello', to: 'index#hello' # POST を許可する場合. post 'hello', to: 'index#hello'
5.7.3. 非 ASCII 文字のルーティング
Rails4.0 では非 ASCII 文字を含むルーティングを記述しやすくなりました。
Rails3 では明示的にエスケープする必要がありましたが、Rails4 ではエスケープは不要になりました。
# Rails3 get Rack::Utils.escape('こんにちは') => 'index#hello' # Rails4.0 get 'こんにちは' => 'index#hello'
5.7.4. constraints に文字列や正規表現以外が指定可能
# 配列を指定する. get '/foo/:action', to: 'foo', constraints: { subdomain: %w[www admin] } # 数値を指定する. get '/foo', to: 'foo#index', constraints: { port: 8080 }
5.8. まとめ
コントローラについては、メソッド名の変更から多くの改善が行われました。Etag や HTTP の PATCH メソッドは技術的なトピックとして頭の片隅に入れておくと良いでしょう。
次回は新機能の一つ、Turbolinks について解説します。