Reputation: 5422
First of all, I don't have any issues with setting up the relationship within the model.
I have a WebGroup
model that can have unlimited parent WebGroup
(s) as well as unlimited child WebGroup
(s).
Parent relationship:
public function parent()
{
return $this
->belongsTo(WebGroup::class, 'pargroup1', 'webgroup')
->with('parent');
}
Child relationship:
public function children()
{
return $this
->hasMany(WebGroup::class, 'pargroup1', 'webgroup')
->with('children');
}
I can get a nested collection of all children for a given WebGroup
via: $webGroup->children
.
This gives me:
It's nested, it's unlimited. Fantastic. But now how can I recursively loop through that collection and recursively get a flatten array of a given attribute. For example each WebGroup
model has a name attribute.
How to recursively get all names for a given collection of all WebGroups
starting from parent, going down to all children down the rabbit hole?
Upvotes: 0
Views: 2023
Reputation: 1
Here is the code to get all the childrens of the selected parent...
// Recursive function to get all children/sub-categories ids
function getRecursiveCategoryId($categoryId){ // Your Parent Category Id
$children = [];
$parentCategories = Category::where('parent_id', $categoryId)
->latest()
->select('id')
->get();
foreach ($parentCategories as $category) {
$children[] = $category->id;
$children[$category->id] = getRecursiveCategoryId($category->id,$children);
}
return $children;
}
$arraySubCategoryIds = getRecursiveCategoryId($categoryId);
$arraySubCategoryIdss = Arr::flatten($arraySubCategoryIds);
Upvotes: 0
Reputation: 941
The easiest way to do this using appends variable. Get the children data using mutator like this,
public function getChildrenAttribute()
{
return $this->hasMany(Category::class,'parent_id')->get();
}
and then use the appends variable,
protected $appends = ['children'];
Then just call the function,
Category::find($id)
Upvotes: 0
Reputation: 5422
OK, I managed to write this by myself…
private function getNestedChildrenByWebGroup(WebGroup $webGroup): Collection
{
$data = collect([]);
foreach ($webGroup->children as $child) {
$data->push($child->webgroup);
// If child has it's own children…
if ($child->children instanceof Collection) {
// Recursive call to all children of a child
foreach ($child->children as $childWebGroup) {
$this->getNestedChildrenByWebGroup($childWebGroup);
$data->push($childWebGroup->webgroup);
}
}
}
return $data;
}
DB Structure:
Final result:
Upvotes: 1