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
This module is incompatible with the :scoped
module.
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.find params[:id]
# If an old id or a numeric id was used to find the record, then
# the request path will not match the post_path, and we should do
# a 301 redirect that uses the current friendly id.
if request.path != post_path(@post)
return redirect_to @post, :status => :moved_permanently
end
end
end
Defined Under Namespace
Modules: FinderMethods, SlugGenerator
Class Method Summary (collapse)
-
+ (Object) included(model_class)
Configures the model instance to use the History add-on.
Instance Method Summary (collapse)
- - (Object) create_slug private
Class Method Details
+ (Object) included(model_class)
Configures the model instance to use the History add-on.
60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/friendly_id/history.rb', line 60 def self.included(model_class) model_class.instance_eval do raise "FriendlyId::History is incompatible with FriendlyId::Scoped" if self < Scoped @friendly_id_config.use :slugged has_many :slugs, :as => :sluggable, :dependent => :destroy, :class_name => Slug.to_s, :order => "#{Slug.quoted_table_name}.id DESC" after_save :create_slug relation_class.send :include, FinderMethods friendly_id_config.slug_generator_class.send :include, SlugGenerator end end |
Instance Method Details
- (Object) create_slug (private)
74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/friendly_id/history.rb', line 74 def create_slug return unless friendly_id return if slugs.first.try(:slug) == friendly_id # Allow reversion back to a previously used slug relation = slugs.where(:slug => friendly_id) result = relation.select("id").lock(true).all relation.delete_all unless result.empty? slugs.create! do |record| record.slug = friendly_id end end |