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 < ActionController::Metal
到
class UnauthorizedController < ActionController::Base
【讨论】:
【参考方案3】:不渲染并返回代码401
使用:
render nothing: true, status: :unauthorized
【讨论】:
以上是关于Rails 4 AbstractController::Metal 渲染状态!= 200(即 401、404)的主要内容,如果未能解决你的问题,请参考以下文章
在使用 Rails 3 时遇到一些问题,继续使用 Rails 4
如何在带有 Rails 4.2 的专用调试端口上使用工头启动 Rails?
任何人都可以帮我处理这段代码吗?我需要将其转换为 rails 4 但我不知道如何..(从 rails 2 到 rails 4 的 routes.rb 文件)