I'm trying to retrieve products from a category and all it's sub-categories.
Here's my categories
table :
| id | parent_id | name |
|---- |----------- |------------- |
| 1 | NULL | Electronics |
| 2 | 1 | Computers |
| 3 | 2 | Accessories |
| 4 | 3 | Keyboards |
and here's my products table :
| id | category_id | name |
|---- |------------- |----------- |
| 1 | 2 | Product 1 |
| 2 | 3 | Product 2 |
| 3 | 4 | Product 3 |
Let's say i'm in Computers
category page, and i want to display products from this table and all it's childrens.
so it should get products first from Computers
and Accessories
and also Keyboards
.
Here's my Category Model :
public function parent() {
return $this->belongsTo(Category::class, 'parent_id');
}
public function childs() {
return $this->hasMany(Category::class, 'parent_id');
}
public function products() {
return $this->hasManyThrough(Product::class, Category::class, 'parent_id', 'category_id', 'id');
}
Product Model :
public function categories() {
return $this->belongsTo(Category::class, 'category_id');
}
Query :
Category::with(['products', 'childs.products'])->where('id', $category->id)->get();
Return :
{
"id":11,
"parent_id":4,
"name":"Computers",
"products":[
{
"id":2,
"category_id":12,
"title":"Product 1",
"laravel_through_key":11
}
],
"childs":[
{
"id":12,
"parent_id":11,
"name":"Accessories",
"products":[
{
"id":1,
"category_id":13,
"user_id":1,
"title":"Product 2",
"laravel_through_key":12
}
]
}
]
}
Above, it's escaping the last child category Keyboards
.
I have tried to use hasManyThrough
relationship but i only got products from Computers
and Accessories
but didn't reach to Keyboards
.
So if i'm on a category i want to get all products from this category tree. even if a sub-category has sub-categories.
How can i achieve this?
Thanks.
Update :
i applied the snippet in Foued MOUSSI's answer :
public function childrenRecursive() {
return $this->childs()->with('childrenRecursive');
}
$categoryIds = Category::with('childrenRecursive')->where('id', $category->id)->get();
Return :
[
{
"id":2,
"parent_id":1,
"name":"Computers",
"children_recursive":[
{
"id":3,
"parent_id":2,
"name":"Accessories",
"children_recursive":[
{
"id":4,
"parent_id":3,
"name":"Keyboards",
"children_recursive":[]
}
]
}
]
}
]
and i got the array of category and all it's sub-categories, but to get products from all these categories i need to extract the IDs from the the list with childrenRecursive
to call something like :
Product::whereIn('category_id', $categoryIds)->get();
Any idea?
mysql
with laravel version5.8
– Amr SubZero