首页 > 解决方案 > before_action 中的 render/head 不会停止执行其余的操作

问题描述

我有一个私有方法 authenticate_user!在我的应用程序控制器中验证标头中的令牌并在找到时返回用户记录。这是它的样子。

def authenticate_user!
  # authenticate
  @current_login = Login.where(oauth2_token: bearer_token).first
  head 401 if @current_login.nil? # and return
  @current_user = @current_login.user
  head 401 if @current_user.nil? 
end

我使用此方法对控制器中的用户进行身份验证,如下所示。

class AddressesController < ApplicationController
   before_action :authenticate_user!

   def some_action
      data = @current_user.some_associated_records
      render json: {data: data}
   end
end

理想情况下,当未找到登录名或未找到相应用户时,我应该从 authenticate_user 获得 401 响应!方法。

相反,我总是收到 500 内部服务器错误。不知何故,head 401 if current_login.nil?它不会停止执行链。即使渲染状态:401 也无法完成这项工作。

根据我的理解,如果在 before_action 过滤器中找到一个render或一个命令,rails 就会返回。head我错过了什么?

编辑:

以下解决方案有效:

      private

      def authenticate_user!(*)
        @current_login = Login.where(oauth2_token: bearer_token).first!
        @current_user = @current_login.user
        rescue ActiveRecord::RecordNotFound
          head 401
      end

但是我仍然很困惑为什么原来的方法不起作用。

标签: ruby-on-railsruby-on-rails-4before-filter

解决方案


正如@Rahul提到的( before_action 中的 render/head 不会停止执行其余的操作)500 的错误发生在您尝试从中获取user此步骤@current_loginnil的步骤中。

head方法只调用render nothing: true提供的状态。并且render不会破坏任何执行链。

根据上面的注释,我建议像这样重写它:

def authenticate_user!
  @current_login = Login.find_by(oauth2_token: bearer_token)
  @current_user = @current_login&.user
  head 401 if @current_user.nil? 
end

推荐阅读