Как работают параметры маршрута / контроллера Laravel? - PullRequest
2 голосов
/ 11 октября 2019

Я понимаю, что если у меня есть маршрут, скажем, api / users / {id}, то он будет передан в функцию контроллера как параметр $ id.

Однако, если у меня есть маршрут api:

Route::patch('roadmap/{roadmapcourse}', 'RoadmapCourseController@update');

и метод контроллера:

/**
   * Update the specified resource in storage.
   *
   * @param  \Illuminate\Http\Request  $request
   * @param  \App\RoadmapCourse $roadmapcourse
   * @return \Illuminate\Http\Response
   */
  public function update(Request $request, RoadmapCourse $roadmapcourse)
  {
    $data = $request->validate([
      'user_id' => 'required|integer',
      'course_id' => 'required|integer',
      'stage' => 'required|integer',
      'title' => 'required|string',
      'creator' => 'required|string',
      'url' => 'required|string',
      'hours' => 'required',
      'completed' => 'required|boolean'
    ]);

    $roadmapcourse->update($data);

    return response($roadmapcourse, 200);
  }

Затем я отправляю запрос на http://projectname/api/roadmap/2 - тогда 2 передается как параметр функции обновления, не так ли?

Но, судя по функции обновления, он ожидает экземпляр RoadmapCourse, а не одну цифру, то есть '2'?

Неужели Laravel, за кадром, ищет запись в базе данных дляRoadmapCourse с идентификатором 2, а затем привнести это в функцию как $ roadmapcourse?

Это единственное, о чем я могу думать, и я не могу найти документацию, объясняющую, что происходит.

PS Я также не могу найти какую-либо документацию, касающуюся соглашения о присвоении имен переменных $ Class, т.е. RoadmapCourse $ roadmapcourse, я понимаю, что он делает, просто не могу найти никаких документов.

PPS Я также могуне могу найти документОбъяснение объяснения «docblocks» над методом контроллера, например,

/**
   * Update the specified resource in storage.
   *
   * @param  \Illuminate\Http\Request  $request
   * @param  \App\RoadmapCourse $roadmapcourse
   * @return \Illuminate\Http\Response
   */

И что эти объявления '@param' на самом деле для ??

Любая помощь или ссылки на документы будут оценены (япросматривал документы Laravel, но не могу найти ни упоминания, ни чего-либо из этого, поэтому отправляю сюда)

Спасибо!

Ответы [ 2 ]

1 голос
/ 11 октября 2019

За кулисами Laravel ищет запись в базе данных для RoadmapCourse с идентификатором 2, а затем вводит ее в функцию как $roadmapcourse?

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

Поскольку переменная $user имеет подсказку типа как модель App\User Eloquent, а имя переменной соответствует сегменту {user} URI, Laravel автоматически внедрит экземпляр модели с идентификатором, соответствующим соответствующему значению, из URI запроса. Если соответствующий экземпляр модели не найден в базе данных, автоматически генерируется HTTP-ответ 404.

Что касается других вопросов (обратите внимание, постарайтесь ограничить вопросы одним, кратким вопросом в будущем), имя переменной не имеет значения;$roadmapcourse может быть чем угодно, если введенная модель верна. Если вы не используете RoadmapCourse, он попытается найти модель, которую вы передадите, на основе первичного ключа (обычно id).

Для docblocks это стандартная функция комментирования. @param и @return могут быть проанализированы и отображать эти значения в документе REST API, но по умолчанию они не делают ничего, кроме предоставления визуальной ссылки. Вы можете спокойно игнорировать их, если хотите.

0 голосов
/ 11 октября 2019

Я понимаю, что если у меня есть маршрут, скажем, api / users / {id}, то он будет передан в функцию контроллера как параметр $ id.

Это потому, чтопараметр будет храниться как обычная переменная.

Однако, если у меня есть маршрут API (...) и мой контроллер выглядит следующим образом:

public function update(Request $request, RoadmapCourse $roadmapcourse) { /** ... */ }

Это не 't работает.

Это потому, что вы пытаетесь использовать привязка модели , но, учитывая имя вашей переменной (и параметр маршрута), Laravel не может разрешить правильный класс.

Если вы сделаете это вместо этого:

Route::patch('roadmap/{roadmapcourse}', 'RoadmapCourseController@update');
public function update(Request $request, $roadmapcourse)
{ //                                     ^^^^^^^^^^^^^^
    dd($roadmapcourse); // you'll get the value
}

Конечно, вы можете указать laravel правильно разрешить переменную пути для получения записи из вашей базы данных. Для этого вам необходимо настроить Explicit Binding . Из документов:

Явная привязка

Чтобы зарегистрировать явную привязку, используйте метод model маршрутизатора, чтобы указать класс для данного параметра. Вы должны определить явные привязки модели в методе boot класса RouteServiceProvider:

public function boot()
{
    parent::boot();

    Route::model('user', App\User::class);
}

Далее определите маршрут, который содержит параметр {user}:

Route::get('profile/{user}', function (App\User $user) {
    //
});

Итак, в вашем случае попробуйте следующее:

# app/Providers/RouteServiceProvider.php

public function boot()
{
    parent::boot();

    Route::model('roadmapcourse', App\RoadmapCourse::class);
}

В этот момент Laravel сможет определить параметры вашего маршрута:

Route::patch('roadmap/{roadmapcourse}', 'RoadmapCourseController@update');
...