その他
    ホーム 技術発信 DoRuby rails の action_cache (アクションキャッシュ)を使う、その二。

    rails の action_cache (アクションキャッシュ)を使う、その二。

    この記事はアピリッツの技術ブログ「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 として実装されているため、
    上記のコードは、以下のような挙動になります。

    キャッシュがなかった場合

    1. キャッシュの存在チェック
    2. index アクションを実行
    3. キャッシュの生成

    キャッシュがあった場合

    1. キャッシュの存在チェック
    2. キャッシュを表示

    注目したいのは、キャッシュがあった場合の処理です。
    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
    

    携帯からのアクセスでなかった場合、例外が発生するコード…のように見えますが、 実際には以下のような挙動になります。

    キャッシュがなかった場合、携帯からアクセス

    1. キャッシュの存在チェック
    2. index アクションを実行
    3. キャッシュの生成

    キャッシュがあった場合、PCからアクセス

    1. キャッシュの存在チェック
    2. キャッシュを表示

    上記のように、先に携帯でキャッシュができていた場合、action_cache の before より 後に設定されている before_filter で呼ばれる mobile_required メソッドは実行されません。

    before_filter :mobile_required
    caches_action :index
    

    上記のように、順番が逆になっていれば、先に mobile_required メソッドが実行され、
    キャッシュがあろうとなかろうと、PC ではアクセスができなくなります。

    jpmobile を利用して携帯に対応している場合かつ action_cache を使う場合、
    jpmobile も around_filter で様々な処理を行っているため、このあたりの順番が
    重要になってきます。

    実際に組み合わせて使う方法は、また次回ということで…
    だらだらと長いエントリーですが、よかったらお付き合いくださいー。