RESTful Rails

Today I decided to get my head around REST and, more specifically, whether and how I should use it in my Rails development projects.

REST (or REpresentational State Transfer – see Wikipedia), is all about resources. As I understand it, in a perfectly RESTful application, every object is resource with a unique identifier (in this case, a Web URL). Any resource can be created, deleted, updated or simply viewed. These operations correspond to the HTTP methods of POST, DELETE, PUT and GET respectively.

Suppose we have an application with a class called User. One instance of that class may have the following URI:

To read this user, we GET
To update the user, we can PUT data to
To create a new user, we POST to
To delete the user, we DELETE

Previously, in a traditional, non-RESTful environment, rather than using these different HTML methods (in particular, PUT and DELETE), you might have something like this:

To read the user, GET
To update the user, we can POST data to
To create a new user, we POST to
To delete the user, we might GET

For GET, PUT, POST and DELETE to work, your Rails application needs to know what to do with them when it receives them (otherwise, for example, how would it know whether you were reading, updating or deleting a user?) To tell Rails that you want to treat Users RESTfully, you specify so in the routes.rb file:

map.resources :users

This has the effect of mapping the GET, POST, PUT and DELETE of the URI to functions show, create, update and destroy in the associated controller. This mapping means that our application will handle such requests appropriately. But how will those requests get generated in the first place? Generally by the user’s browser following links that we’ve offered it. So the question is, how do we generate appropriate links?

We can generate RESTful links by using helper methods that are also (very handily) supplied by the resource declaration.

Named Route Helpers
============ =============================================
account account_url, hash_for_account_url,
account_path, hash_for_account_path

new_account new_account_url, hash_for_new_account_url,
new_account_path, hash_for_new_account_path

edit_account edit_account_url, hash_for_edit_account_url,
edit_account_path, hash_for_edit_account_path

So, for example,

link_to 'See user profile', :controller => 'users', :action => 'show', :id =>

might become

link_to 'See user profile', user_url(@user)

I converted a simple application to be mostly RESTful this afternoon, and switching to these helpers cleaned up the code considerably. I found that I did have a number of operations that couldn’t easily be mapped to a RESTful equivalent. It will be interesting to see whether, with a RESTful mindset, I can find a neater way to accomplish them.

In the meantime, for more details about taking a RESTful approach to Rails, have a look at the Rails API documentation.

London Startup Weekend

I spent this last weekend with a group of 30 or so web developers, designers and entrepreneurs that I’d never met before as part of something called London Startup Weekend. The idea was something that had already been tried out in the US, but was a first for the UK: to get a bunch of strangers together and start a company over the weekend. It was great fun and a fantastic way to meet and work with lots of interesting and talented people. The idea we ended up working on (after a rapid brainstorming and group vote on the Friday night) was something we came to call – a portal to help us all shop a little more ethically with a focus on sharing thoughts about different products and companies. If you’d like to do your bit to help the world become a slightly better place, please visit the site now and rate a few household products that you use. If you get in quick you’ll probably even spot a few endearing little kinks in the site that are still being ironed out. Go on! This is your chance to make a difference!

My Competitors get Dragons’ Den Funding

Half way through discussing my online takeaway idea with a friend, what should show up on Dragons’ Den, but two guys with a different online menu idea! We couldn’t believe it! are similar to and succeeding in getting £100,000 of funding from the Dragons in exchange for 50% of their company (although with the potential to earn back 20% if they hit their targets). Good for them. It will be interesting to see how they get on versus their (relatively more experienced) Danish competitors.

The entrepreneurs came out with a few interesting stats about the UK takeaway market:

  • Worth £1.2B in 2004
  • Growing at approx 6% per annum
  • Average orders are about £15

PayPal’s Comedy Customer Service

Is it just me, or is PayPal’s European customer service laughably bad?

I wrote to them on 10th October about a problem I’d been having. Thankfully, I didn’t really need a reply from them as my issue was resolved. I say thankfully, because it took them until just now (16th November) to send me a reply. Yep, over a month to get back to me. And, to make it even funnier, their reply is a totally generic one:

Dear Matthew Collins,

Thank you for contacting PayPal by email. We apologise for the delay in responding to you.

We value your business and we want to address all your questions in a timely fashion. If you still have a matter outstanding, please either re-send your email or, if you would prefer to speak with a PayPal representative, contact us at 0870 730 1895

Thank you for choosing PayPal!

PayPal (Europe) S.à r.l. & Cie, S.C.A.

Société en Commandite par Actions

Registered Office: 5th Floor 22-24 Boulevard Royal L-2449, Luxembourg

RCS Luxembourg B 118 349


Please do not reply to this e-mail. Mail sent to this address will not be answered.


Some wonderful lines in there…

“We value your business and we want to address all your questions in a timely fashion.”

“If you still have a matter outstanding, please either re-send your email…”

Thanks guys! Sure, I’ll just re-send my email and wait another month for you to reply with an identical response. Great idea :-)

The ‘no-reply’ email address is a lovely touch, too. Nothing like making things as convenient as possible for your customers.

To be fair, though, they do provide a phone number. At least that’s good to see.

Putting Takeaway Menus Online

Alright, it’s time to talk about a new idea I’ve been looking at and have been putting through some initial market testing. It’s quite simple, really: put takeaway menus online. I’m planning to scan as many menus as possible and put them all on a website so that whenever you’re hungry you can find the menus for pretty much any sort of takeaway restaurant nearby.

Good idea? What do you think?

Check out the trial website:

Creative Commons License photo credit: wolfsavard

Yet Another Localmouth Facelift

Yes, it was time for another round of CSS fun and some delving into istockphoto. I’ve been a bit freer with the colours with this version which I think makes the site look a bit more inviting. I’ve also added some graphical buttons to make the site look a bit more professional and hopefully encourage visitors to sign up and add content. I shall be monitoring the site through Google Analytics to see if the changes have any noticeable impact on visitor behaviour. Fingers crossed!

How to add nofollow to links in Rails

It’s really very simple, but this one took me a while to figure out, so I thought I’d post it in case it helps someone else.

If you want to add a rel='nofollow' attribute to a link generated with a Rails helper, you just need to specify it in the html_options hash argument to link_to (or whatever link helper you’re using).

For example:

<%= link_to 'Vote', { :action => 'vote' }, { :rel => 'nofollow' } %>

Voila! This should discourage web crawlers (such as the Google search crawler) from following links they shouldn’t and generating false ‘clicks’.

Getting content

Localmouth was feeling a bit empty. To help counter that problem I’ve hooked up a number of information feeds from other websites. Localmouth now pulls in listings for local news, events, property, jobs and personal ads. I’ve also added a Google map of the local area.

Here’s how the new local homepage looks.