Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Ruby
branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
lib
spec
.gitignore
Gemfile
LICENSE.txt
README.md
Rakefile
circle.yml
vanity_slug.gemspec

README.md

VanitySlug

Test Coverage

Add unique vanity urls to any model without use of redirects. Middleware matches routes that don't resolve with the Rails router and checks if they match a slug from any vanity-slug enabled model. If found, the env["PATH_INFO"] is changed like so:

Given a Post with slug "my-post-title" and id 1, and a Category with slug "the-category" and id 2:

"/my-post-title" => "/posts/1"
"/the-category" => "/category/2"

This lets Rails do the rest of the work.

Installation

Add this line to your application's Gemfile:

gem 'vanity_slug'

And then execute:

$ bundle

Or install it yourself as:

$ gem install vanity_slug

Usage

has_vanity_slug

Options

  • action: route vanity slug will resolve to (default: RESTful show route i.e. "/posts/:id"). Route must be defined.
  • field_to_slug: which column to use in vanity slug generation (default: :name).
  • slug_field: which column to store generated slug (default: :slug).
  • uniqueness_scope: method or attribute to use as uniqueness scope in slug generation (default: nil).

Config

    VanitySlug.path_scope Proc.new { |env| { } }

Use to scope the finder based on rack env, i.e. host parameter. Should return a hash suitable for a where relational argument.

Gotchas

  • no catch all routes may be used in Rails, otherwise the route collision check will always find a matching route

Examples:

    class Post < ActiveRecord::Base
      attr_accesible :title

      has_vanity_slug field_to_slug: :title, uniqueness_scope: :site_id

      belongs_to :site
    end

    class Category < ActiveRecord::Base
      attr_accesible :name

      has_vanity_slug action: "/categories/:id/slug", slug_field: :permalink

      belongs_to :site
    end

    class Site < ActiveRecord::Base
      attr_accessible :domain
    end

Initializer:

    VanitySlug.path_scope = Proc.new{|env|
      { site_id: Site.find_by_domain(env["HTTP_HOST"]).try(:id) }
    }

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request
Something went wrong with that request. Please try again.