in our application which that used laravel
we implemented parent-child structure with data base relation ship. for example:
all ids are sample in this structure:
programmings (NULL):
web programmings (1)
backend (2)
laravel (3)
api )4)
lumen (5)
python (6)
desktop (7)
java (8)
each parent in our database started and pointed with null
and each child has parent id. now when we try to get all parents of laravel
we should have:
backend - web programmings - programmings
Category
model structure:
/**
* Get the parent Category to which the current Category belongs.
*/
public function parent(): BelongsTo
{
return $this->belongsTo(Category::class, 'parent_id', 'id', 'parent');
}
/**
* Get all Categories which belong to the current Category.
*/
public function subcategories(): HasMany
{
return $this->hasMany(Category::class, 'parent_id', 'id');
}
i getting one level of child parent but i don't know how can i get all parents of child til arrived to null
getting all posts based on role:
controller:
$categories = auth()->user()->availableCategories();
HasPosts
trait:
trait HasCategories
{
public function availableCategories(): Collection
{
$categories = $this->categories;
$parents = $categories->filter(function ($cat) use ($categories) {
return !in_array($cat->parent_id, $categories->pluck('id')->all()) || is_null($cat->parent_id);
});
$parents->map(
fn ($parent) => $this->setNested($parent, $categories)
);
return $parents;
}
/**
* Get all Categories with Posts associated with the User in nested tree structure.
*/
public function availableCategoriesWithPosts(): Collection
{
$categories = $this->categories()->withPosts()->get();
$parents = $categories->filter(
fn ($cat) =>
!$categories->contains('id', $cat->parent_id) || is_null($cat->parent_id)
);
$parents->map(fn ($parent) => $this->setNested($parent, $categories));
return $parents;
}
protected function setNested($parent, $categories)
{
$parent->setRelation('subcategories', $categories->where('parent_id', $parent->id));
$parent->subcategories->map(function ($sub) use ($categories) {
if ($categories->contains('parent_id', $sub->id)) {
$this->setNested($sub, $categories);
return $sub;
}
});
}
}
i try this code:
public function parent(): BelongsTo
{
return $this->belongsTo(Category::class, 'parent_id', 'id', 'parent')->with('parent');
}