laravelroute-model-binding

Laravel Slugable Route Model Binding weird behaviour


I have a section in my project with the latest news articles. For this I have a:

  1. Post model
  2. Post resource controller and a
  3. Resource Post Route.

Post Model

class Post extends Model
{
    use HasFactory, Sluggable;

    protected $fillable = [...,...];

    public function getRouteKeyName()
    {
        return 'slug';
    }

    public function sluggable(): array
    {
        return [
            'slug' => [
                'source' => 'title'
            ]
        ];
    }
}

PostController.php

public function show(Post $post)
{
    dd($post);
}

web.php

Route::resource('/posts', App\Http\Controllers\PostController::class)->only(['index','show']);

Index (http://localhost/news) and show (http://localhost/news/{slug}) work as expected!

Now the problem/bug I noticed:

When I change the route from posts to news, the show method no longer works. Index still works.

the modified route from posts to news

Route::resource('/news', App\Http\Controllers\PostController::class)->only(['index','show']); 

http://localhost/news works but http://localhost/news/{slug} shows me only the PostModel Structure.

Do you know the problem and what do I have to do to make it work? I use Laravel 8 and "cviebrock/eloquent-sluggable": "^8.0" packagefor the slugs. Thanks for your time!


Solution

  • Ok. I've figured it out. I'm writing the answer here for anyone who might have the same problem as me. First of all. It is not a bug. If you adjust the route so that the model name is no longer included in the route, then you have to bind the route explicitly. https://laravel.com/docs/8.x/routing#explicit-binding

    All you have to do. In the boot() method of RouteServiceProvider.php, add the desired route and bind it with the desired classes. In my case it was news instead of post.

    public function boot()
    {
        ....
        Route::model('news', \App\Models\Post::class);
    }