我有一个控制器,我正在其中缓存显示操作。show 操作具有许多用于安全性的 before 过滤器,如果用户未登录、不是当前组的成员等,则执行和重定向。当我没有打开缓存时,这些 before 过滤器可以正常工作,但是当我翻转开关以打开缓存时,过滤器不再执行(我的调试器调用没有命中(。
我一直认为,在为缓存操作调用过滤器之前,这是页面缓存和操作缓存之间的主要区别。这由关于操作缓存的 Rails 缓存教程部分支持,内容如下:
操作缓存的工作方式与页面缓存类似,除了传入的 Web 请求确实从 Web 服务器转到 Rails 堆栈和操作包,以便在提供缓存之前可以在其上运行过滤器。这允许在运行身份验证和其他限制的同时仍提供缓存副本的输出结果。
那么为什么我的之前过滤器没有被调用呢?
关于我的设置:使用Devise进行身份验证的Rails 3.1。我正在使用 dalli gem 进行内存缓存商店。
这里有一些代码总结了我的代码(剪掉了很多垃圾(:
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
那么,以前有人见过这种行为吗?我对过滤器和操作缓存应该如何工作的理解是否有漏洞?或者,也许我有一些奇怪的伏都发生在宝石版本的奇怪组合中?
[编辑]
有趣的是,我刚刚了解到返回值对是否沿链运行方法没有影响,而是调用重定向或渲染。
[编辑2]
我将我的应用程序升级到 rails 3.2.3 以查看它是否有效果,但没有解决问题。我发现的是,在应用程序控制器中定义的过滤器被调用,但在我的组控制器中的过滤器没有被调用。
这是一种非常耗时的方式来学习有关缓存的新花絮。
事实证明,您需要在要运行的before_filters之后调用caches_action。我已将缓存操作作为我类中的第一件事。这意味着所有 before 过滤器都不会像它们出现在caches_action下面/之后那样运行,并且caches_action停止代码的运行(并提供缓存的结果(。
感谢 Pan Thomakos 的回答,其中包含这些信息 - 它要么不在 ruby 文档中,要么我已经浏览了它。一旦我设法挽回由于这个小盲点而损失的时间,我将不遗余力地将此信息添加到文档中。