Gem Idol: Friendly Id

This week, I would like to introduce a gem which is being used in almost every project I have been working on. And it becomes more important for us nowadays because everyone want their website to be SEO efficiently.

Link: https://github.com/norman/friendly_id
Developed by: Norman Clarke and Adrian Mugnolo

When to use

Rails is based on RESTful architecture. And by default, as you have noticed, resources will be accessed with the ID in the URL like this

/posts/1 -> show
/posts/1/edit -> edit

We can say that this URL is not friendly, because users can not guess the meaning of that URL. It would be great if the users can look at the URL and tell what the content of that link is. And if you pay attention, you would see that many blogs or websites are taking advantage of this method. They want their websites to be friendly to the users and make their websites be more professional.

Friendly_id is a gem which allows you to replace the ID in the URL with a more friendly URL. This custom value is often generated from a certain field on the table. For example, instead of using /posts/1, you can use something like /posts/first-post-on-sunday in the URL. You can see that it is now much more friendly than the boring ID. The string first-post-on-sunday is called the slug

How to use

The setup is very easy, you just need to specify which column in the database contains the string that will be used as slug. In the following code, I make the slug based on the title field of Post model

class Post < ActiveRecord::Base
  extend FriendlyId

  friendly_id :title, use: :slugged
end

History for Slug

By default, the slug will only be generated once and it will not be changed even when the corresponding field is updated. This is to prevent the issue that the URL becomes invalid after updating the model. For example, let say that we have a Post model with the following attributes

post.title = "This is my first post"

and the generated slug is this-is-my-first-post

If you change the title of this post to Updated: This is not a first post, the slug is still this-is-my-first-post. And any users with the old slug can still access the post. You can of course change this behavior by overriding the method should_generate_new_friendly_id? in your model

class Post < ActiveRecord::Base
  extend FriendlyId

  friendly_id :title, use: :slugged
  
  def should_generate_new_friendly_id?
    slug.blank? || title_changed?
  end
end

But I also highly recommend you to turn on history for the slug so that the user can still visit the old link after the slug has been regenerated. To turn on history, replace the current friendly_id config with this

friendly_id :title, use: [:slugged, :history]

Notes

friendly_id has changed their API for a few times. In friendly_id 4, the find method is overridden and you can find a record through the slug like this

Model.find(params[:slug])

However, this does not work in Friendly_id 5. And you need to do things like this

Model.friendly.find(params[:slug])

But this is a problem if your application has already used Friendly_id 4 and needs to be upgraded to 5. Luckily, friendly_id provides finders feature to support backward compatibility

friendly_id :title, use: [:slugged, :finders] 

Conclusion

Friendly URL is a very good way to show the professional in your application. And with the support of Friendly_id, everything becomes much easier for Rails developer. Try it out today.