#245 awaiting-patch
Andres Jaan Tack

Form Submission Ignores PUT/DELETE Methods

Reported by Andres Jaan Tack | May 19th, 2009 @ 10:32 AM

When Rails sets up a form for the update action, it employs the HTTP PUT method. Unfortunately, for most browsers, if you write, <form ... method="put">, the browser will assume you're an idiot and actually execute a POST request.

Rails' solution to this problem is to include a hidden field (input[name="_method"]) whose value is the actual request method to recognize on the controller side if this method is PUT or DELETE. The existing Webrat form submission method (Webrat::Form#submit) does not take this into account.

The following monkey-patch resolves the issue in my applications. A patch for webrat/core/elements/form.rb is attached (mirroring the below exactly). I'm not certain how to implement a test for the change.

module Webrat
  class Form
    protected
      def form_method
        special_method = Webrat::XML.css_search(@element, 'input[name="_method"]').first
        unless special_method.nil?
          special_method['value']
        else
          Webrat::XML.attribute(@element, "method").blank? ? :get : Webrat::XML.attribute(@element, "method").downcase
        end
      end
  end
end

This ticket affects Webrat 0.4.4, under Rails 2.3.2.

Comments and changes to this ticket

  • gaffo

    gaffo May 28th, 2009 @ 07:22 PM

    • Tag changed from delete, form, method, put, rails to delete, form, method, put, rails, test!, verify
    • State changed from “new” to “awaiting-patch”

    Andres,
    Thanks for the patch! However, could you please add some specs to show that it's working and what the bug is that it's covering?

  • Bryan Helmkamp

    Bryan Helmkamp June 14th, 2009 @ 10:24 PM

    Andres -- The reasoning behind the current behavior is that Webrat just acts like a browser (sending a POST and a _method param), and Rails translates that into a PUT or DELETE internally. So my understanding is that Webrat actually doesn't need to account for this case, just like a regular browser doesn't.

    It's possible though that there's something that causes Webrat requests to be treated differently in this regard than a real request. If that's the case, we should get an integration spec on it.

    Cheers,

    -Bryan

  • Andres Jaan Tack

    Andres Jaan Tack June 15th, 2009 @ 02:55 AM

    Bryan, your understanding of the _method+POST thing is correct, and Rails does do the routing internally when you're running the server.

    Mechanize, however, runs a request directly against the controller with the method specified explicitly, so it ends up being a problem (or, at least, it became a problem for me somewhere).

    As you say, and Gaffo mentioned before, this really deserves a repeatable test to demonstrate the problem. I'll have to look for inspiration on how to write one. Any suggestions?

  • Bryan Helmkamp

    Bryan Helmkamp June 15th, 2009 @ 09:07 AM

    When using mechanize, I would expect the request to be sent as a POST with the _method param, and Rails to interpret it as a PUT or DELETE as well. Should still be the same as the browser.

    As far as a test, the first step would be to isolate the simplest example of a bit of code using Webrat and Rails code that produces the wrong behavior. If you have that, we can help you get it into the test suite. The suite is in a state of flux right now, as we try to improve coverage of the different adapters.

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป

Ruby Acceptance Testing for Web applications.

Shared Ticket Bins

Attachments

Pages