【问题标题】:rails convention for http raising errors in controllers?控制器中http引发错误的rails约定?
【发布时间】:2013-01-30 05:53:30
【问题描述】:

假设我有一个带有 show 方法的articles_controller

我想确保只有具有有效许可证代码的客户端才能读取此控制器操作的 json 端点

def show
  authenticate_license if params[:format] == 'json' 
  # boilerplate
  respond_to do |format|
    format.html
    format.json { render json: @article, status: :ok }
  end
end

我可能想在其他地方使用这个身份验证块,所以我把它放到我的 application_controller 中

# in application_controller
def authenticate_license
  @client = params[:client]
  licenses = License.where(:code => params[:code])
  @license = licenses.first
  if @license
    if @license.client = @client
      # do nothing, we're fine
    else
      respond_to do |format|
        format.json { render json: 'wrong client', status: 400 }
      end
    end
  else
    respond_to do |format|
      format.json { render json: 'bad license', status: :forbidden }
    end  
  end
end

但这会导致双重渲染错误,所以现在我将尝试不同的方法

# in application_controller
def authenticate_license
  licenses = License.where(:code => params[:code]
  @license = licenses.first
  if @license
    if @license.client = @client
      # do nothing, we're fine
    else
      raise ActionController::RoutingError.new('wrong client')
    end
  else
    raise ActionController::RoutingError.new('bad license code')
  end
end
rescue_from ActionController::RoutingError do |exception|
  respond_to do |format|
    format.html { redirect_to root_url, :alert => exception.message }
    format.json { render json: exception.message, status: :forbidden }
  end
end

但是这样,我无法指定 HTTP 状态,而且我还捕获了我可能不想捕获的路由错误。

做我想做的事的正确方法是什么?

我所描述的行为类似于设计的行为。如果您向具有 authorize_user 的操作发出请求!例如,它会引发错误,并将用户重定向到某个页面。 CanCan 也做了类似的事情,如果用户没有被授权做某事,它会引发你应该捕获的自己的异常。

【问题讨论】:

    标签: ruby-on-rails http model-view-controller exception-handling


    【解决方案1】:

    错误是有效的,你渲染了不止一次,这就是doublerender异常的原因。最好只在控制器中进行渲染

    试试这个代码

    def show
      is_client_valid = authenticate_license if params[:format] == 'json' 
      # boilerplate
      respond_to do |format|
        format.html
        if is_client_valid == 'valid' #you can have a switch statement here, so that you can easily set the status tag
          format.json { render json: @article, status: :ok }
        else
           format.json { render json: is_client_valid }
        end
      end
    end
    
    
    # in application_controller
    def authenticate_license
      @client = params[:client]
      licenses = License.where(:code => params[:code])
      @license = licenses.first
      if @license
        if @license.client = @client
          return 'valid'
        else
            return 'wrong client' 
        end
      else
          return 'bad licence'
      end
    end
    

    【讨论】:

    • 'is client_valid'... 'is' 是错字吗?还是 ruby​​/rails 有一个 'is' 关键字...?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-30
    • 1970-01-01
    • 1970-01-01
    • 2011-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多