Search Engine Friendly Rails Routing

Snippet Ruby on Rails

Last updated Feb 16, 2016

Search engine friendly URLs, or slugs, or permalinks, are not as straightforward as one might think. In this lesson, I am going to cover two different methods for creating readable, search friendly URLs in rails. There are some limitations to each of these methods, which will be discussed throughout the lesson.

Lesson Resources

Lesson Checkpoints

A Video Tutorial for SEO Friendly Rails Routing

The Easy Way

In the model, we can override the default parameters with the to_param method. We call the parameterize method on the object’s name attribute, which converts “My Pet Turtle!!!” to “my-pet-turtle”. The end result is a url that is formatted like: /123-my-pet-turtle.

def to_param
  "#{id}-#{name.parameterize}"
end

That’s it, there’s no other code that needs to be changed in the application. Your existing controller methods that use Model.find(params[:id]) will still work because they will only extract the initial id number. This is decent, but it would still be nice to have the URL completely free of the ID number. Let’s start over to make this happen.

The Hardish Way Part 1

I call this the hardish way because it’s relatively complicated compared to the easy way, but it’s still quite easy overall. We’re going to create a new permalink attribute for the Post model that will serve as our URL.

$ rails g migration AddPermalinkToPost permalink:string

$ rake db:migrate

The Hardish Way Part 2

In the model, we are going to use an ActiveRecord callback to set the permalink before the record is created. First, we need to define a generate_permalink method, which uses a Post object's title and converts it to a url friendly format. Then we override the to_param method and set it equal to the object's permalink attribute.

It is important to only run the callback on the create action, otherwise the permalink will change if the title attribute is updated. If Google has already indexed that URL, it will direct visitors to a 404 error page.

models/post.rb

before_validation :generate_permalink, on: :create

def generate_permalink
  self.permalink = self.title.parameterize
end

def to_param
  permalink
end

The Hardish Way Part 3

Now that the ID is totally stripped from the URL, we need to tell rails to search for a different parameter. In the controller, we will need to use the find_by_permalink helper method. Note, the params hash will still have a key of “id”, such as {:id => “my-pet-turtle” }

controllers/posts_controller.rb

def set_post
  @post = Post.find_by_permalink(params[:id])
end

Comments