Categories
blog Code meaningful labor rails ruby

Add automatic URL generation to your Rails App (+ a little about ActiveAdmin)

It’s easy to add a “url” or “slug” field to your rails app, and override the to_param function to report that field. A route can then look for an alphanumeric parameter, like this:

match "pages/:slug" => "purchases#show_by_slug"

But how to generate them without too much manual labour? [manual labour is a good thing, relying on well written gems is sometimes better]

There are many tools out there, I’ve recently used cached_slug to good effect. It not only stores a URL-friendly slug for the current page based on a field of your choosing, using it’s :sync parameter it allows you to automagically store previously used slugs (URLs) and thereby not break historical links. WordPress has a similar feature.

The project’s github page has a good tutorial on implementing cached_slug.

A word on ActiveAdmin

By default, ActiveAdmin looks for the numerical id field of a model (by calling to_param). However, a model using cached_slug will report back with it’s new slug confusing matters. So, your list view will find links to pages such as

http://0.0.0.0:3000/admin/infopages/about/edit

…but won’t understand what to do with the emboldened part, which should translate to :object_id. It will report

ActiveRecord::RecordNotFound

Couldn't find Infopage with id=about

The solution is simple, and a bit of searching will find the answer. You need to add a little instantiation (before_filter) magic to revert the id field to it’s original numerical form. Your edit link will now look like this again. http://0.0.0.0:3000/admin/infopages/1/edit

Add the following function, replacing the class name as appropriate. Reference.

  before_filter do
    Infopage.class_eval do
      def to_param
        id.to_s
      end
    end
  end