[英]Rails Action Caching for user specific records
我是Rails新手,正在尝试为我的应用程序实现缓存。 我安装了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,Rails击中了我的控制器并缓存了产品操作。
2)我以用户B的身份注销并登录,它仍然以用户A的身份登录并显示用户A而不是用户B的产品。它甚至没有击中我的控制器。
密钥可能是路由,在我的内存缓存控制台中,我看到它是基于相同的密钥来获取的。
20 get views/localhost:3000/products
20 sending key views/localhost:3000/products
动作缓存不是我应该使用的吗? 我将如何缓存和显示特定于用户的产品?
谢谢你的帮助。
第一个问题是您的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
这应该可以帮助您为每个用户使用单独的缓存。
基于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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.