Intro

Friendly ID, is a ruby gem that makes adding slugs to your Rails records painless giving you nice human readible URI's. Instead of accessing URI's by their database ID: /site/23 they are accessed via /site/hogwarts instead. Much better.

In this post I will show you how to add Friendly ID to your Rails 6 app.

  • Rails - 6.0.3.4
  • Friendly ID - 5.4.0

Installation

Add the friendly_id gem to your Gemfile .

file
# Gemfile

gem 'friendly_id', '~> 5.4.0'

Install the gem with the bundle command.

cmd
bundle install

Usage

Add a slug field to the required tables.

Note
In the following examples I will be working with a Site model.
cmd
rails generate migration AddSlugToSites slug:uniq

This will create a db/migrate/<timestamp>_add_slug_to_sites.rb file.

Use the friendly_id generator to create the configuration files.

cmd
rails generate friendly_id

This creates two files

  • config/initializers/friendly_id.rb
  • db/migrate/<timestamp>_create_friendly_id_slugs.rb

friendly_id.rb is used to customize the Friendly ID install. This works out of the box and no changes arr required.

<timestamp>_create_friendly_id_slugs.rb Creates a history table of model slugs. This is used in the event a slug is changed the resource can still be found via the old slug thus avoiding broken URLs.

This feature has a storage and performance impact so if you dont need this for your app, you can delete this migration file.

Apply the database migration.

cmd
rails db:migrate

Configure your model to use friendly_id.

file
# app/models/site.rb

class User < ApplicationRecord
  extend FriendlyId
  friendly_id :code, use: :slugged
end

Configure your controller to fetch records using the friendly_id .

file
# app/controllers/sites_controller.rb

class SiteController < ApplicationController
  def show
    # @site = Site.find(params[:id])         # << old
    @site = Site.friendly.find(params[:id])  # << new
  end
end

Alternately, if you use a private method to access individual records you might use something like the below.

file
# app/controllers/sites_controller.rb

class SiteController < ApplicationController
  before_action :set_site, only: [:show, :edit, :update, :destroy]

  def show
  end

  private
    def set_site
      # @site = Site.find(params[:id])         # << old
      @site = Site.friendly.find(params[:id])  # << new
    end
end

If you already have records in your table, update them with a friendly_id from the rails console .

cmd
# in rails console

Site.find_each(&:save)

Finally, because we added an initializer, a restart of the server is required.

Testing

Go to a resources URI and confirm you can access the record. IE: http://<hostname>/site/hogwarts

Outro

In this post we added Friendly URI slugs to our Rails 6 app using the Friendly ID gem. Maximo Leviato!!!