Home > OS >  Use Explicit or Implicit Model Binding on Routes in Laravel Package
Use Explicit or Implicit Model Binding on Routes in Laravel Package

Time:06-16

I am migrating some app functionality into a Laravel package. The package includes Models, Controllers and routes. I am using Laravel 9

Everything is working except my Models are not biding to the routes so the models are not being automatically resolved.

// Route
Route::get('/medium/{medium}', 
    [\ArtMoi\Http\Controllers\MediumController::class, 'fetch']
)->name("get-medium");

Model does not automatically load. In the controller below $medium is null. Route worked when part of the app, but fails when included via a package.

// MediumController
use ArtMoi\Models\Medium;
...
public function fetch(Request $request, Medium $medium)
{
    $this->authorize('view', $medium);
    return response()->json($medium);
}

Everything works if I don't try to automatically load the model

// This works but not the desired approach
use ArtMoi\Models\Medium;

public function fetch(Request $request, $id)
{
    $medium = Medium::find($id);
    $this->authorize('view', $medium);
    return response()->json($medium);
}

In my package ServiceProvider I provide the routes with

public function boot() 
{
    Route::group(['prefix' => 'api'], function () {
        $this->loadRoutesFrom(__DIR__ . '/../routes/api.php');
    });
}

I tried to explicitly bind the Model and the route by adding the following to a RouteServiceProvider but it has no effect.

// RouteServiceProvider.php
use ArtMoi\Models\Medium;
... 
public function boot()
{
    Route::model('medium', Medium::class);   
}

This is the first time I've moved resource type routes to a Package and feel like there is something I am missing. The only difference with the package from the original app is moving models from App\Models to the package namespace of ArtMoi\Models. Models function as expected when performing queries or other functions and the routes have no conflicts.

CodePudding user response:

Can you test this solution? Modify your boot method.


    public function boot() 
    {
        Route::group([
             'middleware'=>['bindings'],
             'prefix' => 'api'
             ], function () {
            $this->loadRoutesFrom(__DIR__ . '/../routes/api.php');
        });
    }

That bindings middleware is here and is registered by default in web and api middleware.

Solution found here

I hope this works, I didn't test it.

CodePudding user response:

Found that I needed to add the SubstitudeBindings middleware to my routes.

Updated my ServiceProvider to load routes with

use Illuminate\Routing\Middleware\SubstituteBindings;
...
public function boot() 
{
    Route::group(['prefix' => 'api', 'middleware' => [SubstituteBindings::class]], function () {
        $this->loadRoutesFrom(__DIR__ . '/../routes/api.php');
    });
}
  • Related