Rails 4 AbstractController::Metal 渲染状态!= 200(即 401、404)

Posted

技术标签:

【中文标题】Rails 4 AbstractController::Metal 渲染状态!= 200(即 401、404)【英文标题】:Rails 4 AbstractController::Metal rendering with status != 200 (i.e. 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 好的,很高兴知道。很遗憾它必须到那个地步。 【参考方案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

【讨论】:

以上是关于Rails 4 AbstractController::Metal 渲染状态!= 200(即 401、404)的主要内容,如果未能解决你的问题,请参考以下文章

Rails 4 和 ActionCable

在使用 Rails 3 时遇到一些问题,继续使用 Rails 4

如何在带有 Rails 4.2 的专用调试端口上使用工头启动 Rails?

设计注销链接问题(Rails 4)

Rails:为啥捆绑安装被 sassc 2.4.0 冻结

任何人都可以帮我处理这段代码吗?我需要将其转换为 rails 4 但我不知道如何..(从 rails 2 到 rails 4 的 routes.rb 文件)