SEO urls on the cheap
RESTful rails apps don’t necessarily make your urls that friendly if you end up with
http://www.zombification.net/posts/1
An id isn’t very descriptive of the content of the post. The quick fix for was is to add the method Post#to_param
class Post < ActiveRecord::Base validates_presence_of :title validates_presence_of :content def to_param return "#{self.id}-#{self.slug}" end def slug return self.title.clone.downcase.gsub(' ','-') end end
to_param is defined in ActionController::Routing and is used when generating urls with link_to, etc, but only when you specify the object and not the id itself.
link_to :controller => 'posts', :action => :show, id => @post
If you use name routes this is all taken care of for you. At this point all the links for @post will be the more meaningful URL
http://www.zombification.net/posts/1-nested-transactions
This is not the whole story however, this works with minimal effort because when we get our post object back Post#find(params[:id]), params[:id] will be ‘1-nested-transactions’. However, ActiveRecord::Base#find calls #to_i, on the single argument. So as long as the id of the post in params[:id] appears first the result from ActiveRecord will be the same.
rob@rob-laptop:~/src/zombification$ ./script/console Loading development environment (Rails 2.1.0) >> Post.find('1-random-meaningless-string') => #<Post id: 1, title: "nested transactions", content: "After an hour of head banging, well....banging our ...", published_at: nil, created_at: "2008-07-29 16:40:35", updated_at: "2008-08-16 07:51:57">
Hey presto slightly more SEO urls. Ok you still have the id floating about which is a little ugly but its certainly better.