Fix override API response bug in respond_with #4869

Merged
merged 1 commit into from Feb 4, 2012

Projects

None yet

2 participants

@sikachu
Member
sikachu commented Feb 3, 2012

Default responder was only using the given respond block when user
requested for HTML format, or JSON/XML format with valid resource. This
fix the responder so that it will use the given block regardless of the
validity of the resource. Note that in this case you'll have to check
for object's validity by yourself in the controller.

See #4796. This is for master.

Member

I don't think we should even call the responder. We should just yield the block, as in respond_to.

Member
sikachu commented Feb 3, 2012

Ah yeah, you're right. Fixing that now.

Member

retrieve_response_from_mimes could probably return the collector and then we ask it directly if there is a response (and invoke) or fallback to the default one (with the responder).

@sikachu sikachu Fix override API response bug in respond_with
Default responder was only using the given respond block when user
requested for HTML format, or JSON/XML format with valid resource. This
fix the responder so that it will use the given block regardless of the
validity of the resource. Note that in this case you'll have to check
for object's validity by yourself in the controller.

Fixes #4796
3def1c8
Member
sikachu commented Feb 3, 2012

Code has been updated.

@josevalim josevalim commented on the diff Feb 4, 2012
actionpack/lib/action_controller/metal/mime_responds.rb
options = resources.size == 1 ? {} : resources.extract_options!
- options.merge!(:default_response => response)
- (options.delete(:responder) || self.class.responder).call(self, resources, options)
+
+ if defined_response = collector.response_for(negotiated_format(collector))
+ if action = options.delete(:action)
josevalim
josevalim Feb 4, 2012 Member

Why do we need this exactly?

sikachu
sikachu Feb 4, 2012 Member

There's a functionality that you can pass in :action => 'some_action' to respond_with block, and the responder will ignore the response block given and render that action instead. I have to retain this functionality so that the test for this still pass.

  def using_resource_with_action
    respond_with(resource, :action => :foo) do |format|
      format.html { raise ActionView::MissingTemplate.new([], "bar", ["foo"], {}, false) }
    end
  end

#--

  def test_using_resource_with_action
    @controller.instance_eval do
      def render(params={})
        self.response_body = "#{params[:action]} - #{formats}"
      end
    end

    errors = { :name => :invalid }
    Customer.any_instance.stubs(:errors).returns(errors)

    post :using_resource_with_action
    assert_equal "foo - #{[:html].to_s}", @controller.response.body
  end
josevalim
josevalim Feb 4, 2012 Member

Awesome, thanks for the explanation. Meeeeerging.

@josevalim josevalim merged commit 776a373 into rails:master Feb 4, 2012
Member
sikachu commented Feb 4, 2012

Yay, don't forget #4870 for 3-2-stable as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment