问题
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