Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel Model not binding in controller method

I have a Laravel model PurhaseOrder and a controller PurchaseOrdersController with a method show

If I typecast the method with an an interger:

public function show(int $purchaseOrder)
{
        dd(PurchaseOrder::find($purchaseOrder));
}

Then dd() dumps out what I expect ( the record in the database where the id matches $purchaseOrder)

However if instead I do this:

public function show(PurchaseOrder $purchaseOrder)
{
        dd($purchaseOrder);
}

Then $purchaseOrder is an empty model and not populated with any data from the database. My route looks like this:

Route::get('purchase-orders/{purchase_orders}/show', ['as' => 'admin.purchase-orders.show', 'uses' => 'PurchaseOrdersController@show']);

This is code that I've inherited and I'm trying to update from Laravel 5.3 to Laravel 5.6. Where should I be looking to solve this issue of the model not being populated correctly?

like image 244
ChronoFish Avatar asked Jun 14 '18 23:06

ChronoFish


1 Answers

The implicit model binding requires you to match the variable name with the route parameter name, so for example, for the following method:

public function show(PurchaseOrder $purchaseOrder)
{
    dd($purchaseOrder);
}

The route should contain the matching parameter name, for example:

Route::get('purchase-orders/{purchaseOrder}/show', [
    'as' => 'admin.purchase-orders.show',
    'uses' => 'PurchaseOrdersController@show'
]);

Notice that, the method parameter name in show method which is $purchaseOrder and the route parameter name {purchaseOrder} both are same and that's a requirement for the implicit model binding, otherwise you have to do an explicit model binding, where you've to explicitly tell the framework about your parameter name, for example (in RouteServiceProvider):

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

    Route::model('purchase_orders', App\PurchaseOrder::class);
}

This will tell the framework that, if there is the {purchase_orders} parameter name available in the route then resolve/bind an instance of PurchaseOrder model into the given method for that route.

like image 158
The Alpha Avatar answered Nov 10 '22 05:11

The Alpha