我希望PUT
加入导轨,避免获得204
。我正在使用这种模式:
class SomeController < ApplicationController
respond_to :json
def update
# ...
respond_with(some_object)
end
end
但是,当我进行put
更新时,我会收到204
。我意识到这是完全有效的,但我明确地希望内容回来。我可以在某种程度上覆盖它:
def update
respond_with(some_object) do |format|
format.json{render json: some_object}
end
end
但是对于rails来说这似乎有点过分了。有没有更惯用的方法来避免204
并要求发回全部内容?这是Rails 3.2。
总结:我想要避免204
的最大惯用轨道。
答案 0 :(得分:31)
我制作了一个自定义响应器,即使在PUT / POST上也会返回我的JSON编码资源。
我把这个文件放在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
您现在应该在PUT上重新获得JSON编码资源。
答案 1 :(得分:12)
作为一种侵入性较小的替代方法,您可以将respond_with
选项传递给控制器update
操作中的def update
# ...
respond_with some_object, json: some_object
end
方法调用,如下所示:
render json:
当然,似乎有点unDRY不得不在参数中重复两次对象,但是它会给你你想要的东西,对象的json表示在PUT请求的响应中,你不需要使用Path.GetExtension
方式,这不会给您带来响应者的好处。
但是,如果你有很多这种情况的控制器,那么定制响应者,就像jpfuentes2在接受的anwser中所显示的那样,是可行的方法。但对于快速单一案例,这种替代方案可能更容易。
来源:https://github.com/plataformatec/responders/pull/115#issuecomment-72517532
答案 2 :(得分:11)
这种行为似乎是故意与HTTP规范一致,并且“理想情况下”您应该触发额外的GET请求以查看结果。但是,我同意在现实世界中我宁愿让它返回JSON。
@ jpfuentes2上面的解决方案应该可以解决这个问题(它与下面的pull请求非常相似),但是我对应用任何修补rails内部结构的东西犹豫不决,因为在主要版本之间升级可能是一个真正的痛苦,特别是如果你没有对它进行测试(让我们面对它,开发人员通常会吝啬控制器测试)。
参考
答案 3 :(得分:9)
只是为了澄清,你不需要响应者宝石这样做......你可以这样做:
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
答案 4 :(得分:3)
简单地做错了什么:
def update
some_object = SomeObject.update()
render json: some_object
end
答案 5 :(得分:1)
不是这种行为的忠实粉丝。为了解决这个问题,我不得不避免使用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