ruby-on-rails – rails中的PUT请求不会更新respond_with呼叫的
|
给定以下控制器:
class AccountsController < ApplicationController
respond_to :json,:xml
def update
@account = Account.where(uuid: params[:id]).first
unless @account.nil?
if @account.update_attributes params[:account]
respond_with @account,location: account_url(@account)
else
respond_with error_hash,status: :unprocessable_entity,root: :error,location: api_account_url(@account)
end
else
respond_with error_hash,status: :not_found,location: accounts_url
end
end
def error_hash
{ :example => "Example for this question",:parameter => 42 }
end
end
我会期望一个PUT请求/ accounts / update /来执行以下操作 >如果id存在,并且update_attributes调用成功,则提供204(无内容)成功消息. (我有它返回@account,这将是不错的,但没有什么大不了的204在这里很好) 实际发生的是: 提供一个没有身体的204. 为什么它忽略了我的身份和身体?我已经有一个类似的设置GET请求,工作很好(正确的状态,正确的身体). 示例CURL请求(对于不存在的ID): PUT请求
curl -i --header "Accept: application/xml" --header "Content-type: application/json" -X PUT -d '{"name": "whoop"}' http://localhost:3000/api/accounts/3d2cc5d0653911e2aaadc82a14fffee9
HTTP/1.1 204 No Content
Location: http://localhost:3000/api/accounts
X-Ua-Compatible: IE=Edge
Cache-Control: no-cache
X-Request-Id: bf0a02f452fbace65576aab6d2bd7c1e
X-Runtime: 0.029193
Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-01-15)
Date: Thu,24 Jan 2013 08:01:31 GMT
Connection: close
Set-Cookie: _bankshare_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRkkiJWFmNmI2MmU0MzViMmE3N2YzMDIzOTdjMDJmZDhiMzEwBjsAVA%3D%3D--133e394eb760a7fce07f1fd51349dc46c2d51626; path=/; HttpOnly
GET请求
curl -i --header "Accept: application/json" --header "Content-type: application/json" -X GET http://localhost:3000/api/accounts/3d2cc5d0653911e2aaadc82a14fffee9
HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8
X-Ua-Compatible: IE=Edge
Cache-Control: no-cache
X-Request-Id: 9cc0d1cdfb27bb86a206cbc38cd75473
X-Runtime: 0.005118
Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-01-15)
Date: Thu,24 Jan 2013 08:19:45 GMT
Content-Length: 116
Connection: Keep-Alive
{"friendly-status":"not-found","status":404,"message":"No account with id '3d2cc5d0653911e2aaadc82a14fffee9' found"}
解决方法
根据
this讨论,这种相当非直观的行为是由于希望保持与脚手架的兼容性.
您有两个选择来覆盖默认行为. A)将一个块传递给respond_with unless @account.nil?
if @account.update_attributes params[:account]
respond_with @account do |format|
format.json { render json: @account.to_json,status: :ok }
format.xml { render xml: @account.to_xml,status: :ok }
end
else
respond_with error_hash do |format|
format.json { render json: error_hash.to_json(root: :error),status: :unprocessable_entity }
format.xml { render xml: error_hash.to_xml(root: :error),status: :unprocessable_entity }
end
end
else
respond_with error_hash do |format|
format.json { render json: error_hash.to_json(root: :error),status: :not_found }
format.xml { render xml: error_hash.to_xml(root: :error),status: :not_found }
end
end
不幸的是,我们必须重新出现每种格式的重复,但这似乎是迄今为止Rails 4.0的当前建议;见here. 如果您返回更新的对象,或者不返回任何东西并让您的客户端代码“GET”更新的对象,则应返回200 – OK,而不是204 – 否. :位置在api上下文中无意义,它用于重定向html响应. B)创建一个自定义响应者 respond_with @account,status: :ok,responder: MyResponder 我自己也没有这样做,所以我不能举个例子,但是这似乎也是过分的. 查看Railscasts Episode:224有关response_with的一些讨论,包括自定义响应者. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
