この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
M.T. です。だいぶ開いてしまいましたが、
rails の action_cache について、続きを書きます。
前回のエントリはこちら。
action_cache の仕組み
前回のエントリでは rails 組み込みのキャッシュ機能についてざっと書きました。
今回は、その中から action_cache に的を絞って書いてみます。
実際に、コードを例にして見てみましょう。
# コードはこんな感じ
SampleController < ApplicationController
caches_action :index
def index
@sample = Sample.find(:all)
end
end
サンプルモデルから全件を取得して表示するだけのコントローラです。
action_cache の宣言は、cache_action :メソッド名で、指定されたメソッドが対象となります。
引数にメソッド名を指定しない場合、クラス内の全 public メソッドが対象となります。
おさらいすると、action_cache は around_filter として実装されているため、
上記のコードは、以下のような挙動になります。
キャッシュがなかった場合
- キャッシュの存在チェック
- index アクションを実行
- キャッシュの生成
キャッシュがあった場合
- キャッシュの存在チェック
- キャッシュを表示
注目したいのは、キャッシュがあった場合の処理です。
action_cache では、キャッシュがあった場合、キャッシュを生成するためのafter フィルタを実行しません。
もっと言うと、action_cache の before フィルタより順番が後になっている、
そのとき設定されているすべてのフィルタの実行を行いません。
以下のようなコードがあるとします。
# コードはこんな感じ
# jpmobile はインストール済みで使えるようになっていると仮定
SampleController < ApplicationController
caches_action :index
before_filter :mobile_required
def index
@sample = Sample.find(:all)
end
private
def mobile_required
unless request.mobile?
raise "pc access"
end
end
end
携帯からのアクセスでなかった場合、例外が発生するコード…のように見えますが、 実際には以下のような挙動になります。
キャッシュがなかった場合、携帯からアクセス
- キャッシュの存在チェック
- index アクションを実行
- キャッシュの生成
キャッシュがあった場合、PCからアクセス
- キャッシュの存在チェック
- キャッシュを表示
上記のように、先に携帯でキャッシュができていた場合、action_cache の before より 後に設定されている before_filter で呼ばれる mobile_required メソッドは実行されません。
before_filter :mobile_required
caches_action :index
上記のように、順番が逆になっていれば、先に mobile_required メソッドが実行され、
キャッシュがあろうとなかろうと、PC ではアクセスができなくなります。
jpmobile を利用して携帯に対応している場合かつ action_cache を使う場合、
jpmobile も around_filter で様々な処理を行っているため、このあたりの順番が
重要になってきます。
実際に組み合わせて使う方法は、また次回ということで…
だらだらと長いエントリーですが、よかったらお付き合いくださいー。