#ruby-on-rails #production-environment #before-filter
#ruby-on-rails #производственная среда #предварительный фильтр
Вопрос:
У меня есть контроллер, который запускается в двух разных «контекстах» в зависимости от вошедшего в систему пользователя (в принципе, пользователь может выполнять операции CRUD в своей собственной учетной записи, а пользователь-администратор может выполнять CRUD во всех учетных записях пользователей; действия одинаковы в разных контекстах, но разрешения разные).
Чтобы облегчить это, я написал фильтр before, который проверяет контекст и добавляет правильное контекстно-зависимое разрешение before filter:
def ensure_logged_in
if user_context?
self.class.append_before_filter :authorize_user
else
self.class.append_before_filter :authorize_admin
end
end
Кроме того, ensure_logged_in
вызывается только для определенных действий:
before_filter :ensure_logged_in, :only => [:show, :edit, :update]
Это отлично работает в режиме разработки, но как только код запущен в производство, мы начали испытывать странное поведение (т. Е. пользователям предлагается войти в систему для действий, для которых вход в систему не требуется; в контроллере есть пара действий open view).
Я предполагаю, что, поскольку разработка перезагружает классы при каждом попадании на страницу, append_before_filter
вызов применяется только к этому попаданию на страницу, но поскольку производство кэширует классы, вызов append_before_filter
добавляет его для последующего использования контроллера. Является ли это допустимым предположением? Если да, то что я могу сделать вместо этого?
Ответ №1:
Я предполагаю, что, поскольку разработка перезагружает классы при каждом попадании на страницу, вызов append_before_filter применяется только к этому попаданию на страницу, но поскольку производство кэширует классы, вызов append_before_filter добавляет его для последующего использования контроллера. Является ли это допустимым предположением? Если да, то что я могу сделать вместо этого?
Ваше утверждение здесь абсолютно правильное. В рабочем режиме вы не можете изменять цепочку фильтров для подобных классов, потому что классы являются постоянными, поэтому, если вы измените цепочку фильтров, это теперь повлияет на каждый запрос, обрабатываемый этим классом контроллера с этого момента. Я бы просто использовал обычный метод before filter, который вызывает любой из других, основанных на user_context?
чем-то вроде этого:
before_filter :ensure_logged_in, :only => [:show, :edit, :update]
def ensure_logged_in
if user_context?
return authorize_user
else
return authorize_admin
end
end
Комментарии:
1. Нет необходимости в этих возвратах, но в остальном это звучит как хорошее решение.
2. Да, это то, что я в итоге сделал (без
return
ов). Я не совсем уверен, почему я решил использоватьappend_before_filter
вместо прямого вызова методов в первую очередь!