Gbever's avatar

Dynamic Routing with Slugs

I am creating a directory that lists professionals with SEO friendly URLs. An example would look something like this:

/professionals/state-name-slug/city-name-slug/professional-name-slug/professional-id

So far nothing unusual. Currently in my routing I pass each url subdirectory after /professionals as a dynamic parameter, so you could imagine that my route looks like this:

Route::get('/professionals/{stateSlug}/{citySlug}/{nameSlug}/{professional}')->name('show-professional')

I'm realizing that this is problematic. Because I want to show my urls with the state name instead of the abbreviation, and the very large database I'm using stores the abbreviation with the professional. Because of this, I am doing a look up each time from my states table to get that state name slug, which seems unnecessary and wasteful.

What I would like to do is store the professional's "full slug" with his/her record, so the slug stored on the professional would look like

$professional->slug == '/state-name-slug/city-name-slug/professional-name-slug/'

Then I would simply look them up by the ID at the end of the full url:

/{fullSlug}/{professional} 

After I make this switch, I realized that Laravel expects either more or less variables to be passed to the route. Since {fullSlug} is actually multiple sub directories, I get errors. What I am trying to figure out is can I let Laravel know that all of the sub directories before the id are just vanity / dynamic?

0 likes
3 replies
mstrauss's avatar

@gbever

There are some helpful options for you in this SO thread.

But, in reality that may add extra confusion to your routes file and it will certainly decrease its readability. So instead of hitting the DB each time to lookup the state name based on the abbreviation, maybe just add a method with a lookup in a helper type file, if that makes sense.

1 like
Snapey's avatar
Snapey
Best Answer
Level 122

You can still accept those parameters as if you were going to use them.

Keep the URL like

Route::get('/professionals/{stateSlug}/{citySlug}/{nameSlug}/{professional}')->name('show-professional')

but just pass a large part of it direct from the slug.

It might mean that the route() helper has difficulties so you might not be able to use that

1 like
Gbever's avatar

Thank you, actually both of these are really good ideas I hadn't thought of, and I'm thinking I can use both concepts in my app. I hadn't thought about just dropping the urls into the template vs using the route() helper. I can also use a look up table to convert the state where I need to use the full name like in the meta titles.

Please or to participate in this conversation.