Super Computer.

Instructions for Implementing Friendly ID

Step-by-step instructions for implementing Friendly ID in a Rails app.

You already know RESTful urls are n00b sauce, otherwise you wouldn’t be here.

If you’re not familiar, Friendly ID is a sweet gem that turns Rails standard RESTful urls (e.g. /users/1/) into more friendly and best practice string-based urls (e.g. /chris-lake)

The following instructions were curated from Norman Clarke’s complete documentation and Ryan Bates’s RailsCast — because the former is more in-depth than necessary for your run of the mill Rails app, and the latter is not quite deep enough.

Add FriendlyID to your Rails app’s gemfile.

gem 'friendly_id', '5.0.0.beta4' #=> Or whatever the current version is.

From terminal run bundle install, per usual:

$ bundle install

For all the models you want to add FriendlyId’s, run the following migration.

$ rails g migration add_slug_to_[your model name here] slug:string

Ryan Bates says it’s a good idea to add an index for finding records, and at this point in my coding career, I’m a follow Ryan Bates’s advice. (Btw, that dude is the man. I hope he takes the time he needs to get his head straight.)

In the migration file – let’s use a User model by way of example – /db/migrate/20120101000000_add_slug_to_user.rb, add the index like so.

class AddSlugToUsers < ActiveRecord::Migration 
  def change
    add_column :users, :slug, :string
    add_index :users, :slug, unique: true
  end
end

Please remember to run the migration.

$ rake db:migrate

To fill the slug in for existing records, we need to go into each record and save it.

$ rails c
> User.find_each(&:save)

We’ll want our slugs to update when records are changed in the db. At the same time it seems to be a good practice to still recognize older slugs and their legacy urls. We can do this by using FriendlyID’s history option in our model /app/models/user.rb.

class User < ActiveRecord::Base
  extend FriendlyId
  friendly_id :name, use: [:slugged, :history]
end

This history needs to be stored somewhere so you’ll also want to add a table to your database schema to store the slug records. FriendlyID provides a generator for this purpose:

$ rails generate friendly_id

And again.

$ rake db:migrate

Ryan Bates points out that, at this point, if our customer visits a legacy url, it will just work. Better would be to redirect them to the new url. We can do this by adjusting the show page on the controller – /app/controllers/users_controller.rb

Not sure if I’ll even bother implementing this, but here’s the syntax.

def show
  @user = User.find(params[:id])
  if request.path != user_path(@user)
    redirect_to @user, status: :moved_permanently
  end
end