staudenmeir / eloquent-has-many-deep

Laravel Eloquent HasManyThrough relationships with unlimited levels
MIT License
2.67k stars 157 forks source link

Category has many manufacturers from product brands #174

Closed Stelikas closed 1 year ago

Stelikas commented 2 years ago

I honestly tried everything before writing an issue but i couldn't find a solution. In sort:

I'm trying to grab manufacturers from product categories and the only connection is through the product brand

Category→ many to many → Product→ has one → Brand→ has one → Manufacturer

Inside category.php model

    public function manufacturers() {
        return $this->hasManyDeep(Manufacturer::class, ['category_product', Product::class], [Brand::class],
        [
            'category_id', // Foreign key on the "category_product" table.
            'id', // Foreign key on the "products" table (local key).
            'manufacturer_id', // Foreign key on the "brands" table.
            'id' // Foreign key on the "manufacturers" table.
        ],
        [
            'id', // Local key on the "categories" table.
            'product_id', // Local key on the "category_product" table (foreign key).
            'id' // Local key on the "products" table,
            'id' // Local key on the "brands" table,
        ]
        );
    }

What am i doing wrong?

staudenmeir commented 2 years ago

Hi @Stelikas,

['category_product', Product::class], [Brand::class]

Is this a typo or are passing two separate arrays here? It should be ['category_product', Product::class, Brand::class].

If that's not the issue, please share the migrations (local and foreign keys) of all tables involved in this relationship.

Stelikas commented 2 years ago

Hello @staudenmeir thanks for responding.

I changed the code as below:

public function manufacturers() {
        return $this->hasManyDeep(Manufacturer::class, ['category_product', Product::class, Brand::class],
        [
            'category_id',
            'brand_id',
            'manufacturer_id',
            'id'
        ],
        [
            'id',
            'product_id',
            'id',
            'id'
        ]
        );
    }

As of the tables:

category --id

category_product --category_id --product_Id

product --id --brand_id

brand --id --manufacturer_id

manufacturer --id

staudenmeir commented 2 years ago

Use this relationship:

public function manufacturers() {
    return $this->hasManyDeep(
        Manufacturer::class,
        ['category_product', Product::class, Brand::class],
        [
            'category_id',
            'id',
            'id',
            'id',
        ],
        [
            'id',
            'product_id',
            'brand_id',
            'manufacturer_id',
        ]
    );
}
Stelikas commented 2 years ago

@staudenmeir I actually tried this and it displays a manufacturer two times.

staudenmeir commented 2 years ago

There must be multiple paths from the category through the category_product table to this manufacturer (possibly with different products and/or brands). The query result is correct, but they are also ways to only get unique manufacturers.

What does your query look like in this case?

devstack-be commented 1 year ago

@staudenmeir you can add ->distinct(); at the end of your relationship