Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how do I make the URL's in Ruby on Rails SEO friendly knowing a @vendor.name?

My application is in RoR

I have an action/view called showsummary where the ID has been passed into the URL, and the controller has used that to instantiate @vendor where @vendor.name is the name of a company.

I would like the URL to be, rather than showsummary/1/ to have /vendor-name in the URL instead.

How do I do that?

like image 232
AFG Avatar asked Apr 07 '09 00:04

AFG


3 Answers

All of these solutions use find_by_name, which would definitely require having an index on that column and require they are unique. A better solution that we have used, sacrificing a small amount of beauty, is to use prefix the vendor name with its ID. This means that you dont have to have an index on your name column and/or require uniqueness.

vendor.rb

def to_param
  normalized_name = name.gsub(' ', '-').gsub(/[^a-zA-Z0-9\_\-\.]/, '')
  "#{self.id}-#{normalized_name}"
end

So this would give you URLs like

/1-Acme

/19-Safeway

etc

Then in your show action you can still use

Vendor.find(params[:id])

as that method will implicitly call .to_i on its argument, and calling to_i on such a string will always return the numerical prefix and drop the remaining text- its all fluff at that point.

The above assumes you are using the default route of /:controller/:action/:id, which would make your URLs look like

/vendors/show/1-Acme

But if you want them to just look

/1-Acme

Then have a route like

map.show_vendor '/:id', :controller => 'vendors', :action => 'show'

This would imply that that it would pretty much swallow alot of URLs that you probably wouldnt want it too. Take warning.

like image 124
Cody Caughlan Avatar answered Oct 14 '22 21:10

Cody Caughlan


I thought I'd mention String#parameterize, as a supplement to the tagged answer.

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

It'll filter out hyphenated characters, replace spaces with dashes etc.

like image 36
August Lilleaas Avatar answered Oct 14 '22 23:10

August Lilleaas


Ryan Bates has a great screencast on this very subject.

Basically you overload the to_param method in the Vendor model.

   def to_param
     permalink
   end

Then when you look up the resource in your controller you do something like this:

   @vender = Vender.find_by_name(params[:id])

But the problem with this is that you'll have to make sure that the vendors' names are unique. If they can't be then do the other solution that Ryan suggests where he prepends the the id to the name and then parses the resulting uri to find the item id.

like image 31
vrish88 Avatar answered Oct 14 '22 22:10

vrish88