Laravel 8: Как я могу сделать неявно связанный с моделью параметр маршрута необязательным вместо 404?

#php #laravel #routes #laravel-8

#php #laravel #маршруты #laravel-8

Вопрос:

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

файл маршрутов:

 
Route::get('go/{example?}', [ExampleController::class, 'click'])->name('example');
  

И в контроллере:

 public function click(Example $example = null)
{
    // Execution never reaches here
} 
  

Выполнение никогда не достигает контроллера, если нет примера с правильным slug, поскольку он выдает 404. Я хочу проверить, является ли $example значение null в контроллере, и использовать там пользовательскую логику. Как это можно сделать?

Ответ №1:

Попробуйте это

 Route::get('go/{example?}', [ExampleController::class, 'click'])->name('example');
  
 public function click($example)
{
    if($example != null){
        $example = Example::findOrfail($example);
    }

    
}
  

при привязке модели он автоматически запускается findOrfail к этой модели, так что не так ли, чтобы у вас был контроль над ним, тогда вы можете управлять

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

1. Это работает. Я надеялся сохранить подсказку типа и привязку модели маршрута. Вы говорите, что нет способа настроить Laravel на поиск вместо findOrFail?

2. @Menasheh да, потому что по умолчанию Laravel использует findOrFail привязку к модели

3. @Menasheh да, вы можете переопределить findOrFail, явно объявив свою собственную привязку к модели, см. Эту ссылку: laravel.com/docs/8.x/routing#customizing-the-resolution-logic

Ответ №2:

ответ @ettdro идеален (и вся заслуга в нем), но я думаю, что ответ с фактическим кодом был бы полезен:

маршруты:

 Route::get('go/{example?}', [ExampleController::class, 'click'])->name('example');
  

контроллер:

 public function click(Example $example)
{
    // Stuff
} 
  

Модель примера:

  /**
 * Retrieve the model for a bound value.
 *
 * @param  mixed  $value
 * @param  string|null  $field
 * @return IlluminateDatabaseEloquentModel|null
 */
public function resolveRouteBinding($value, $field = null)
{
    $result=$this->where('id', $value)->first();
    return ($result)?$result:new Example();
}
  

Вы должны всегда получать в контроллере допустимый объект, пустой или нет.

Была такая же проблема, и я доволен этим решением.

Ответ №3:

Для этого вам нужно использовать ‘id’ в качестве первичного ключа в базе данных и модели,

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

 Route::get('go/{example:number?}', [...]);
  

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

1. Как это поможет?