Module: FriendlyId::History

Defined in:
lib/friendly_id/history.rb

Overview

## History: Avoiding 404’s When Slugs Change

FriendlyId’s History module adds the ability to store a log of a model’s slugs, so that when its friendly id changes, it’s still possible to perform finds by the old id.

The primary use case for this is avoiding broken URLs.

### Setup

In order to use this module, you must add a table to your database schema to store the slug records. FriendlyId provides a generator for this purpose:

rails generate friendly_id
rake db:migrate

This will add a table named ‘friendly_id_slugs`, used by the Slug model.

### Considerations

Because recording slug history requires creating additional database records, this module has an impact on the performance of the associated model’s ‘create` method.

### Example

class Post < ActiveRecord::Base
  extend FriendlyId
  friendly_id :title, :use => :history
end

class PostsController < ApplicationController

  before_filter :find_post

  ...

  def find_post
    @post = Post.friendly.find params[:id]

    # If an old id or a numeric id was used to find the record, then
    # the request slug will not match the current slug, and we should do
    # a 301 redirect to the new path
    if params[:id] != @post.slug
      return redirect_to @post, :status => :moved_permanently
    end
  end
end

Defined Under Namespace

Modules: Configuration, FinderMethods

Class Method Summary collapse

Class Method Details

.included(model_class) ⇒ Object

Configures the model instance to use the History add-on.



72
73
74
75
76
77
78
79
80
81
82
# File 'lib/friendly_id/history.rb', line 72

def self.included(model_class)
  model_class.class_eval do
    has_many :slugs, -> { order(id: :desc) }, **{
      as: :sluggable,
      dependent: @friendly_id_config.dependent_value,
      class_name: Slug.to_s
    }

    after_save :create_slug
  end
end

.setup(model_class) ⇒ Object



62
63
64
65
66
67
68
69
# File 'lib/friendly_id/history.rb', line 62

def self.setup(model_class)
  model_class.instance_eval do
    friendly_id_config.use :slugged
    friendly_id_config.class.send :include, History::Configuration
    friendly_id_config.finder_methods = FriendlyId::History::FinderMethods
    FriendlyId::Finders.setup(model_class) if friendly_id_config.uses? :finders
  end
end