Есть ли способ в Rails пропустить файл before_filter, если запрос xhr?
Со следующим кодом:
class TestsController < ApplicationController
skip_before_filter :load_something, # how to skip these only
:load_something_else # if the request is xhr ?
def index
respond_to do |format|
format.html
format.js
end
end
end
Есть ли способ пропустить перед фильтрами, если запрос является вызовом javascript без изменения методов :load_something
и :load_something_else
?
Спасибо!
Ответы
Ответ 1
Раньше не было чистого решения. Предполагая, что вы не имеете контроля над before_filters
(или не хотите их изменять), я бы оставил skip_before_filter
и добавил дополнительный before_filter
, который выполняет только нужные методы, если это метод xhr
.
Так что-то вроде
skip_before_filter :load_something, # how to skip these only
:load_something_else # if the request is xhr ?
before_filter :do_loads_if_xhr
def do_loads_if_xhr
if request.xhr?
load_something
load_something_else
end
end
Метод, описанный здесь, работает только потому, что условие является глобальным для приложения: условное значение оценивается только при создании класса. Не по каждому запросу.
[ОБНОВЛЕНО]
Однако существует более чистый способ сделать условие skip_before_filter
условным. Напишите это следующим образом:
skip_before_filter :load_something, :load_something_else, :if => proc {|c| request.xhr?}
Также обратите внимание, что пока skip_before_filter
по-прежнему полностью поддерживается и не устаревает, поскольку рельсы 4, похоже, предпочитают (идентичные) документы skip_before_action
. Кроме того, документация не совсем понятна, пришлось проверить код.
Ответ 2
Попробуйте эту строку, чтобы пропустить фильтрацию по условию:
skip_before_filter :load_something, :load_something_else,
:if => proc { request.xhr? }
Для ruby-2.0 вы также можете использовать lambdas (которые имеют строгость в передаче аргументов):
skip_before_filter :load_something, :load_something_else,
if: -> { request.xhr? }
или с аргументом:
skip_before_filter :load_something, :load_something_else,
if: ->(arg) { request.xhr? && arg }
Ответ 3
Все эти ответы, по моему мнению, используют неправильный подход. Использование skip_before_action с условием делает это в обратном порядке и не столь явным и ясным, как добавление условия к самому before_action; поэтому это мое предложение:
before_action :require_password_change, unless: -> { request.xhr? }
Таким образом, кому-то, читающему ваш код, он сразу же выясняет, при каких условиях это before_action запускается или не запускается, не полагаясь на то, что они происходят через это skip_before_action где-то в иерархии контроллера.
Ответ 4
Используйте alias_method_chain
, чтобы украсить фильтры, чтобы они не выполнялись, если запрос xhr.
def load_something_with_noxhr(*args)
load_something_without_noxhr(*args) unless request.xhr?
end
alias_method_chain :load_something, :noxhr
(измените load_something
на все, что необходимо, _with_
и _without_
являются буквальными, а суффикс noxhr
должен быть тем же самым, что вы передаете в качестве второго аргумента в вызове alias_method_chain
.)
Ответ 5
Вы закодировали эти фильтры? В этом случае вы можете написать предложение if
внутри них, не используя skip_before_filter
:
def load_something
unless request.xhr?
#Code
end
end
С другой стороны, вы можете сделать свой собственный фильтр и делегировать:
before_filter :my_own_filter
def my_own_filter
unless request.xhr?
load_something
load_something_else
end
end
Я думаю, что это должно сработать.