2016-08-17 2 views
0

У меня есть ProjectsController, для которого все действия, кроме new и index, ограничены admins. Я добавил before_filter в мой контроллер, какDoubleRenderError in rails

before_action :authorize_admin!, except: [:index, :show] 

и before_filter выглядит следующим образом.

def authorize_admin! 
    check_login! 

    unless current_user.admin? 
    redirect_to root_path, alert: "You're not authorized" 
    end 
end 

check_login! является метод ApplicationController, который перенаправляет на root_path является пользователь не вошел в систему.

def check_login! 
    flash[:alert] = 'You need to sign up or sign in before continuing' 
    redirect_to login_path unless current_user 
end 

current_user это метод, который возвращает запись пользователя, если сеанс для пользователя существует. (Его не имеет отношения к ошибке)

Проблема в том, когда я пытаюсь получить доступ к /projects/4/edit без входа в систему, я получаю сообщение undefined method admin? ' для nil: NilClass error. In the before filter, check_login! is executed first and if the user's not logged in, he should be redirected to the root_path`. Это явно означает, что даже после перенаправления выполнение не прерывается.

В веб-консоли я попытался выполнить check_login!, и на этот раз я получил ошибку AbstractController::DoubleRenderError: Render and/or redirect were called multiple times in this action.. И он намекнул мне использовать redirect_to(..) and return.

Хотя я знал, что это не будет работать, я попытался модифицировать мой check_login? метод

def check_login! 
    redirect_to login_path, alert: 
    'You need to sign up or sign in before continuing' and return unless current_user 
end 

И я также попытался следующие после глядя на SO нить.

return redirect_to login_path, alert: 
    'You need to sign up or sign in before continuing` unless current_user 

Я предполагаю, что она не потому что она возвращается к вызываемым, метод authorize_admin! и снова, как current_user равна нулю, я получаю ошибку undefined method.

Как я могу решить эту проблему?

Примечание: Я не хочу повторять код check_login! в authorize_admin!, поскольку он нарушает СУХИЕ.

ответ

1

Если фильтр перенаправляет последующие фильтры и само действие не запускается, но сам фильтр продолжается. В вашем случае, после вызова check_login!, фильтр authorize_admin! продолжает выполнение.

Вы можете изменить check_login!, чтобы вернуть true, если проверка прошла и false, если нет текущего пользователя. Тогда authorize_admin может сделать

check_login! || return 

В качестве альтернативы, метод performed? говорит вам, если рендер или перенаправлять произошло, так что вы могли бы сделать

check_login! 
return if performed? 
Смежные вопросы