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 за его ответ, который содержал этот драгоценный камень информации - которого либо нет в рубиновых документах, либо я пролистал его. Я постараюсь, чтобы эта информация была добавлена в документы, как только мне удастся вернуть время, потерянное из-за этого маленького слепого пятна.