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的一些讨论,包括自定义响应者. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |