Luiz Wynne
Luiz Wynne

Reputation: 500

Replacing object ID by object name on URL on Laravel route

I am trying to make my URL more SEO friendly on my Laravel application by replacing the ID number of a certain object by the name on the URL when going to that specific register show page. Anyone knows how?

This is what I got so far and it displays, as normal, the id as the last parameter of the URL:

web.php

Route::get('/job/show/{id}', ['as'=>'website.job.show','uses'=>'HomeController@show']);

Controller method

public function show($id){
        $job = Job::findOrFail($id);
        return view('website.job')->with(compact('job'));
    }

Blade page where there is the link to that page

<a href="{{route('website.job.show', $job->id)}}">{{$job->name}}</a>

Upvotes: 1

Views: 3275

Answers (3)

Chin Leung
Chin Leung

Reputation: 14941

You can overwrite the key name of your Job model:

public function getRouteKeyName()
{
    return 'name';
}

Then in your route simply use {job}:

Route::get('/job/show/{job}', ...);

And to call your route:

route('website.job.show', $job);

So your a tag would look like this:

<a href="{{ route('website.jobs.show', $job) }}">{{ $job->name }}</a>

Inside your controller, you can change the method's signature to receive the Job automatically:

public function show(Job $job)
{
    return view('website.job')
        ->with(compact('job'));
}

For more information, look at customizing the key name under implicit binding: https://laravel.com/docs/5.8/routing#implicit-binding

Upvotes: 2

shushu304
shushu304

Reputation: 1498

2 options:

1) one is like @zakaria-acharki wrote in his comment, by the name of the job and search by the name for fetching the data

2) the second is to do it like here in stackoverflow

to build the url with the id/name

in this way you will make sure to fetch and show the relevant job object by the unique ID

the route:

Route::get('/job/show/{id}/{name}', ['as'=>'website.job.show','uses'=>'HomeController@show']);

in the controller, update the check if the name is equal to the job name (in case it was changed) to prevent duplicate pages url's

public function show($id, $name){
    $job = Job::findOrFail($id);

    // check here if( $job->name != $name ) {
    // redirect 301 to url with the new name
    // }

    return view('website.job')->with(compact('job'));
}

in the blade.php :

<a href="{{route('website.job.show', $job->id, $job->name)}}">{{$job->name}}</a>

Upvotes: 0

Zakaria Acharki
Zakaria Acharki

Reputation: 67525

You need simply to replace the id by the name :

Route::get('/job/show/{name}', ['as'=>'website.job.show','uses'=>'HomeController@show']);

In the controller action:

public function show($name){
    //Make sure to replace the 'name' string with the column name in your DB
    $job = Job::where('name', $name)->first();
    return view('website.job')->with(compact('job'));
}

Finally in the blade page :

<a href="{{route('website.job.show', $job->name)}}">{{$job->name}}</a>

Upvotes: 2

Related Questions