Замена идентификатора объекта на имя объекта в URL-адресе на маршруте Laravel

#php #laravel #url #laravel-blade #laravel-route

#php #laravel #url #laravel-blade #laravel-маршрут

Вопрос:

Я пытаюсь сделать свой URL-адрес более удобным для SEO в моем приложении Laravel, заменив идентификационный номер определенного объекта на имя в URL-адресе при переходе на эту конкретную страницу отображения реестра. Кто-нибудь знает как?

Это то, что я получил до сих пор, и он отображает, как обычно, идентификатор в качестве последнего параметра URL:

web.php

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

Метод контроллера

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

Блейд-страница, на которой есть ссылка на эту страницу

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

Ответ №1:

Вы можете перезаписать имя ключа вашей Job модели:

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

Затем в вашем маршруте просто используйте {job} :

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

И для вызова вашего маршрута:

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

Таким образом, ваш a тег будет выглядеть следующим образом:

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

Внутри вашего контроллера вы можете изменить сигнатуру метода, чтобы автоматически получать задание:

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

Для получения дополнительной информации ознакомьтесь с настройкой имени ключа в разделе неявная привязка: https://laravel.com/docs/5.8/routing#implicit-binding

Комментарии:

1. И как это будет работать с тегом a? Я передаю задание-> Идентификатор?

2. Нет, вы просто передаете экземпляр задания, как в маршруте.

3. @LuizWynne Посмотрите на мой обновленный ответ. Я показываю пример с тегом a.

4. Я попробую это. Большое спасибо!!

Ответ №2:

Вам нужно просто заменить на id name :

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

В действии контроллера:

 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'));
}
 

Наконец, на странице блейда :

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

Комментарии:

1. Спасибо тебе, Закария. Проблема с этим решением будет заключаться в 2 заданиях с одинаковым названием заголовка в БД, не так ли?

2. Да, это может произойти, если вам нужно уникальное значение, которое вы должны использовать id , или вы можете использовать и то, и другое в виде комбинации id-name .

3. Вам нужен образец, использующий комбинацию обоих значений, например /job/show/1-name_here

Ответ №3:

2 варианта:

1) один похож на то, что написал @zakaria-acharki в своем комментарии, по названию задания и поиску по имени для извлечения данных

2) второй способ — сделать это, как здесь, в stackoverflow

чтобы создать URL-адрес с идентификатором / именем

таким образом, вы убедитесь, что извлекаете и показываете соответствующий объект задания по уникальному идентификатору

маршрут:

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

в контроллере обновите проверку, если имя равно имени задания (в случае, если оно было изменено), чтобы предотвратить дублирование URL-адресов страниц

 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'));
}
 

в blade.php :

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

Комментарии:

1. Первый вариант будет извлекать несколько заданий с одинаковым именем в БД, а второй фактически не работал, когда я пытался

2. Отлично, это тоже мой любимый вариант, и я использую его уже давно. Вы можете проголосовать 🙂