Laravel get all parents of category
you can append the parent variable:
class Category extends Model
{
protected $table = 'categories';
protected $appends = [
'parent'
];
public function parent()
{
return $this->belongsTo('App\Category', 'parent_id');
}
}
It's the shortest solution, but this is not the best way, since then every time a parent object is loaded. Better do this:
class Category extends Model { protected $table = 'categories';
public function parent()
{
return $this->belongsTo('App\Category', 'parent_id');
}
public function getParentsNames() {
if($this->parent) {
return $this->parent->getParentsNames(). " > " . $this->name;
} else {
return $this->name;
}
}
In your blade you call: {{ $category->getParentsNames() }}
You could define a model accessor on Cateory
model that retrieves all parents and puts them into a collection. So in your Category
model add the following method:
public function getParentsAttribute()
{
$parents = collect([]);
$parent = $this->parent;
while(!is_null($parent)) {
$parents->push($parent);
$parent = $parent->parent;
}
return $parents;
}
then in your blade template you can fetch all the parents of a category
@if(count($category->parents))
<td>{{ $category->parents->implode('-') }} <strong>-></strong> {{ $category->name }}</td>
@else
<td>{{ $category->name }}</td>
@endif
I see no other solution different from recursively retrieving all the parents and the package suggested by @Ross Wilson in the comments. Take into account that the number of queries will be equal to the number of the parent categories.
Another thing that you could do is setting the parent tree into the DB in the categories
table, to save a lot of queries. Add in your categories
table a string field like parents_tree
and at save/update time set this value with the parent names already concatenated. This is a little dirty because if one of the parents change its name you have to update all the children accordingly. Is up to you to which trade-off you want to succumb.