slug

Slug provides simple, straightforward slugging for your ActiveRecord models.

Slug is based on code from Norman Clarke's fantastic friendly_id project and Nick Zadrozny's friendly_identifier.

What's different:

INSTALLATION

sudo gem install slug

then add

config.gem 'slug'

to your rails project.

Note that this version of slug is only compatible with Rails/active_support/active_record 3.x+. Rails 2 applications should use slug 0.5.3.

USAGE

It's up to you to set up the appropriate column in your model. By default, Slug saves the slug to a column called 'slug', so in most cases you'll just want to add

t.string :slug

to your create migration.

I'd also suggest adding a unique index on the slug field in your migration

add_index :model_name, :slug, :unique => true

Though Slug uses validates_uniqueness_of to ensue the uniqueness of your slug, two concurrent INSERTs could conceivably try to set the same slug. Unlikely, but it's worth adding a unique index as a backstop.

Once your table is migrated, just add

slug :source_field

to your ActiveRecord model. :source_field is the column you'd like to base the slug on–for example, it might be :headline.

If you want to save the slug in a database column that isn't called slug, just pass the :column option. For example

slug :headline, :column => :web_slug

would generate a slug based on headline and save it to web_slug.

The source column isn't limited to just database attributes–you can specify any instance method. This is handy if you need special formatting on your source column before it's slugged, or if you want to base the slug on several attributes.

For example:

class Article < ActiveRecord::Base
  slug :title_for_slug

  def title_for_slug
    "#{headline}-#{publication_date.year}-#{publication_date.month}"
  end
end

end

would use headline-pub year-pub month as the slug source.

From here, you can work with your slug as if it were a normal column–find_by_slug and named scopes will work as they do for any other column.

A few notes:

AUTHOR

Ben Koski, ben.koski@gmail.com

with generous contributions from: Derek Willis, @derekwillis