8

I am writing a simple crud app on Phoenix. How does one submit PATCH and DELETE requests from a form without using javascript?

Chris McCauley
  • 25,824
  • 8
  • 48
  • 65
greggreg
  • 11,945
  • 6
  • 37
  • 52
  • 1
    http://stackoverflow.com/questions/165779/are-the-put-delete-head-etc-methods-available-in-most-web-browsers – Barmar Jan 27 '15 at 06:00
  • @Barmar this is a phoenix specific question – greggreg Jan 27 '15 at 06:47
  • If it depends on what the browser supports in `
    `, I don't think the framework matters.
    – Barmar Jan 27 '15 at 06:54
  • @Barmar - not so, the question is really how can one tell Phoenix to ignore the explicit verb (POST) and use PATCH instead. Rails made a particular convention popular (use _method to override the verb) so it's a reasonable bet that Phoenix did something similar but maybe not. – Chris McCauley Jan 27 '15 at 13:41

3 Answers3

7

Ah I figured it out, same as rails:

<form method="POST">
  <input name="_method" type="hidden" value="patch" />
...

Handled in Plug.MethodOverride: https://github.com/elixir-lang/plug/blob/master/lib/plug/method_override.ex

greggreg
  • 11,945
  • 6
  • 37
  • 52
  • Check out @Barmar's comment, not all browsers are supported — some only understand GET and POST. Rails for example uses a hidden form field `_method` as a workaround. – Patrick Oscity Jan 27 '15 at 06:26
  • 2
    @PatrickOscity, not trying to be rude at all but my question presupposes the fact that browsers don't all natively support methods other than GET and POST, and the answer that you commented on plainly states that not only did I figure it out but that I am using the exact same workaround used in rails. I feel like neither you nor Bamar took the time to actually read what my question or answer were. :/ I was asking for a Phoenix specific solution... and I found it. – greggreg Jan 27 '15 at 06:44
  • Isn't this solution what the first answer in the question I linked to suggests? – Barmar Jan 27 '15 at 06:55
  • 1
    @greggreg sorry for that. Indeed it seems I did not read your answer properly. Maybe it's a bit too early in the morning. I just saw the input element and skipped the rest of the line. Your approach is perfectly fine! – Patrick Oscity Jan 27 '15 at 06:57
  • @Barmar the first answer of the question you linked to simply states that many browsers support only GET and POST, that some frameworks have workarounds (which was my actual specific question) and that AJAX requests support other HTTP verbs. – greggreg Jan 27 '15 at 08:13
  • easy enough, its the same as rails – max pleaner Jan 27 '17 at 05:00
4

<form> elements only support sending GET and POST requests. The workaround that Rails uses is to read the request method from the _method request parameter, overriding the actual request method (the GET or POST method).

Phoenix does exactly the same through Plug, the Rack-like framework that Phoenix is built on. Long story short, Plug provides middlewares and one of the middlewares it provides is Plug.MethodOverride, which does exactly what we discussed. Doing so in a middleware, the Phoenix app barely knows that the original request was not a GET/POST.

You can see Plug.MethodOverride used in Phoenix's source code.

whatyouhide
  • 15,897
  • 9
  • 57
  • 71
  • Awesome, thanks for the doc links. Helped me find the source: https://github.com/elixir-lang/plug/blob/master/lib/plug/method_override.ex – greggreg Jan 27 '15 at 21:37
4

As the others have mentioned, Phoenix handles this in the routing via the MethodOverride plug.

In order to change this in the template with the form_for helper, use the :method parameter:

<%= form_for @changeset, path(@conn, :update), [multipart: true, method: "patch"], fn f -> %>

This will add the hidden input to the HTML, as noted by @greggreg:

<input name="_method" type="hidden" value="patch" />

Stephen Watkins
  • 25,047
  • 15
  • 66
  • 100