Reputation: 388
I'm using resource controllers in my laravel app and I'm trying to use dependancy injection but it's not working on a particular model and controller.
This works:
/**
* Display the specified resource.
*
* @param \App\Booking $booking
* @return \Illuminate\Http\Response
*/
public function show(Booking $booking)
{
return $booking;
}
But for some infuriating reason this doesn't:
/**
* Display the specified resource.
*
* @param \App\SchoolEvent $schoolEvent
* @return \Illuminate\Http\Response
*/
public function show(SchoolEvent $schoolEvent)
{
return $schoolEvent;
}
My Routes look like this:
// Events
Route::resource('events', Resources\SchoolEventController::class);
// Bookings
Route::resource('bookings', Resources\BookingController::class);
For some reason /bookings/1 returns a filled object but /events/1 returns an empty one. Can anyone tell me why?
Upvotes: 14
Views: 8603
Reputation: 9161
Change the injected variable name to $event
to match the route parameter name {event}
:
public function show(SchoolEvent $event)
You can see the route parameters with this command:
php artisan route:list
Upvotes: 28
Reputation: 529
When you use Route::resource, this will automatically generate all routes and the name for parameters that comes into each route.
To know what is the name, run php artisan route:list
at your terminal. After that you will see the name that each route is waiting. Use this name into your Controller.
In your case, probably will be $school_event.
If you doesn't like the name you can use parameters function like this:
Route::resource(**'events'**, Resources\SchoolEventController::class)
->parameters([
**'events'** => 'here_the_name_you_want'
]);
Work on Laravel 5.5!
Reference: https://laravel.com/docs/5.5/controllers#restful-naming-resource-route-parameters
Upvotes: 0
Reputation: 11
There is another possible solution.
As has been explained Laravel tries to inject an instance, but there is a mismatch between the URI segment name and the variable.
Laravel allows to explicitly bind a Model to a slug in the RouteServiceProvider within the boot() method.
In your case:
public function boot()
{
parent::boot();
// binds the slug event to our SchoolEvent model
Route::model('event', \App\SchoolEvent::class);
}
See: https://laravel.com/docs/5.4/routing#explicit-binding
I feel both solutions are viable, but personally prefer this one. All non-default slugs are in one place rather than in the individual controllers and I keep using artisan to quickly generate the basic controller code.
Upvotes: 1
Reputation: 163768
Change the model name to Event
to make model binding work.
Since the
$user
variable is type-hinted as theApp\User
Eloquent model and the variable name matches the{user}
URI segment, Laravel will automatically inject the model instance that has an ID matching the corresponding value from the request URI
Upvotes: 5