12

我有一个控制器,我在其中缓存显示操作。show 操作有许多用于安全的 before 过滤器,如果用户未登录,而不是当前组的成员等,这些过滤器将执行和重定向。当我没有打开缓存时,这些 before 过滤器可以正常工作,但是当我翻转开关以在不再执行过滤器之前打开缓存时(我的调试器调用未命中)。

我一直认为,在为缓存操作调用过滤器之前,这是页面缓存和操作缓存之间的主要区别。这得到了Rails 缓存教程中关于动作缓存的部分的支持,该部分内容如下:

Action Caching 的工作方式与 Page Caching 类似,不同之处在于传入的 Web 请求确实从 Web 服务器发送到 Rails 堆栈和 Action Pack,以便在提供缓存之前可以在其上运行之前的过滤器。这允许运行身份验证和其他限制,同时仍提供缓存副本的输出结果。

那么为什么我之前的过滤器没有被调用呢?

关于我的设置:Rails 3.1 using Devise for authentication。我正在将 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

那么,有没有人见过这种行为?我对过滤器和动作缓存应该如何工作之前的理解是否存在漏洞?或者也许我有一些奇怪的巫毒发生在一个奇怪的 gem 版本组合中?

[编辑]

有趣的是,我刚刚了解到,返回值对是否运行更远的方法没有影响,而是调用重定向或渲染。

[编辑 2]

我将我的应用程序升级到 rails 3.2.3 以查看它是否有效果,但没有解决问题。我发现,ApplicationController 中定义的过滤器被调用,但 GroupsController 中的过滤器没有。

4

1 回答 1

27

好吧,这是学习有关缓存的新花絮的一种非常耗时的方法。

事实证明,您需要在要运行的 before_filters之后调用 caches_action。我已将缓存操作作为课堂上的第一件事。这意味着所有之前的过滤器都没有运行,因为它们出现在 caches_action 的下方/之后,并且 caches_action 会停止代码的运行(并提供缓存的结果)。

感谢Pan Thomakos回答,其中包含这些信息的瑰宝——这不是在 ruby​​ 文档中,或者我已经略过它。一旦我设法收回由于这个小盲点而损失的时间,我将努力将这些信息添加到文档中。

于 2012-05-21T06:27:57.603 回答