storing seo frendly url in column
Ruby
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
db
gemfiles
lib
spec
.gitignore
.rspec
.rvmrc
.travis.yml
Appraisals
Gemfile
LICENSE.txt
README.md
Rakefile
changelog.md
slugable.gemspec

README.md

Slugable

Build Status Gem Version Code Climate Test Coverage

  • adds support for creating seo friendly url to your active record models and simplifies generating url
  • gem is tests against rails 3.2, 4.0, 4.1, 4.2 and ruby 1.9.3. and 2.2.2
# model
class Article < ActiveRecord::Base
  # has columns: id, name, slug
  has_slug
end

# creating new
item = Article.create!(name: 'First article')
item.slug # => 'first-article'
item.to_slug # => 'first-article'

# routes to the article
get "articles/:slug" => "articles#show", as: :article

# view
link_to 'My first article', article_path(item.to_slug) # => '/articles/first-article'

Installation

Add this line to your application's Gemfile:

gem 'slugable'

And then execute:

$ bundle

Or install it yourself as:

$ gem install slugable

Usage

  • default configuration converts name column to slug column and formatted by parameterize method from active support
  • it internally use callbacks to do the job
  • it also adds several convenient methods for generating url parts to_slug, to_slug_was, to_slug_will
class Item < ActiveRecord::Base
  # columns :name, :slug

  has_slug # default from: :name, to: :slug
end

# then in code
item = Item.create!(name: "my name is")
item.slug # => "my-name-is"

item.to_slug # => "my-name-is"

item.slug = "new-slug"

item.to_slug_was  # => "my-name-is"
item.to_slug_will # => "new-slug"
item.to_slug      # => "new-slug"

you can override defaults by passing hash

class Page < ActiveRecord::Base
  # has columns: :id, :title, :seo_url

  has_slug from: :title, to: :seo_url, formatter: lambda { |string| string.downcase }
end

# then in code
page = Page.create!(title: "NAME")
page.seo_url # => "name"
page.to_seo_url # => "name"

if model is a tree structure and you use ancestry gem, tree like structure will be generated

class Category < ActiveRecord::Base
  # has columns: :id, :name, :slug

  has_ancestry
  has_slug
end

# then in code
root = Category.create!(name: "root", slug: "root")
root.slug # => "root"
root.to_slug # => ["root"]

child = Category.new(name: "child", slug: "child")
child.parent = root
child.save!

child.slug # => "child"
child.to_slug # => ["root", "child"]

branch = Category.create!(name: "branch", slug: "branch")
child.parent = branch
child.slug = "renamed"

child.to_slug_was # => ["root", "child"]
child.to_slug_will # => ["branch", "renamed"]

child.to_slug # => ["root", "child"]
child.save!
child.to_slug # => ["branch", "renamed"]
  • You can cache slug for tree structure if you want to optimize performance, all you need is to pass cache storage object
class Category < ActiveRecord::Base
  # has columns: :id, :name, :slug

  has_ancestry
  has_slug tree_cache_storage: Rails.cache
end

Configuration

You can set up default formatter and default tree_cache_storage in you initializer.

class MyFormatter
  def self.call(string)
    string.my_own_parameterize
  end
end

Slugable.configure do |config|
  config.formatter          = MyFormatter
  config.tree_cache_storage = Rails.cache
end

to_slug, to_slug_was and to_slug_will methods are implemented by to_slug_builder. You can implement you own one and pass as configuration

# you own to slug builder
class StupidToSlug
  def to_slug(record)
    "to_slug_#{record.id}"
  end

  def to_slug_was(record)
    "to_slug_was_#{record.id}"
  end

  def to_slug_will(record)
    "to_slug_will_#{record.id}"
  end
end

# model
class News < ActiveRecord::Base
  # columns: :id, :name, :slug

  has_slug to_slug_builder: StupidToSlug.new
end

# code
news = News.create!(name: 'whatever')
news.to_slug      # => "to_slug_#{news.id}"
news.to_slug_was  # => "to_slug_was_#{news.id}"
news.to_slug_will # => "to_slug_will_#{news.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