Reputation: 43
I have a model 'Item'. It all works fine, however am not completely satisfied with its show path. I want to use certain parameters from items table to construct a more SEO friendly url. So here is my question..
How can I change my Show action url from 'mysite.com/items/1' to 'mysite.com/items/item-name/item-city/item-id' where item-name, item-city, and item-id are dynamic for each specific item.
Is it possible to achieve this without a gem? if yes, how? If no, which gem would you suggest to achieve this in simplest way?
Thanks
Upvotes: 2
Views: 2835
Reputation: 18100
One approach to this problem is to use route globbing:
http://guides.rubyonrails.org/routing.html#route-globbing-and-wildcard-segments
You should be able to do something like this:
get 'items/*names/:id', to: 'items#show', as: :item_names_path
And put whatever you want in *names
. This would take a little experimentation to get it right. I might add a method to item to create the names
array.
def names
[city.name, name].uniq.compact
end
Then I believe you would call item_names_path(@item.names, @item)
Upvotes: 3
Reputation: 18100
You can do something relatively simple and stays true to Rails by adding a to_param
method to your model like so:
def to_param
"#{id}-#{name}-#{city.name}"
end
What this does is every time you use a method like the item_path
, it will use the @item.to_param method (this is what it does now, and returns :id). Generating the normal route, but replacing the :id param with the SEO friendly one.
And, on the other end, when you go to find(params[:id]) in the controller in your show, edit, delete, or update actions, it will to a to_i
on it and turn it back into an id. This is what it does now, but to_i on an int is still an int.
Your urls will look something like
/items/56-boston-itemname
The other benefit to this, if you happen to change the item name or the city name, it will change all the urls appropriately, but old urls that were sent in email will still work.
Upvotes: 1