我有一个控制器,我正在缓存show动作。 show动作有许多安全过滤器,用于执行和重定向,如果用户没有登录,不是当前组的成员等。这些过滤器在我没有打开缓存时工作正常,但是当我打开开关以转动缓存之前,不再执行过滤器(我的调试器调用没有被命中)。
我一直认为,在为缓存操作调用过滤器之前,这是页面缓存和操作缓存之间的主要区别。这由Rails Caching Tutorial section on action caching支持,内容如下:
动作缓存的工作方式与页面缓存类似,不同之处在于传入的Web请求确实从Web服务器传递到Rails堆栈和Action Pack,以便在提供缓存之前可以在其上运行筛选器。这允许在仍然提供缓存副本的输出结果的同时运行身份验证和其他限制。
那么为什么我的前过滤器不会被调用?
关于我的设置:Rails 3.1使用Devise进行身份验证。我正在使用dalli gem作为memcached商店。
以下是一些代码,总结了我的代码(很多琐事):
class GroupsController < ApplicationController
caches_action :show
cache_sweeper :group_sweeper
before_filter :authenticate_user!, :except => [:index]
before_filter :init_group, :except => [:new, :create, :index]
before_filter :requires_group_membership, :except => [:new, :create, :index]
def show
end
private
def requires_group_membership
if current_user and !@group.users_active.index(current_user).nil?
return true
else
redirect_to :root
return false
end
end
def init_group
@group = current_user.active_groups.find_by_id(params[:id])
if @group.nil?
redirect_to :root
return false
end
end
那么,有没有人见过这种行为?在理解过滤器和动作缓存应该如何工作之前,我是否有一个漏洞?或者也许我有一些怪异的voodo发生了奇怪的宝石版组合?
[编辑]
有趣的是,我刚刚了解到返回值对是否运行链中的方法没有影响,而是调用重定向还是渲染。
[编辑2]
我将我的应用程序升级到rails 3.2.3以查看它是否有效,但没有解决问题。我发现的东西是在ApplicationController中定义的before过滤器被调用,但是我的GroupsController中的过滤器没有被调用。
答案 0 :(得分:27)
这是一个非常耗费时间的方法来学习关于缓存的新知识。
事实证明,您需要调用caches_action AFTER 要运行的before_filters。我把缓存操作放在了我班上的第一件事之一。这意味着所有之前的过滤器都没有运行,因为它们出现在caches_action下面/之后,并且caches_action停止了代码的运行(并提供了缓存的结果)。
感谢Pan Thomakos his answer包含了这个信息的宝石 - 它不在ruby文档中,或者我已经浏览过它。一旦我设法收回因这个小盲点而丢失的时间,我会努力将这些信息添加到文档中。