Why does my Rails form always return a `POST` when I explicitly calling `PUT`?

1.1k Views Asked by At

Here's my examples that produce the same result :

# `enterprise_registration` is an already created/saved object

form_for enterprise_registration, method: :put do |format|; format; end
form_for enterprise_registration, url: logo_url, method: :put do |format|; format; end
form_for enterprise_registration, url: logo_url, html: {method: :put} do |format|; format; end

This returns the form with the method attribute set to POST.

Why is that happening, do you think? And how can I make it a :put request?

Update

I now understand that Rails forms embed a hidden _method and set it to put, but my form is still getting delivered as a POST that is preventing my form from finding my matching PUT URL

2

There are 2 best solutions below

0
On

Web browsers are actually only programmed to receive POST and GET requests (I'm not sure why). The way Rails mimics full REST (which includes put and delete) is include those in hidden fields. So technically it's sending a POST, but with the PUT attached sort of awkwardly in that hidden field.

I'm assuming that Rails is still doing that sort of conversion behind the scenes still.

6
On

form tag has only GET or POST method allowed. See also here for more explanation. Rails, however, has his own method to handle GET/POST/PUT/PATCH requests. If you would examine any of your form defined as either form_for or form_tag in Rails, you will notice that first element of the form is a hidden <div> which contain two hidden fields:

<div style="display:none">
  <input name="utf8" type="hidden" value="✓"><input name="_method" type="hidden" value="patch">  
  <input name="authenticity_token" type="hidden" value="9i5eRhwhx4NhvSxqIJm6cv9x6NSlY82hpNpfrpk/I0c=">
</div>

First field called _method contains the form action which is the request type for controller.