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.
Add this line to your application's Gemfile:
gem 'vanity_slug'
And then execute:
$ bundle
Or install it yourself as:
$ gem install vanity_slug
has_vanity_slug
- 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).
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.
- no catch all routes may be used in Rails, otherwise the route collision check will always find a matching route
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
VanitySlug.path_scope = Proc.new{|env|
{ site_id: Site.find_by_domain(env["HTTP_HOST"]).try(:id) }
}
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request