在rails中简单的respond_with避免了PUT的204

我想要PUT轨道,并避免获得204 。 我正在使用这种模式:

 class SomeController < ApplicationController respond_to :json def update # ... respond_with(some_object) end end 

然而,当我做了更新,我得到了204回来。 我意识到这是完全有效的,但我明确希望内容回来。 我可以在某种程度上覆盖它:

 def update respond_with(some_object) do |format| format.json{render json: some_object} end end 

但是这对于rails来说似乎有点过分了。 有没有更多的惯用的方法来避免204并要求全部内容被送回? 这是Rails 3.2。

总之:我想最大限度地惯用导轨,避免了204

我做了一个自定义响应者,它总是返回我的JSON编码资源,即使在PUT / POST上。

我把这个文件放在lib/responders/json_responder.rb 。 你的/lib目录应该是自动加载的。

 module Responders::JsonResponder protected # simply render the resource even on POST instead of redirecting for ajax def api_behavior(error) if post? display resource, :status => :created # render resource instead of 204 no content elsif put? display resource, :status => :ok else super end end end 

现在,明确地修改需要这种行为的控制器,或将其放置在应用程序控制器中。

 class ApplicationController < ActionController::Base protect_from_forgery responders :json end 

你现在应该得到JSON编码的资源回PUT。

这种行为似乎有意符合HTTP规范,并且“理想情况下”您应该引发额外的GET请求来查看结果。 不过,我同意在现实世界中,我宁愿让它返回JSON。

上面的@jpfuentes2的解决scheme应该可以做到这一点(这与下面的pull请求非常相似),但是我不愿意应用任何修补rails内部的东西,因为在主要版本之间升级可能是一个真正的痛苦,没有testing它(让我们面对它,开发人员经常吝啬控制器testing)。

参考

作为一种侵入性较小的替代scheme,您可以在控制器update操作中将json:选项传递给respond_with方法调用,如下所示:

 def update # ... respond_with some_object, json: some_object end 

当然这似乎有点不必要在参数中重复两次对象,但它会给你你想要的,对象的JSON表示在PUT请求的响应中,而且你不需要使用render json:这种方式,不会给你响应者的好处。

但是,如果你有很多控制者有这种情况,那么定制响应者,就像jpfuentes2在被接受的anwser中显示的那样,是要走的路。 但是对于一个简单的例子来说,这个select可能会更容易。

来源: https : //github.com/plataformatec/responders/pull/115#issuecomment-72517532

只是为了澄清,你不需要响应者gem这样做…你可以做:

configuration/初始化/ responder_with_put_content.rb

 class ResponderWithPutContent < ActionController::Responder def api_behavior(*args, &block) if put? display resource, :status => :ok else super end end end 

然后(对于所有更新操作都将受到影响):

 class ApplicationController < ActionController::Base def self.responder ResponderWithPutContent end end 

或在你的行动:

 def update foo = Foo.find(params[:id]) foo.update_attributes(params[:foo]) respond_with foo, responder: ResponderWithPutContent end 

简单的做什么错了:

 def update some_object = SomeObject.update() render json: some_object end 

不是这种行为的大粉丝。 为了解决这个问题,我必须避免使用respond_with方法:

 class SomeController < ApplicationController respond_to :json def update # ... respond_to do |format| format.json { render(json: some_object, status: 200) } end end end