Trivial friendly URL routing for Ruby on Rails 2009-08-28

Back to the times I was programming in PHP (it hasn’t been that long but it feels like an eternity has passed), I worked in a company own made CMS. One of my biggest headaches was tuning and reimplementing the friendly URL generator.

Having the need to implement friendly URLs for a little and very specific CMS using Rails I found that it was a trivial matter. So I basically came up with a model acting as a tree (let’s call it Page), a route and a class method.

First thing I did was creating a model Page with the fields I needed plus, a slug string field, plus a parent_id integer field. I installed the acts_as_tree plugin and made my model use it.

Then I set up a route:

  1. map.connect '*slugs':controller => 'pages':action => 'show'  

Next thing was creating a class method to process the slugs chain:

  1. class Page < ActiveRecord::Base  
  2.   def self.locate_by_slugs(slugs, parent_id=nil)  
  3.     page = if slugs.size == 1  
  4.       Page.find_by_slug_and_parent_id!(slugs.first, parent_id)  
  5.     else  
  6.       parent_page = Page.find_by_slug!(slugs.shift, :select => 'id')  
  7.       Page.locate_by_slugs(slugs, parent_page.id)  
  8.     end  
  9.   end  
  10. end  

Lastly, I created the show action on PagesController:

  1. class PagesController < ApplicationController    
  2.   def show  
  3.     @page = Page.locate_by_slugs(params[:slugs].dup)  
  4.   end  
  5. end  

Well, I haven’t carried out a revolution, it’s nothing fancy, it’s been done a million times before, I don’t even talk about the slug generation process. This post is just another evidence of how amazing the Ruby on Rails framework is.