Can route model binding be used with RESTful controllers?

僤鯓⒐⒋嵵緔 提交于 2020-08-19 06:33:08

问题


I have been using RESTful controllers in my Laravel project. By including:

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

in my routes.php, I can define functions in the ThingController like:

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

so that GETting the URL "...things/display/1" would automatically be directed to the controller function. This seems pretty handy and has been working great for me so far.

I noticed many of my controller functions start with getting a model by id from the url, and I thought it would be nice to be able to use route model binding to do this for me instead. So I updated my routes.php to

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

and changed the ThingController functions to

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

I assumed this would magically work the way I wanted it to (like everything else I've tried so far in Laravel has) but unfortunately I get "Trying to get property of non-object" when I attempt to use $thing in the function. Is this something that should be able to work and I have just done it wrong, or can route model binding only work with routes explicitly named in routes.php?


回答1:


If you don't mind with URI path, method name and just work only show, edit and update method, you can use Resource Controller to generate URI string which can define model binding.

In routes.php change to

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

You can use php artisan routes command to see all URIs

$ 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

After that you can threat parameter as Thing object without explicitly name route.

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

If you want to access ThingController@show, pass your model ID and Laravel will retrieve it automatically.

http://example.com/things/1

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



回答2:


You can use Route:resource and still provide other methods. Place the route you need just before that particular Route::resource line. Eg:

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

Then create the corresponding method in your controller.

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

Here is the official documentation from the Laravel 4.2 docs:

Source: http://laravel.com/docs/controllers#resource-controllers

Adding Additional Routes To Resource Controllers

If it becomes necessary for you to add additional routes to a resource controller beyond the default resource routes, you should define those routes before your call to Route::resource:

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


来源:https://stackoverflow.com/questions/24397660/can-route-model-binding-be-used-with-restful-controllers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!