skip to Main Content

I’ve got 90% of my site finished, up until now it’s been passing round model IDs from page to page as such:

http://website.domain/2/content/3

I’m using models bound within the web.php like so:

Route::get('{post}/content/{comment}', 'ContentController@index');

This is working fine.

I would like to change the URL so it’s more user/SEO friendly so it displays as such:

http://website.domain/hello-world/content/this-is-more

I know I can do a look-up in the controller for every index, however I was wondering if there was a more automated way to convert the URL when an ID is used, such as a middleware perhaps, or is doing a look-up everytime I need to do it the only way forward?

Any help would be appreciated.

2

Answers


  1. You dont need to do that through middleware…

    The Eloquent’s models has a method that indicates what column will be used by the router to lookup the binded model, you just need to override it.

    Example for the post’s model:

    namespace AppModelsPost;
    
    use IlluminateDatabaseEloquentModel;
    use IlluminateSupportFacadesRoute;
    
    class Post extends Model
    {
        public function getRouteKeyName(): string {
            $identifier = Route::current()->parameters()['post'];
    
            if (!ctype_digit($identifier)) {
                return 'your-slug-col-name';
            }
    
            return 'id';
        }
    }
    

    This way your route will work with id or slug…

    Login or Signup to reply.
  2. One easy way is use explicit model binding

    in app/Providers/RouteServiceProvider.php in method boot you can define your bindings

    For ex:

    public function boot()
    {
        Route::bind('postSlug',function($value){
           return Post::whereSlug($value)->firstOrFail();
        });
        Route::bind('commentSlug',function($value){
           return Comment::whereSlug($value)->firstOrFail();
        });
    
        parent::boot();
    }
    

    and in your Route.php:

    Route::get('{postSlug}/content/{commentSlug}', 'ContentController@index');
    

    hope this is helpful

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search