What are slugs?

do I need them in my rails app?

Slugs are a colloquial term for the “SEO-friendly” identifier part of a URL. Seen a lot in applications like blogs or public sites, they turn a URL like:

https://blog.example.com/posts/123

into one like this:

https://blog.example.com/posts/clickbait-teaser-goes-here

Search engines LOVE them some anchor tags, after all, so getting all your clickbait search terms into the URL itself is one of the most powerful tools you can use to raise the ranking of your page.

The down-side of using this scheme is that you will run out of meaningful slugs, and in the case of a collision, you will end up with some disambiguation scheme like the one used in FriendlyID (the most-used tool for building these, by the way) where they just whack a UUID on to the end of the duplicates.

Give FriendlyID a look and a try, it does take a lot of the effort out of using this pattern. There is also a dead-simple way to do this, by overloading the to_param method on your model:

# in your model
def to_param
  "#{id}-#{title.parameterize}"
end

This takes advantage of the fact that the default ActiveRecord.find method takes whatever is passed to :id and turns it into a number before building a query. Any string that begins with numerals, and is cast to an integer will return all the initial numerals as an integer. So the URL, which ends up looking like posts/123-my-buzzwordy-title-here gets treated just the same as Post.find(123). This has the added benefit of both letting you change the “slug” later (as long as you keep the same id).

Walter

3 Likes

thanks.

I found friendly id and added it to my rails app.

it worked out nicely, added it to my product model.

here’s what I’m working on… https://desolate-journey-54830.herokuapp.com/

(kind of ugly isn’t it?)

If you like using concerns to organise methods, this might be the pattern to use (i have not checked if it works).

module Post::Sluggable
  extend ActiveSupport::Concern

  included do
    def to_param
       "#{id}-#{title.parameterize}"
    end
  end  
end

class Post
  include Sluggable
end

Not sure how i’d manage the routes for the slug though.