shin
shin

Reputation: 32721

Laravel Eloquent how to get all products in a category with slug

My Productcategory.php has

public function products()
{
    return $this->hasMany('App\Models\Product');
}

And Product.php has

public function productcategory()
{
    return $this->belongsTo('App\Models\Productcategory', 'category_id');
}

Now my route is

Route::get('gallery/{slug}', 'GalleryController@index');

When URL is something like gallery/print-pattern-client-work, how can I get all products with the same category? I have the following but category_id is an integer and not a slug. So I am not so sure how to do it.

public function index()
{
    $categoryslug = Request::segment(2);
    $products = Productcategory::with('products')->where('category_id',$categoryslug)->get();
...
}

Upvotes: 2

Views: 8511

Answers (3)

Saumya Rastogi
Saumya Rastogi

Reputation: 13699

As you're using Laravel, you should use Laravel's Many to Many Relationships like this:

Your table structure would be like:

- products
    - id
    - name
    - ...

- categories
    - id
    - name
    - slug
    - ...

- category_product
    - id
    - category_id
    - product_id
    - ...

Your models should be like this:

class Product extends Model {

    public function categories() {
        $this->belongsToMany(Category::class, 'category_product');
    }

}

class Category extends Model {

    public function products() {
        $this->belongsToMany(Product::class, 'category_product');
    }

}

and you can fetch all the products for a particular $category_slug like this:

$category = Category::where('slug', $category_slug)->first();
if($category) {
    $products = $category->products;
}

Upvotes: 0

DevK
DevK

Reputation: 9952

This assumes you have a column named "slug" in your product_categories table. And that your described relations work well.

You could make an accessor in Product.php

public function scopeFindByCategorySlug($query, $categorySlug)
{
    return $query->whereHas('productcategory', function ($query) use ($categorySlug) {
        $query->where('slug', $categorySlug);
    });
}

Then in your controller you call this:

public function index(Request $request, $slug)
{
    $products = Product::findByCategorySlug($slug)->get();
}

Edit:

As mentioned in comments there is no actual need for an accessor. This is basically all you need (in controller):

public function index(Request $request, $slug)
{
    $products = Product::whereHas('productcategory', function ($query) use ($categorySlug) {
        $query->where('slug', $categorySlug);
    })->get();
}

Upvotes: 7

Illia Yaremchuk
Illia Yaremchuk

Reputation: 2025

Don't

$categoryslug = Request::segment(2);

Use $slug

public function index($slug)
{
    $products = Productcategory::with('products')->where('category_id',$slug)->get();
...
}

Upvotes: 2

Related Questions