Chhorn Soro
Chhorn Soro

Reputation: 3151

Yii2 Find all products in parent category

I have 2 tables structure as following:

category(id,cat_name , parent_id);
product(id,category_id ,pro_name);

Relation in Product Model

public function getCategory()
    {
        return $this->hasOne(Category::className(), ['id' => 'category_id']);
    }  

Category

id   cat_name    parent_id
1    Electronic   0
2    Fruit        0
3    TV           1
4    Apple        2

Product
id category_id  pro_name
1  1            Samsung
2  3            Sony
3  3            Panasonic
4  2            Apple
5  2            Orange

What I want to do is when I select on category (1) Electronic I want to get Samsung,Sony,Panasonic from table Product

Upvotes: 0

Views: 2146

Answers (2)

Clyff
Clyff

Reputation: 4076

So, you must have a relational function in your Category model calling more Categories. And another relational function calling the Products. I'm assuming the names are getParentId() and getProducts(). (If you dont have, you can use Gii to generate them for you)

Here is a recursive approach you can do inside your Category model:

public function getSubCategories()
{
    if ($categories = $this->parentId) { // the name of your relational function.   
        foreach ($this->parentId as $sub) {
            $categories = array_merge($categories, $sub->subCategories);
        }
    }

    return $categories;
}

public function getProductsWithSubcategories()
{
    $products = $this->products; // the name of your relational function.   

    foreach ($this->subCategories as $sub) {
        $products = array_merge($products, $sub->products);
    }

    return $products;
}

Upvotes: 3

Jørgen
Jørgen

Reputation: 3567

// given $id is your current toplevel category
$cat_ids = Category::find()->select('id')->where(['parent_id' => $id])->asArray()->all();
$ids = [];
foreach($cat_ids as $value)
{
    $ids[] = $value['id'];
}
$ids = implode(',',$ids);
$categories = Products::find()->where('category_id IN ('.$ids.','.$id.')')->all();

Some object to array functionallity there that you might be able to clean up. This was quick and dirty, but should work. You get the point.

Upvotes: 0

Related Questions