Rails操作缓存用户特定记录

我是一个铁杆新手试图为我的应用程序实现缓存。 我安装了memcached并在我的development.rb中配置它,如下所示:

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

我有一个控制器ProductsController,它在登录时显示用户特定的产品。

 class ProductsController  false before_filter :require_user def index @user.products end end The route for index action is: /products 

问题是,当我登录时

1)用户A第一次,rails命中我的控制器并缓存产品动作。

2)我注销并以用户B身份登录,它仍然以用户A身份登录并显示用户A而非用户B的产品。它甚至没有打到我的控制器。

关键可能是路由,在我的memcached控制台中,我看到它是基于相同的密钥获取的。

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

动作缓存不是我应该使用的吗? 我如何缓存和显示用户特定的产品?

谢谢你的帮助。

第一个问题是,您的before_filter for require_user是在操作缓存之后,因此不会运行。 要解决此问题,请使用此控制器代码:

 class ProductsController < ApplicationController before_filter :require_user caches_action :index, :layout => false def index @products = @user.products end end 

其次,对于动作缓存,您执行与页面缓存完全相同的操作,但在运行filter后,您的@ 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 

这可以帮助您开始为每个用户提供单独的缓存。

基于Pan Thomakos的回答,如果您从处理身份validation的控制器inheritance,则需要从父类复制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 
Interesting Posts