1

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>
Zakaria Acharki
  • 66,747
  • 15
  • 75
  • 101
Luiz Wynne
  • 460
  • 3
  • 10
  • 28

3 Answers3

2

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>
Zakaria Acharki
  • 66,747
  • 15
  • 75
  • 101
2

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

Chin Leung
  • 14,621
  • 3
  • 34
  • 58
0

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>
shushu304
  • 1,506
  • 1
  • 7
  • 15
  • The first option would retrieve multiple jobs with the same name in the DB, and the second didn’t actually work when i tried – Luiz Wynne Apr 18 '19 at 16:28
  • Great, this is my preffered option too and i am using it for a long time. You are welcome to vote up :) – shushu304 Apr 18 '19 at 16:49