Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

osc2nuke's avatar

3 tables products, products_to_categories, categories scenario

What i have as models:

  • Category (with description method on foreign Key categories_id)
  • CategoryDescription The combo above is working via DB table categories WITH categories_description

Same for products

  • Product
  • ProductDescription (with description method on foreign Key products_id) Now i created the model ProductsToCategories Owning the table: products_to_categories contains the columns: categories_id | products_id My url can be the following and already working for the categories mysite.test/cPath=1_2_3 I get back the names and id's for all 3 categories. Now i need to list the products assigned to categories_id = 3, or if i'm in ...cPath=1_2 for 2 ( if contain products or in cPath=1 if contain products......... i think you get the point).

What should be found via products_to_categories.

At this moment i'm stuck, as i can only find examples where the product is directly associated to the categories DB and not via a middle table products_to_categories. So far i figured that Product can have many Category, and i also figured that ProductsToCategories can have Many Product. But i'm getting a brainFreeze on this one, while i know it is something very simple as i try to avoid the N+1 scenario.

Hope someone can clear it up for me. Thanks in advance! (i keep learning)

0 likes
8 replies
SilenceBringer's avatar

@osc2nuke show your relationships, what do you have now, current output and expected output. It's really hard to understand your description

osc2nuke's avatar

@SilenceBringer I think i explained it well? The relationship should go via ProductsToCategories ( table: products_to_categories, columns : products_id | categories_id) So if i'm on 3 cPath=4_67_3 i should call products_to_categories table and load all Products (products_id) related to category.categories_id: 3 I handle the cPath by explode it, i not worry for that.... an example with a static categories_id would be sufficient to get me on track.

        $cPath = \Request::input('cPath');

PS: i think the relationship is between ProductsToCategory and Product ........... mmmm i'm getting smarter while answering. I think like this:

http://mysite.test/?cPath=1_2_3

                                          i fetch 3

                                          I load ProductsToCategory ->where('id', 3)-get()  or all()?????

and then i load all products_id matching the categories_id Vs. products_id

PS: i'm kinda new to Laravel.

osc2nuke's avatar

@SilenceBringer In my Category Model i do:

    public function getProducts($cPath){

        $cPath = \Request::input('cPath');
        $cPath = explode('_', $cPath);
        $cPath = end($cPath);
        return ProductsToCategories::selectRaw('products.products_id')
            ->where('products_to_categories.categories_id', '=', $cPath)
            ->leftJoin('products', 'products.products_id', '=', 'products_to_categories.products_id')->get();
    }
osc2nuke's avatar

I get the desired return from products_to_categories in the model Categories

I now need to do .................( i think) a "belongsTo"................... not sure yet! Or tell ProductsToCategories to return all products_id like a

protected $with = 'product????????'

That's the reason why i ask!

osc2nuke's avatar

Ok, got it! I used the asterisk , products(asterisk ) //how to put that here?

        return ProductsToCategories::selectRaw('products.*')

Is that a good practice?

        return ProductsToCategories::selectRaw('products.*')
            ->where('products_to_categories.categories_id', '=', $cPath)
            ->leftJoin('products', 'products.products_id', '=', 'products_to_categories.products_id')->get();
    }

So much variaties. Makes me a little crazy! Not sure if this query allowme to use ->paginate.(config ('setting.productPaginating'))

osc2nuke's avatar

I need to think better! The desired result does not come back, what is Obvious. I told in the Products Model to return $with.................

    protected $with = [ 'description'];
    
public function description(){

        return $this->belongsTo(ProductDescription::class, 'products_id')
            ->where('language_id','1')
            ;
    }

The selectRaw............. does not respect that.

osc2nuke's avatar

Add another->join.................... Is this how it should be done? not sure! I got the data now from products_description:

        return ProductsToCategories::selectRaw('products.*, products_description.*')
            ->where('products_to_categories.categories_id', '=', $cPath)
            ->leftJoin('products', 'products.products_id', '=', 'products_to_categories.products_id')
            ->leftJoin('products_description', 'products_description.products_id', '=', 'products_to_categories.products_id')
            ->where('products_description.language_id','1')
            ->get();
    }
osc2nuke's avatar

None of the above is good. Now i understand, i think!

Took me a while. PhpStorm and it's anoying 'Hints' helped me out.

class ProductsToCategories extends Model
{
    use HasFactory;
    protected $table = 'products_to_categories';
    protected $with = [ 'products'];


    public function products(){

        return $this->belongsTo(Products::class, 'products_id');
    }
}

Please or to participate in this conversation.