← Back to Upcase

How to remove id from url


(Acandael Acandael) #1

Hi,

I’m working on a Rails app for a cosmetologist:

http://178.62.173.211

my repository is here: https://github.com/acandael/beautysalonapp2

I created a Treatment model, wich belongs to a Category.

Then in my menu bar, I have a menu link for each Treatment category:

‘gelaatsverzorgingen’, ‘make-up’, ‘lichaamsbehandelingen’, …

(sorry guys, it’s in Dutch, translated, it means something like ‘facial treatments’, ‘make-up’, ‘body treatments’)

Then I defined routes for this:

get 'gelaatsverzorgingen/:category_id', to: 'treatments#index', as: 'gelaatsverzorgingen'
get 'make-up/:category_id', to: 'treatments#index', as: 'makeups'
get 'lichaamsbehandelingen/:category_id', to: 'treatments#index', as: 'lichaamsbehandelingen'

this results in url’s like:

http://localhost:3000/gelaatsverzorgingen/1
http://localhost:3000/make-up/2
http://localhost:3000/lichaamsbehandelingen/3

as you can see, the category_id is appended at the end of each url.

So my question is, if there is a way to get rid of this category_id at the end of the url’s, for human-friendly url’s and seo purposes, while still sending over the category_id to the TreatmensController, so I can have url’s like:

http://localhost:3000/gelaatsverzorgingen
http://localhost:3000/make-up
http://localhost:3000/lichaamsbehandelingen

thanks for your advice,

Anthony


(Acandael Acandael) #2

Found a solution:

Instead of a category_id, I’m using a the name of the category as a section key:

  get '/:category', to: 'treatments#index', as: 'category'

then I just needed to adapt the treatments#index method, so that it finds the category, based on the category name, instead of the id:

  def index
    @category = Category.find_by_name(params[:category])
    @treatments = Treatment.all.where(category_id: @category.id)
  end

this way, I can create a link like so:

<%= link_to "Gelaatsverzorgingen", category_path("gelaatsverzorging") %>

which results in a more human friendly url:

http://localhost:3000/gelaatsverzorgingen

(Brian Dear) #3

Glad you found your own solution! That’s similar to how I would have done it. I use something similar in a little app I’m making. I don’t want users to be be able to access “transactions” based on the ActiveRecord ID. So I’ve created a SecureRandom number, that’s saved in the db, then instead of doing exactly what you did, I just have the transaction looked up from that random number instead of the id. So this /transactions/2 becomes this: transactions/4949482-4829819842-28394-323423

So that makes it close to impossible for someone to look at a record they shouldn’t see (while keeping the URL publicly accessible.

the gem friendly_id is also really good for dealing with slugged urls.

Nice work!


(Acandael Acandael) #4

Hi briandear,

thanks for your feedback. Actually afterwards, I needed to tweak my route a bit, as it was munching everything as a ‘category’ parameter.

So now I use this route:

get 'behandelingen/:category_id', to: 'treatments#index', as: 'behandelingen'

with ‘behandelingen’ being Dutch for ‘treatments’

which leads to url’s like

http://localhost:3000/behandelingen/gelaatsverzorgingen
http://localhost:3000/behandelingen/make-up
...

which makes sense as well.

greetings,

Anthony