Можно ли использовать привязку модели маршрута с контроллерами RESTful?

#php #laravel-4 #laravel-routing

#php #laravel-4 #laravel-маршрутизация

Вопрос:

Я использую контроллеры RESTful в своем проекте Laravel. Путем включения:

 Route::controller('things', 'ThingController')
 

в моем routes.php , я могу определить функции следующим ThingController образом:

 public function getDisplay($id) {
    $thing = Thing::find($id)
    ...
}
 

так что получение URL-адреса «… things / display / 1» будет автоматически перенаправлено на функцию контроллера. Это кажется довольно удобным и до сих пор отлично работало для меня.

Я заметил, что многие функции моего контроллера начинаются с получения модели по идентификатору из URL-адреса, и я подумал, что было бы неплохо иметь возможность использовать привязку модели маршрута, чтобы сделать это для меня. Итак, я обновил свой routes.php чтобы

 Route::model('thing', 'Thing');
Route::controller('things', 'ThingController')
 

и изменил ThingController функции на

 public function getDisplay($thing) {
    ...
}
 

Я предположил, что это волшебным образом сработает так, как я хотел (как и все остальное, что я пробовал до сих пор в Laravel), но, к сожалению, я получаю «Пытаюсь получить свойство не-объекта», когда пытаюсь использовать $thing в функции. Это то, что должно работать, и я только что сделал это неправильно, или привязка модели маршрута может работать только с маршрутами, явно названными в routes.php ?

Ответ №1:

Если вы не возражаете против пути URI, имени метода и только для работы show edit и update метода, вы можете использовать контроллер ресурсов для генерации строки URI, которая может определять привязку модели.

В routes.php изменении на

 Route::model('things', 'Thing');
Route::resource('things', 'ThingController');
 

Вы можете использовать php artisan routes command для просмотра всех URI

 $ artisan routes | grep ThingController
GET|HEAD things                | things.index               | ThingController@index
GET|HEAD things/create         | things.create              | ThingController@create
POST things                    | things.store               | ThingController@store
GET|HEAD things/{things}       | things.show                | ThingController@show
GET|HEAD things/{things}/edit  | things.edit                | ThingController@edit
PUT things/{things}            | things.update              | ThingController@update
PATCH things/{things}          |                            | ThingController@update
 

После этого вы можете использовать параметр как Thing объект без явного указания маршрута.

 /**
 * Display the specified thing.
 *
 * @param  Thing  $thing
 * @return mixed
 */
public function show(Thing $thing)
{
    return $thing->toJson();
}
 

Если вы хотите получить доступ ThingController@show , передайте свой идентификатор модели, и Laravel получит его автоматически.

http://example.com/things/1

 {"id":1,"type":"Yo!"}
 

Ответ №2:

Вы можете использовать Route:resource и по-прежнему предоставлять другие методы. Поместите нужный маршрут непосредственно перед этой конкретной Route::resource строкой. Например:

 Route::model('things', 'Thing');
Route::get('things/{things}/owner', 'ThingController@getOwner');
Route::resource('things', 'ThingController');
 

Затем создайте соответствующий метод в вашем контроллере.

 public function getOwner($things) {
    return Response::json($things->owner()->get());
}
 

Вот официальная документация из документации Laravel 4.2:

Источник: http://laravel.com/docs/controllers#resource-controllers

Добавление дополнительных маршрутов к контроллерам ресурсов

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

 Route::get('photos/popular');
Route::resource('photos', 'PhotoController');