Mike P's avatar

How make route work? Sluggable (Cviebrock) with category id

I'm new to Laravel, could you push me into the right direction?

I need to render blog post on url like this site.com/posts/1/slugged-url-of-the-post/, where 1 is the category_id.

I have no problem with site.com/posts/slugged-url-of-the-post/, but absolutely stuck with adding one more parameter to the route and making it work. The database is okay, and I have no problems with displaying the post category_id as a text value, for example, in the posts.show blade file.

Please, help?

routes/web.php

Route::get('/posts/{post}', function( App\Models\Post $post) {
// need to make this work:
// Route::get('/posts/{category_id}/{post}' ...
  return view('posts.show')->with('post', $post);
});

app/Models/Post.php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Cviebrock\EloquentSluggable\Sluggable;
use Cviebrock\EloquentSluggable\SluggableScopeHelpers;

class Post extends Model
{
    use HasFactory, Sluggable, SluggableScopeHelpers;

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

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

}
0 likes
3 replies
danielrubango's avatar
Level 32

Hello @mike p... you can do that like this :

use App\Models\Category, App\Models\Post;

Route::get("/posts/{category}/{post:id}", function(Category $category, Post $post) {
    return view('posts.show')->with([
        'category' => $category,
        'post' => $post
    ]);
});

Hope it helps you !

1 like
Mike P's avatar

@danielrubango Thank you, but I don't have Category model at the moment.

I have a database record in the posts table:

| id  | category_id | slug         |
| --- | ----------- | -----------
| 1   | 12          | it-is-a-slug |

and I'm using github.com/cviebrock/eloquent-sluggable, which says:

you can set up your routes as described in the Eloquent documentation:

Route::get('api/posts/{post}', function(App\Post $post): string {
    return $post->title;
});

In this example, since the Eloquent type-hinted $post variable defined on the route matches the {post} segment in the route's URI, Laravel will automatically inject the model instance that has a slug matching the corresponding value from the request URI.

What I need is to write such a route to make this work

posts/12/it-is-a-slug/

instead of this (which is currently working):

posts/it-is-a-slug/

So that's the question, how to write it? Thank you

Mike P's avatar

@danielrubango I don't know if this decision is good or not, but I came up with the following:

routes/web.php

Route::get('/posts/{category}/{slug}', [PostController::class, 'getSingle']);

app/Http/Controllers/PostController.php

public function getSingle($category, $slug)
{

    $post = Post::where('category_id','=',$category)->where('slug','=',$slug)->first();
    
    return view('posts.single')->with('post', $post);
}

Please or to participate in this conversation.