Creating slug URLs in Rails without gems

Yassir Hartani
2 min readApr 23, 2018

In this article we will use a human readable URL instead of id’s , so instead of having an awful url like http://localhost:3000/articles/114 wouldn’t http://localhost:3000/articles/114-creating-slug-urls-in-rails-without-gems be better ? So

First add slug to the table

> rails generate migration AddSlugToArticles slug:string

run the migration

> rake db:migrate

Next create a method to generate the slug

#app/model/article.rbclass Article < ApplicationRecord privatedef set_slug
self.slug = title.to_s.parameterize
end

The parameterize method replace the special characters with hyphens

> "Creating slug URLs in Rails without gems".to_s.parameterize
=> "creating-slug-urls-in-rails-without-gems"

Then ensure that set_slug is called in create and update by adding

#app/model/article.rbclass Article < ApplicationRecord
after_validation :set_slug, only: [:create, :update]
.
.
.
end

If you already have created records you can run this commands

> articles = Article.all
> articles.each do |article|
> article.update(slug: article.title.parameterize)
> end

Finally override Rails default to_param method

To generate the slug we should force Rails to use both slug and ids instead of just the ids by overwriting the to_param method

#app/model/article.rbclass Article < ApplicationRecord
after_validation :set_slug, only: [:create, :update]
def to_param
"#{id}-#{slug}"
end
.
.
.
end

Note : We used the id with the slug in order to have a better performance because the id column are normally unique and indexed .

Now we can find the record just by id and have a beautiful url, that’s work because in rails find_by_id call to_i method and ruby only casts all numeric characters

> "114-creating-slug-urls-in-rails-without-gems".to_i
=> 114

Conclusion

if you want to clean your URLs, without hitting the performance, this strategy will work for you.

Thanks for reading!

Feel free to leave a comment below or reach out to me on Twitter

--

--