Make descriptive URLs using friendly_id

Steve Condylios
2 min readJun 15, 2022
Descriptive URLs let users know where the link is going to take them.

This guide shows how to use the friendly_id gem on a posts scaffold so the title of the post is in the URL, and the history of the URL is remembered (so if the title of the post changes, old links will still work).

Setup and Installation

First make a new rails app and a posts scaffold

rails new myapp 
rails g scaffold post title content:text

In this example, we’ll create the slugs (urls) from the post’s title .

First add the most recent version of friendly_id to your Gemfile

gem 'friendly_id', '~> 5.4.0'

Create a migration to add a slug column to the posts table, as well as a unique index on that column

rails g migration AddSlugToPosts slug:uniq

Then run

rails generate friendly_id

And finally

rails db:migrate

Using friendly_id in the controller

In the set_post before_action, simply change

def set_post
@post = Post.find(params[:id])

To this

def set_post
@post = Post.friendly.find(params[:id])

Updating the model

Add this to your post model:

  extend FriendlyId
friendly_id :title, use: [:slugged, :history]

This tells friendly_id to use a post’s title as the basis for its slug .

Below that (also in the post model) place this which will update the slug when the title attribute changes:

def should_generate_new_friendly_id?

See more on should_generate_new_friendly_id? here and here.

That’s it!

That’s all there is to it. You should now see the slug in the URL for a post. If you update the post’s title, the URL will change accordingly, and the old URL will still work!

Extra tips

If you have existing posts which need friendly ids created for them, you can do this to create them


Also, if you’re using uuid as the primary key on your posts table, you’ll have to also change this line in the friendly_id_slugs table:

t.integer  :sluggable_id,   :null => false

to this

t.uuid  :sluggable_id,   :null => false


  • This great youtube video
  • This one too (although it doesn’t go into histories)
  • Offical friendly_id guide here
  • Friendly_id readme here