larangah's avatar

How to use category {slug} wildcard in categories table when retrieving a post by category.

I have two(2) tables;

Posts: id, title, slug, category_id, body, is_published, created_at, updated_at

Categories: id, name, slug, created_at, updated_at

And here's my Post & Category model;

Post:

    public function category()
    {
        return $this->belongsTo(Category::class);
    }

Category:

    public function posts()
    {
        return $this->hasMany(Post::class);
    }

And here's my controller to retrieve a posts by category. (But for now, I retrieve the category directly via category_id in posts table itself)

    public function postCategory($id)
    {
        $posts = Post::where('category_id', $id)->get();

        return view('front.posts.category', compact('posts'));
    }

Finally my route;

Route::get('/category/{id}', 'PostController@postCategory')->name('post.category');

The question is, how can I use slug wildcard in categories table to replace the category_id I currently use.

I want my route to be like this:

Route::get(/category/{slug}); // http://example.com/category/laravel
0 likes
7 replies
edoc's avatar

Here u go.

Route::get(/category/{slug});

    public function postCategory($slug)
    {
        $posts = Post::where('slug', $slug)->get();

        return view('front.posts.category', compact('posts'));
    }

Is this what you want?

@LARANGAH

larangah's avatar

Thank you for your prompt reply @edoc but that doesn't solve the problem.

If you write the query like the above

        $posts = Post::where('slug', $slug)->get();

It will look for the slug field in the posts table where it doesn't exist.

My category slug was in the categories table.

When I dd your above code, it returns an empty array.

edoc's avatar
edoc
Best Answer
Level 24

I thought it's there cause your first post says so.

$posts = Category::where('slug', $slug)->first()->posts;

Can you try this?

@LARANGAH

larangah's avatar

you are my man @edoc! that nailed it!

before, I tried below query; can you have a look and comment on what I did wrong. thank you in advance.

$posts = Category::where('slug', $slug)->with('posts')->get();

thank you so so much again @edoc!

1 like
larangah's avatar

Thanks @edoc. Your assistance in this matter is greatly appreciated.

1 like
rjvandoesburg's avatar

@larangah You could also opt for Route model binding on other keys than ID if you're interested.

The following code snippet is from the docs:

/**
 * Get the route key for the model.
 *
 * @return string
 */
public function getRouteKeyName()
{
    return 'slug';
}

https://laravel.com/docs/5.4/routing#implicit-binding

As for the 'with' part this is also possible in eloquent, there is a $with attribute in your model you can inherit and specify default relations to load

Please or to participate in this conversation.