append_before_filter в рабочем режиме

#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 вместо прямого вызова методов в первую очередь!