I have a MySQL table as
+--------------------+--------------------+--------------------+
| Id | parent_id | title |
+--------------------+--------------------+--------------------+
| 1 | 0 | Student Management |
|--------------------|--------------------|--------------------|
| 2 | 0 | Staff Management |
|--------------------|--------------------|--------------------|
| 3 | 1 | Add Student |
|--------------------|--------------------|--------------------|
| 4 | 1 | View Students |
|--------------------|--------------------|--------------------|
| 5 | 2 | Add Staff |
|--------------------|--------------------|--------------------|
| 6 | 2 | View Staff |
|--------------------|--------------------|--------------------|
| 7 | 4 | Delete |
|--------------------|--------------------|--------------------|
| 8 | 5 | Copy |
+--------------------+--------------------+--------------------+
I want to get above as in my view recursively as.
Desired Output
+-------------------------------+------------------------------+
| Student Mangement | Staff Management |
| Add Student | Add Staff |
| View Student | Copy |
| Delete | View Staff |
+-------------------------------+------------------------------+
I want to get above MySQL table as structure I defined above
My get method is as
public function get()
{
$categories = Categories::where('parent_id', '=', 0)->get();
$permission = Categories::pluck('title','id')->all();
return view('create-role')->with(compact('categories'));
}
With above method, i am getting parents in y view as
@foreach($categories as $category)
<li>
{{ $category->title }}
</li>
@endforeach
Output is as
Student Management
Staff Management
Please Help how can I get above-mentioned structure recursively.
First define the relationships in your model
public function children() {
return $this->hasMany(Category::class, 'parent_id', 'id');
}
public function parent() {
return $this->belongsTo(Category::class, 'parent_id', 'id');
}
Then in your view, I don't know how many sub levels you have. But there are 2 ways:
1- The easiest way
If you know, you will never go over 3 levels, just nest 3 foreach in your view
First you query eagerly
$categories = Category::with('children')->get(); //save you some queries
@foreach($categories as $category)
@if( $category->children )
@foreach($category->children as $level2)
@if($level2->children)
@foreach($level2->children as $level3)
@if($level3->children)
//another foreach
@endif
{{ $level3->title }}
@foreach
@endif
{{ $level2->title }}
@endforeach
@endif
{{ $category->title }}
@endforeach
2- The actual recursive way.
This is experimental and not tested
Define a recursive relationship
public function recursiveChildren() {
return $this->children()->with('recursiveChildren');
//It seems this is recursive
}
Here is simple recusive way to do it with php (any framework).
Basically you need all of the items in a simple array and run formatTree, but you can change the function to use object instead of array.
<?php
function formatTree($tree, $parent)
{
$tree2 = array();
foreach ($tree as $item) {
if ($item['parent_id'] == $parent) {
$tree2[$item['id']] = $item;
$tree2[$item['id']]['child'] = formatTree($tree, $item['id']);
}
}
return $tree2;
}
//for demo
$beforeTree = [
['id' => 1, 'parent_id' => 0],
['id' => 2, 'parent_id' => 1],
['id' => 3, 'parent_id' => 2],
['id' => 4, 'parent_id' => 0],
['id' => 5, 'parent_id' => 4],
['id' => 6, 'parent_id' => 4],
];
$afterTree = formatTree($beforeTree, 0);
var_dump($afterTree);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With