Simple respond_with in rails that avoids 204 from PUT

前端 未结 6 447
有刺的猬
有刺的猬 2020-12-23 17:46

I want to PUT to rails and avoid getting a 204. I am using this pattern:

class SomeController < ApplicationController
  respond_         


        
相关标签:
6条回答
  • 2020-12-23 17:50

    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

    • https://github.com/rails/rails/issues/9862
    • https://github.com/rails/rails/pull/9887
    0 讨论(0)
  • 2020-12-23 17:53

    Not a big fan of this behavior. To get around it, 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
    
    0 讨论(0)
  • 2020-12-23 18:02

    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

    0 讨论(0)
  • 2020-12-23 18:09

    Just to clarify, you do not need the responders gem to do this... You can just 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 updates actions to 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
    
    0 讨论(0)
  • 2020-12-23 18:11

    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.

    0 讨论(0)
  • 2020-12-23 18:13

    What's wrong with simply doing:

    def update
      some_object = SomeObject.update()
      render json: some_object
    end
    
    0 讨论(0)
提交回复
热议问题