Beginning Ruby On Rails: Route A Custom Controller Action
January 28, 2009
I recently rewrote my pet project in Ruby on Rails: Again! A very long time ago, in a galaxy far far away (aka Johannesburg, since I’m now staying in Cape Town), the project was done in Python, and later I converted it to Java and Google Web Toolkit – ’cause I thought GWT kicked serious ass. It wasn’t going too bad with the Java-GWT affair, but somehow I never felt completely in love with GWT’s philosophy. I like designing HTML pages, and prefer not to have to code my UI in Java. Coding a UI as a bunch of classes, and not laying it out in design medium like HTML, is really not my cup of tea. After a recent project based on ASP .NET MVC and jQuery that turned out as one of my favorite projects ever, I realized that, personally, this is the way to go.
So with a lot of personal reluctance, I thought I’d give one of the most famous MVC web frameworks a try and see how it goes: Ruby On Rails. And man, am I impressed: I really enjoy scaffolding, DB migration, and how you can incrementally generate models, and controllers. The way which model objects can automatically accommodate any query via the method_missing mechanism is also wicked. And the fact that I don’t need to know anything but Ruby to achieve it all, is a real bonus. I have done work in Rails in a couple of minutes, that will take me hours to do in Java and GWT. And I’m only an amateur Ruby developer at this stage. Anyways, just thought I’d give a little background as to how I ended up writing about Ruby.
Routing a call to a custom controller action wasn’t too clear from the official Rails documentation, and I had to do a little more Googling than I thougt is acceptable.
In my case I wanted to add a custom controller action called “pick” that should display web_feeds/pick.html.erb:
class WebFeedsController < ApplicationController def pick end end
This will produce the error:
“ActiveRecord::RecordNotFound in WebFeedsController#show
Couldn’t find Post with ID=pick“
From this error message we infer that Rails thinks we are requesting the “show” view with WebFeed ID “pick”, which is not what we really want. Routes are defined in config/routes.rb. To view all the available routes for your application run rake routes in the shell. Routes defined before others get a higher priority. So you need to define more specific routes before the general/default routes. When you look at routes.rb you’ll notice lines beginning with map.resources :controller_name. Map.resources generates routes for seven default actions (index, show, create, new, edit, update, and destroy). So what we need to do is define a more specific route to our other custom actions, before these default routes:
map.connect "web_feeds/:action", :controller => 'web_feeds', :action => /[a-z_]+/i
This line will map to any custom action on WebFeedsController. The :action argument is a regular expression that accepts any word and underscores. This stops Rails from trying to map an ID for one of the default routes to an action. “i” Makes the regex case insensitive.





