Part of my task when building my Sinatra app is to adhere to RESTful resources, which means using the standard HTTP verbs and a conventional routing pattern. Rails provides lots of form helpers and support for your GETs, POSTs, PUTs and DELETEs and can even take care of the routing with something like a simple resources :users line in your routes file. However, in Sinatra you need to explicitly define those routes, which means that you only have the code for what you really need, but of course you’re rolling it by hand.

The form helpers that RAILS provide automatically handle translating all of the action and method requests for the aforementioned verbs, but HTML forms really only support the GET and the POST methods. So, if you want to use the PUT and DELETE you need to trick your form into going to the right place.

A standard HTML form for POST would look like so:

<form method="post" action="/tasks">
    # ... all of your form fields
    <button type="submit">Submit</button>
</form>

In order to use POST in Sinatra you need to do this (where @task is the specific task I’m updating):

<form method="post" action="/tasks/<%= @task.id %>"> 
    <input type="hidden" name="_method" value="put">
    #.. all of your form fields
    <button type="submit">Update</button>
</form>

And in order to use DELETE you would just swap out the value="put" for value="delete".

This little form trickery is courtesy of some Ruby method magic provided by Rack::MethodOverride, which is also used by Rails. It allows the default method to be overridden when we set the params[:method] like we do in the hidden input above.

Big props to the nettuts “Singing with Sinatra - Part 2” tutorial for helping me figure this out and to this Stack Overflow post.