Introduction

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

Summary

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

rails friendlyid