How do I change Rails routing to :contoller/:name from :controller/:id

skm376 used Ask the Experts™
I have a location model in my Rails app with a single column: name.  I'd like my routes to display like:


instead of


How do I do this?  What do I need to pass to url_for to generate this route?
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
You should use a named route.

Add the 'map.location' statement below to your config/routes.rb file, somewhere above the default entries.  When someone then tries to go to 'location/Chicago', Rails will send the request to 'your_controller/your_action', with the ':name' parameter set to 'Chicago'.  To have Rails generate that URL, you can use 'location_url' or 'location_path', and just pass in the hash {:name => "value"}.

Of course, there are some important caveats to doing this.  First, you need to have a 'validates_uniqueness_of' and 'validates_presence_of' validations on the :name column in your location model; otherwise, locations could be added which will either never be reached again, or you'll never know which one is returned.  

Also, if the controller you specify in the map.location call is 'location', then you cannot use any actions which do not require an ':id'.  For example, if you had a 'list' method in LocationController and you tried to go to 'location/list', you would really get sent to 'location/your_action' with the parameter :name => 'list'; it would try to find the location model with a name of 'list'.  Of course, the easiest workaround would be to just rename the mock controller being used, like the alternate suggested below.
I don't know what happened to the code snippet that I created for my last submission, so I'll try again.
# add to 'config/routes.rb', somewhere above the default routes
map.location 'location/:name', 
  :controller => 'your_controller', :action => 'your_action'
# alternate named route
map.location 'goto/:name', :controller => 'location', :action => 'your_action'
# examples of URL specification in a view
<%= link_to 'Memphis', location_url({:name => 'Memphis'}) %>
<%= link_to 'Columbus', location_path({:name => 'Columbus'}) %>

Open in new window

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial