3
def login_required
        unless current_user
            store_location
            flash[:notice] = I18n.t('must_be_logged_in')
            redirect_to new_user_session_path
            return false
        end
    end

我在 Rails 应用程序中有这种方法。我的问题是该线路何时return false运行?

它前面的行说redirect_to new_user_session_path.

def admin_required
        return false if login_required == false
        unless current_user.admin?
            store_location
            flash[:notice] = t('must_be_admin')
            redirect_to new_user_session_url
            return false
        end
    end

为了澄清这个方法需要login_required == false(或真)..第一个方法将如何返回假?

4

2 回答 2

7

困扰您的是 a#redirect_to不是 return 语句:它将响应标记为必须重定向到其他地方,但它不会停止执行流程。

redirect_to root_path # executed
puts "foo"            # executed
return                # executed
puts "bar"            # not executed

当您考虑#redirect_to实施时,其原因实际上是显而易见的。redirect_to是由 rails 实现的方法,而不是核心语言关键字,如return.

现在,想象一下你必须#redirect_to自己实现。你会做这样的事情:

def redirect_to( url )
  response.redirect = url
end

现在,您在操作中调用该方法:

def index
  redirect_to root_path
  puts "foo"
end

显然,在这里,您的第二条指令#index也将被调用,因为您的#redirect_to方法没有意思[1] 通知其调用者它应该停止执行。

请注意,这也适用于#render:它们是简单的方法,而不是指令流控制关键字。

[1] 实际上,我们可以想到一种中断执行流程的方法:抛出由处理重定向的类在某处捕获的异常,但这通常被认为是在没有实际错误时使用异常来控制流程的糟糕设计。

于 2013-09-15T10:54:50.110 回答
1

返回 false 只会停止该操作的代码执行。您还会看到这样的行

return redirect_to :action => :index

或者

redirect_to :action => :index and return

它们都是同一个意思。

于 2013-09-15T10:42:09.053 回答