6

私は自分のアプリにキャッシュを実装しようとしているレール初心者です。memcached をインストールし、development.rb で次のように構成しました。

config.action_controller.perform_caching             = true
config.cache_store = :mem_cache_store

ログイン時にユーザー固有の製品を表示するコントローラー ProductsController があります。

class ProductsController < ApplicationController
  caches_action :index, :layout => false
  before_filter :require_user

  def index
    @user.products              
  end
end

The route for index action is: /products

問題は、私がとしてログインするときです

1) ユーザー A が初めて、レールがコントローラーにヒットし、製品アクションをキャッシュします。

2) ログアウトしてユーザー B としてログインすると、引き続きユーザー A としてログインし、ユーザー B ではなくユーザー A の製品が表示されます。コントローラーにもヒットしません。

キーはおそらくルートです。memcached コンソールでは、同じキーに基づいて取得していることがわかります。

20 get views/localhost:3000/products
20 sending key views/localhost:3000/products

アクションキャッシングは私が使用すべきものではありませんか? ユーザー固有の製品をキャッシュして表示するにはどうすればよいですか?

ご協力いただきありがとうございます。

4

2 に答える 2

15

最初の問題は、require_user の before_filter がアクション キャッシュの後であるため、実行されないことです。これを修正するには、次のコントローラー コードを使用します。

class ProductsController < ApplicationController
  before_filter :require_user
  caches_action :index, :layout => false

  def index
    @products = @user.products              
  end
end

次に、アクション キャッシングでは、ページ キャッシングとまったく同じことを行いますが、フィルターが実行された後なので、@user.products コードは実行されません。これを修正するには、いくつかの方法があります。

まず、必要に応じて、ページに渡されるパラメーターに基づいてアクションをキャッシュできます。たとえば、user_id パラメータを渡すと、次のようにそのパラメータに基づいてキャッシュできます。

caches_action :index, :layout => false, :cache_path => Proc.new { |c| c.params[:user_id] }

次に、ページ全体ではなくクエリのみをキャッシュする場合は、次のようにアクション キャッシュを完全に削除し、クエリのみをキャッシュする必要があります。

def index
  @products = Rails.cache.fetch("products/#{@user.id}"){ @user.products }
end

これは、ユーザーごとに個別のキャッシュを用意するのに役立ちます。

于 2011-02-23T22:07:05.237 に答える
0

Pan Thomakosの回答に基づいて、認証を処理するコントローラーから継承している場合は、親クラスからbefore_filterをコピーする必要があります。例えば:

class ApplicationController < ActionController::Base
  before_filter :authenticate
end

class ProductsController < ApplicationController
  # must be here despite inheriting from ApplicationController
  before_filter :authenticate
  caches_action :index, :layout => false
end
于 2011-04-11T01:19:08.220 に答える