I have a category model and I’m routing it using the default scaffolding of resources :categories. I’m wondering if there’s a way to change the paths from /category/:id to /category/:name. I added:
match "/categories/:name" => "categories#show"
above the resources line in routes.rb and changed the show action in the controller to do:
@category = Category.find_by_name(params[:name])
it works, but the ‘magic paths’ such as link_to some_category still use the :id format.
Is there a way to do this? If this is a bad idea (due to some possible way in which rails works internally), is there another way to accomplish this? So that /categories/music, for example, and /categories/3 both work?
Rails has a nifty model instance method called
to_param, and it’s what the paths use. It defaults toid, but you can override it and produce something like:For more info, check the Rails documentation for to_param.
EDIT:
When it comes to category names which aren’t ideal for URLs, you have multiple options. One is, as you say, to
gsubwhitespaces with hyphens and vice versa when finding the record. However, a safer option would be to create another column on the categories table calledname_param(or similar). Then, you can use it instead of the name for, well, all path and URL related business. Use theparameterizeinflector to create a URL-safe string. Here’s how I’d do it: