Rails caches_action пропускает before_filters

У меня есть контроллер, в котором я кеширую действие шоу. Действие show имеет ряд фильтров предварительной защиты для обеспечения безопасности, которые предназначены для выполнения и перенаправления, если пользователь не вошел в систему, не является членом текущей группы и т. Д. Эти фильтры перед работой работают отлично, когда я не включил кэширование, но когда я переключаю переключатель, чтобы включить кэширование до того, как фильтры больше не выполняются (мои вызовы отладчика не удаляются).

Я всегда понимал, что до того, как фильтры будут вызываться для кэшированных действий, это основное различие между кэшированием страниц и кэшированием действий. Это подтверждается разделом Учебное руководство по кэшированию Rails, в котором говорится:

Кэширование действий работает так же, как и кэширование страниц, за исключением того факта, что входящий веб-запрос переходит с веб-сервера в стек Rails и Action Pack, так что до того, как фильтры могут быть запущены на нем, до обслуживания кеша. Это позволяет выполнять аутентификацию и другие ограничения, в то же время обслуживая результат вывода из кэшированной копии.

Так почему же мои фильтры не вызывались?

Немного о моей настройке: Rails 3.1 использует Devise для аутентификации. Я использую камень Далли для магазина 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

Так кто-нибудь видел такое поведение раньше? Есть ли у меня дыра в моем понимании того, как прежде должны работать фильтры и кэширование действий? Или, может быть, у меня происходит какое-то странное колдовство со странной комбинацией версий гемов?

[РЕДАКТИРОВАТЬ]

Интересно, что я только что узнал, что возвращаемое значение не влияет на то, выполняются ли методы дальше по цепочке или нет, а на то, вызывается ли перенаправление или рендер.

[править 2]

Я обновил свое приложение до rails 3.2.3, чтобы посмотреть, оказало ли оно влияние, но не устранило проблему. Кое-что, что я обнаружил, состоит в том, что перед вызовом фильтры, определенные в ApplicationController, вызываются, а в моем GroupsController - нет.

1 ответ

Решение

Что ж, это был очень трудоемкий способ узнать новый тезис о кешировании.

Оказывается, вам нужно сделать вызов caches_action ПОСЛЕ предфильтров, которые вы хотите запустить. Я поместил действие с кешами как одну из первых вещей в моем классе. Это означало, что все фильтры before не запускались так, как они появились ниже / после caches_action, а caches_action останавливает выполнение кода (и подает кешированный результат).

Спасибо Pan Thomakos за его ответ, который содержал этот драгоценный камень информации - которого либо нет в рубиновых документах, либо я пролистал его. Я постараюсь, чтобы эта информация была добавлена ​​в документы, как только мне удастся вернуть время, потерянное из-за этого маленького слепого пятна.

Другие вопросы по тегам