Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change Route Model Binding finding data from id to slug

I have a route like the following.

Route::get('/articles/{articleSlug}' , 
    [App\Http\Controllers\ArticleController::class, 'single']);

And the method of single() at ArticleController class goes here:

public function single($slug)
{
    $article = Article::where('slug',$slug)->first();
    $article->increment('viewCount');

    return view('home.article',compact('article'));
}

Now I wish to use Route Model Binding for finding this data from the articles table based on the column slug. But as I know, Route Model Binding finds data based on the id. So how to change Route Model Binding finding data from id to slug ONLY for ArticleController.php (meaning that the other Controller classes can work with id as route model binding)?

like image 988
Peter Amo Avatar asked Sep 07 '25 07:09

Peter Amo


2 Answers

In case you want to use other model field as the biding attribute instead of id you can define a getRouteKeyName which return the name of the field which must be use

class Article extends Model {
    // other methods goes here
    public function getRouteKeyName() {
        return 'slug';
    }
}

Or you can pass the field name directly when you define the route like this

Route::get('/articles/{article:slug}' , [App\Http\Controllers\ArticleController::class, 'single']);

With this code inside of your controller you must ensure that the name provide as parameter in the route definition match the name of the controller argument

public function single(Article $article)
{
    $article->increment('viewCount');

    return view('home.article',compact('article'));
}
like image 162
Yves Kipondo Avatar answered Sep 10 '25 03:09

Yves Kipondo


change your route to this:

Route::get('/articles/{article:slug}' , [App\Http\Controllers\ArticleController::class, 'single']);

and then inject the Article model to your controller function and let laravel do the rest for you:

public function single(Article $article)
    {
        $article->increment('viewCount');
        return view('home.article',compact('article'));
    }
like image 37
Behzad Avatar answered Sep 10 '25 02:09

Behzad