I want to PUT
to rails and avoid getting a 204
. I am using this pattern:
class SomeController < ApplicationController
respond_to :json
def update
# ...
respond_with(some_object)
end
end
However, when I do a put
to update, I get a 204
back. I realize this is completely valid etc, but I explicitly want the content back. I can override it to some extent like this:
def update
respond_with(some_object) do |format|
format.json{render json: some_object}
end
end
but this seems a bit too hands-on for rails. Is there any more idiomatic way of avoiding a 204
and requesting the full content to be sent back? This is Rails 3.2.
In summary: I want maximally idiomatic rails that avoids a 204
.
I made a custom responder which always returns my JSON encoded resource even on PUT/POST.
I put this file in lib/responders/json_responder.rb
. Your /lib
dir should be autoloaded.
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 which requires this behavior, or place it in the application controller.
class ApplicationController < ActionController::Base protect_from_forgery responders :json end
You should now get JSON encoded resources back on PUT.
As a less invasive alternative, you can pass a json:
option to the respond_with
method invocation inside your controller update
action, like this:
def update
# ...
respond_with some_object, json: some_object
end
Granted it seems a bit unDRY having to repeat the object twice in the arguments, but it'll give you what you want, the json representation of the object in the response of a PUT request, and you don't need to use the render json:
way, which won't give you the benefits of responders.
However, if you have a lot of controllers with this situation, then customizing the responders, as jpfuentes2 showed in the accepted anwser, is the way to go. But for a quick single case, this alternative may be easier.
Source: https://github.com/plataformatec/responders/pull/115#issuecomment-72517532
This behavior seems intentional to fall in line with the HTTP spec, and "ideally" you should be firing off an additional GET request to see the results. However, I agree in the real world I'd rather have it return the JSON.
@jpfuentes2's solution above should do the trick (it's very similar to the pull request below), but I'm hesitant to apply anything that's patching rails internals, as it could be a real pain to upgrade between major versions, especially if you don't have tests for it (and let's face it, developers often skimp on controller tests).
References
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With