Slugs or permalinks are a common feature of blogging applications—instead of accessing data on your site with URLs like
http://mygreatrubybookstore.com/books/349 you can point users (and search engines) to pretty URLs like
http://mygreatrubybookstore.com/books/pragmatic-ruby. And slugs aren’t just for blog applications! I use these techniques liberally in my applications to add a little polish and usability. Group names, user profiles, and other models are fair game. This is an easy feature to implement, whether you’re using one of several available Ruby gems. You can even roll your own if you’d like. Read on to get started.
I have the most experience with FriendlyId. It’s easy to install and configure, is under active development, includes thorough documentation, and overall has a good balance of features to simplicity. In addition to creating nice URLs, FriendlyId also handles reserved words like
edit (you can add your own, too); non-unique slugs; caching; and scoped slugs (which I haven’t had a need for yet).
Let’s say you’ve got an existing Book model, and you want to add FriendlyId to it. Install the gem to get started, then run the generator and, optionally, a migration to generate a cached version of the slug string to speed up queries:
And finally configure your model to have a friendly ID:
If you’re adding FriendlyId to a model that already has some records stored in the database, and are using the cached slug option, you’ll need to run the following rake task to create slugs for existing data:
Restart your application server and you’re ready to go.
ActsAsUrl, part of the Stringex collection of extensions to Ruby’s String class, may be more beneficial to you if you need better Unicode support (as in, you want to translate common Unicode characters into more search-friendly terms). Check the README for some of the slick translations ActsAsUrl can do. You’ll have to do a little more work‐once you’ve indicated your model’s attribute for
acts_as_url, you’ll need to override
to_param. This isn’t too hard, but it’s also not as turnkey as FriendlyId. If you need that translation support, though, ActsAsUrl should be worth the extra effort.
You might also take a look at Babosa, a FriendlyId derivative that lets you do things like convert strings to Ruby methods. I actually could have used that for a project I currently maintain at work.
I’m including the venerable permalink_fu because it was an early and popular solution to this problem. I used this plugin in some of my own early-ish Rails projects. It doesn’t appear to be in current development, though, and lacks some of the features of more current projects like FriendlyId and ActsAsUrl.
Finally, I should acknowledge that yes, you can easily do this yourself in your model, by creating a method for the slug (probably using Rails’
parameterize method) and overriding
to_param to do lookups based on the slug instead of the
id column. The benefit of a gem like one of these I’ve listed, though, is that you can apply slugs to as many different models in your application as you’d like, with minimum code duplication, and be able to focus on features more unique to your own project.
If you liked my series on practical advice for adding reliable tests to your Rails apps, check out the expanded ebook version. Lots of additional, exclusive content and a complete sample Rails application.
Ruby on Rails news and tips, and other ideas and surprises from Aaron at Everyday Rails. Delivered to your inbox on no particular set schedule.