Browse the Ruby on Rails Community.

You are here: Browse Railsplugins Sluggable Finder

Sluggable Finder

Ismael Celis (http://www.estadobeta.com)

This is a variation of acts_as_sluggable and acts_as_permalink. This plugin allows models to generate a unique “slug” (url-enabled name) from any regular atribute. Sluggable models can have a scope parameter so slugs are unique relative to a parent model.

The plugin also adds an ActiveRecord::Base#find_sluggable method that looks into the “slug” field. If not found, it raises an ActiveRecord::RecordNotFound exception so you can use it just like find_by_id

The plugin modifies to_param so it’s transparent to link_to and url_for view helpers

EXAMPLES

++++++++++++ In your models (app/models) +++++++++++++++ class Category < ActiveRecord::Base has_many :posts sluggable_finder :title #slugifies the :title field into the :slug field end

class Post < ActiveRecord::Base belongs_to :category has_many :comments sluggable_finder :title, :scope => :category_id #Post slugs are unique to the parent category end

class Comment < ActiveRecord::Base belongs_to :post sluggable_finder :get_slug, :to => :permalink #creates slug from custom attribute and stores it in “permalink” field end

def get_slug #we define the custom attribute
    "#{post.id}-#{Time.now}" 
end
  1. Provide a list or reserved slugs you don’t want available as permalinks # sluggable_finder :title, :reserved_slugs => [‘admin’,’settings’,’users’]

++++++++++++ In your routes (config/routes.rb)++++++++++++

map.post ‘posts/:post_slug’

Or just the usual

map.post ‘posts/:id’

..because now Post.to_param returns the sluggable field anyway

++++++++++++ In your controllers (app/controllers)++++++++++

You can do Model.find(slug) just how you would with a single numerical ID. It will also raise a RecordNotFound exception so you can handle that in your custom rescue_action_in_public action (more on that on http://www.estadobeta.com/2007/05/06/activerecordrecordnotfound/#comment-17669). The idea is that you keep your controller actions clean and handle Not Found errors elsewhere. You can still use Model.find the regular way.

class PostsController < ApplicationController def show @post = Post.find( params[:post_slug] ) #raises ActiveRecord::RecordNotFound if not found end end

INSTALLATION

Download it to your Rails app as usual.

.script/plugin install http://code.estadobeta.com/plugins/sluggable_finder

Generate the migration to add the “slug” field to you model (“slug” is the default. You can use other field names).

.script/generate migration AddSlugToBlogs

class AddSlugToBlogs < ActiveRecord::Migration def self.up add_column :blogs, :slug, :string end end

def self.down
  remove_column :blogs, :slug
end

migrate it

rake db:migrate

  1. Use it as in the EXAMPLES part above.
  2. Questions to Ismael at http://www.estadobeta.com

NOTE: This description has been extracted from the Plugin README and so the formatting may need updating to make browser friendly

Users


See all details


Membership

+ Join this railsplugin

Record Maintainer

'None'