December 07, 2010
Since I have a certain level of self-loathing I decided to upgrade our app to the latest version of Rails (as of now, 3.0.3). Rails 3 is a big upgrade and change from Rails 2. One of the biggest areas getting a facelift is the routing system.
In general this guide does a great job explaining everything, but I recently ran into a rather specific wall. By default Rails prefers you to use what they call ”RESTful Routes”. I’m rather indifferent to the idea, but I go along with it. This provides you with 7 default routes for a resource. For example, say you create routes for a Model called “Photo”. This will create the following routes (stolen from the aforementioned guide):
This kind of approach works for 95% of my needs, but sometimes you just need to define something beyond the defaults. Say you need an action called “DoThis”. You can simply modify your Photo route like so:
resources :photos do
member do
get :dothis
end
end
And then /photos/1/dothis will map to a dothis method in your controller. This works as expected, but I needed to submit a form to a custom route as well. So, I just added this to my member do function:
post :dothat
I then attempted to submit a form to the dothat action, but got a Routing Error telling me the route wasn’t found. I double checked and the URL was definitely correct.
<%= form_for(@photo, :url => {:controller => 'photos', :action => 'dothat'} ) do |f| %>
It generated the correct URL: photos/1/dothat, which I confirmed by calling rake routes at the command line.
After searching the Interent and only getting frustrated I finally saw something that jogged my memory.
In REST, ‘post’ is for creating new resources. I was editing my model. Simply changing it to:
put :dothat
Fixed everything.
I’ll attribute that mixup to years and years of having only GET and POST available drilled into my head. It doesn’t exactly help that Rails doesn’t use a “real” PUT in the form’s method attribute. It uses POST, but includes a hidden input, ”_method” to store the verb it should respond to.
Written by Scott Williams who lives and works in sunny Phoenix, AZ. Twitter is also a place.