HighOnRails
HighOnRails

Reputation: 43

How to create a custom route for show action in rails 5?

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

Answers (2)

Mark Swardstrom
Mark Swardstrom

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

Mark Swardstrom
Mark Swardstrom

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

Related Questions