【问题标题】:Rails 4 AbstractController::Metal rendering with status != 200 (i.e. 401, 404)Rails 4 AbstractController::Metal 渲染状态!= 200(即 401、404)
【发布时间】:2014-10-21 06:59:17
【问题描述】:

我正在我的应用程序中实现一个简单的 API 来与 Android 应用程序通信。我正在尝试使用 AbstractController::Metal 主要是为了提高性能。我遇到的问题是渲染忽略了我正在传递的状态选项。

非常简单的例子:

class Api::V1::ApiController < ActionController::Metal
  include AbstractController::Rendering
  include ActionController::Renderers::All
  include ActionController::RackDelegation
  include ActionController::MimeResponds
end

class Api::V1::SessionsController < Api::V1::ApiController
  def show
    render status: :unauthorized   # using 401 yields the same result
  end
end

打电话

curl -v -X GET http://app.dev:3000/api/v1/sessions.json

我希望收到 401,但我得到了 200 OK:

> GET /api/v1/sessions.json HTTP/1.1
> User-Agent: curl/7.30.0
> Host: app.dev:3000
> Accept: */*
> 
< HTTP/1.1 200 OK

有什么想法吗?覆盖 response.status 是迄今为止我发现的唯一解决方法,但老实说,它看起来像一个丑陋的 hack。

提前感谢您的见解。

【问题讨论】:

  • 您确定/api/v1/sessions.json 会执行您的操作show 操作吗?而且看起来应该是render nothing: true, status: 401而不是render status: :unauthorized
  • @IS04 是的,它会显示,因为在我的路线中我有资源:会话(而不是资源s)。我也尝试过什么都不渲染并得到相同的结果(关于状态,响应的正文是空的)。
  • 我在 ActionController::Metal 上遇到了同样的问题——您对此有何发现?
  • @Michael 不,我正在覆盖 response.status :(
  • @FelipeKoch 好的,很高兴知道。很遗憾它必须到那个地步。

标签: ruby-on-rails ruby render rack


【解决方案1】:

使用head ActionController::Head

class Api::V1::SessionsController < Api::V1::ApiController
  def show
    head :unauthorized
  end
end

【讨论】:

    【解决方案2】:

    我在下面显示的示例代码中遇到了同样的问题。这在 Rails 3 中与 ActionController::Metal 一起使用,并在升级到 Rails 4.2.4 后开始失败:

    # config/routes.rb
    get :unauthorized, to: 'unauthorized#respond'     
    
    # app/controllers/unauthorized_controller.rb
    class UnauthorizedController < ActionController::Metal
      def respond
        head :forbidden
      end
    end
    
    # spec/controllers/unauthorized_controller_spec.rb
    describe UnauthorizedController do
      it 'should respond with 403 forbidden' do
        get :respond, {}, {}
    
        expect(response.status).to be == 403
      end
    end
    

    升级后测试失败。所以为了解决这个问题我不得不改变

    class UnauthorizedController &lt; ActionController::Metal

    class UnauthorizedController &lt; ActionController::Base

    【讨论】:

      【解决方案3】:

      不渲染并返回代码401 使用:

      render nothing: true, status: :unauthorized
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-20
        • 1970-01-01
        • 2016-01-28
        • 2017-04-22
        相关资源
        最近更新 更多