A simple response_with in rails that avoids 204 from PUT

I want to PUT on rails and do not get 204 . I am using this template:

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

However, when I update PUT , I get back 204 . I understand that this is fully valid, etc., but I clearly want the content to be back. I can redefine this to some extent:

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

but it seems too practical for rails. Is there a more idiomatic way to avoid 204 and request full content to send? This is Rails 3.2.

In short: I want the most idiomatic rails that avoid 204 .

+48
ruby-on-rails
Mar 31 '12 at 7:17
source share
6 answers

I created my own responder that always returns my JSON-encoded resource even in PUT / POST.

I put this file in lib/responders/json_responder.rb . Your /lib directory should be automatically loaded.

 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 

Now, explicitly modify the controller that requires this behavior, or place it in the application controller.

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

Now you should get JSON-encoded resources on PUT.

+29
Apr 10 2018-12-12T00:
source share

This behavior seems intentional according to the HTTP specification, and "ideally" you should fire an additional GET request to see the results. However, I agree in the real world, I would prefer to return JSON.

Decision

@ jpfuentes2 above should do the trick (it looks very much like a pull request below), but I hesitate to apply anything that fixes the insides of the rails, as this can be a real pain to upgrade between major versions, especially if you don't have tests for this (and let them face it, developers often save controller tests).

References

+11
May 08 '13 at 15:57
source share

As a less invasive alternative, you can pass the json: option to call the respond_with method inside your action with the update controller, for example:

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

Of course, it seems that the unDRY bit should repeat the object twice in arguments, but it will give you what you want, the json representation of the object in the PUT request response, and you do not need to use the render json: method, which will not give you the benefits of the respondents.

However, if you have a lot of controllers with this situation, then setting up respondents as shown by jpfuentes2 in the accepted underserver is the way to go. But for a quick solitary case, this alternative could be simpler.

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

+9
May 13 '15 at 12:15
source share

To clarify, you do not need a stone responder to do this ... You can simply do:

config / Initializers / 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 

and then either (for all actions that will be affected):

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

or in your action:

 def update foo = Foo.find(params[:id]) foo.update_attributes(params[:foo]) respond_with foo, responder: ResponderWithPutContent end 
+6
Dec 11
source share

Which is not so simple:

 def update some_object = SomeObject.update() render json: some_object end 
+3
Feb 13 '13 at 20:20
source share

Not a big fan of this behavior. To get around this, I had to avoid using the respond_with method:

 class SomeController < ApplicationController respond_to :json def update # ... respond_to do |format| format.json { render(json: some_object, status: 200) } end end end 
+1
Jun 01 '15 at 20:02
source share



All Articles