rails中的DoubleRenderError

时间:2016-08-17 07:35:29

标签: ruby-on-rails ruby

我有一个ProjectsController,除newindex之外的所有操作都限制在admins。我在我的控制器中添加了一个before_filter,如

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管理员? for 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`。这显然意味着即使在重定向之后,执行也不会终止。

在Web控制台中,我尝试执行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为nil时,我得到undefined method错误。

我该如何解决这个问题?

注意:我不想在check_login!中重复authorize_admin!代码,因为它违反了DRY。

1 个答案:

答案 0 :(得分:1)

如果过滤器重定向,则后续过滤器和操作本身不会运行,但过滤器本身会继续。在您的情况下,在调用check_login!后,authorize_admin!过滤器将继续执行。

如果检查通过,您可以更改check_login!以返回true,如果没有当前用户,则返回false。然后authorize_admin可以做

check_login! || return

或者,performed?方法告诉您是否发生了渲染或重定向,以便您可以

check_login!
return if performed?