Skip_before_filter игнорирует условные обозначения
Я пытаюсь использовать skip_before_filter только в том случае, если приложение находится в рабочем режиме. (Я не хочу, чтобы мои экземпляры разработки были общедоступны, и я хочу, чтобы приложение автоматически определяло, какой тип экземпляра он включен, и отображает экран входа в систему, когда он не находится в рабочем режиме). Итак, мой контроллер приложений имеет следующую строку:
before_filter :authenticate_user!, :except => "sign_in" #redirects to log-in
И контроллер для отображения страниц имеет следующую строку:
skip_before_filter :authenticate_user!, :only => :show, :if => :in_production
#public pages are public, but only when in production.
И in_production просто:
def in_production
ENV['RAILS_ENV']=='production'
end
Я понимаю, что здесь могут быть другие возможности, но мне любопытно, почему skip_before_filter, похоже, игнорирует условное и всегда просто пропускает before_filter. Что-то мне не хватает?
Ответы
Ответ 1
Это ошибка Rails (или, по крайней мере, недокументированное странное поведение). Отслеживается здесь: https://github.com/rails/rails/issues/9703
В этом потоке вы можете найти (скрученное) решение.
Вместо
skip_before_filter :authenticate_user!, :only => :show, :if => :in_production
записи
skip_before_filter :authenticate_user!, :only => :show
before_filter :authenticate_user!, :only => :show, :unless => :in_production
Это сработало для меня.
Ответ 2
Я обнаружил, что решение, отправленное SmartLove в описанном сценарии, представляет собой своего рода дыру в безопасности или неожиданное поведение. Строка
before_filter :authenticate_user!, :only => :show, :unless => :in_production
из-за :only => :show
, переопределяет существующий before_filter, определенный в ApplicationController. Это означает, что все действия этого контроллера (например: edit,: create и т.д.), За исключением: show one, будут опущены authenticate_user! фильтр.
Возможным решением является удаление предложения: only и проверка действия, вызываемого внутри условного метода. Например:
before_filter :authenticate_user!, :unless => :skip_filter?
def skip_filter?
params[:action] == "show" && in_production
end
Ответ 3
Я не уверен, что skip_before_filter
принимает параметр :if
, поэтому я бы попробовал этот синтаксис
(skip_before_filter :authenticate_user!, :only => [:show]) if in_production
Если он по-прежнему не работает, попробуйте поместить его в контроллер приложения
if ENV['RAILS_ENV']=='production'
skip_before_filter :authenticate_user!, :only => :show
end