Reputation: 43
I have then next 2 tables
/* systems */
id sys_name
1 Debtors
2 Creditors
3 Cashbook
/* menus */
id system_id parent_id menu_desc
1 1 0 Maintenance
2 1 1 Maintain Debtors
3 1 2 Debtor Addresses
4 1 1 Maintain Clerks
5 3 0 Bank Reconciliation
I have 2 Eloquent models
/* System */
public function menus(){
return this->hasMany(Menu::class,'system_id','id')->where('menus.parent_id','=',0);
}
public function submenus(){
return this->hasMany(Menu::class,'system_id','id')->where('menus.parent_id','=','menus.id');
}
/* Menu */
public function system(){
return $this->belongsTo(System::class,'system_id','id');
}
public function parent(){
return $this->hasOne(Menu::class,'id','parent_id');
}
public function children(){
return $this->hasMany(Menu::class,'parent_id','id');
}
I want to achieve the following in blade.php:
@foreach($systems as $system)
.......
@foreach($menus as $menu)
.......
@foreach($submenus as $submenu)
........
@endforeach
@endforeach
@endforeach
with the following output: (I am using bootstrap for indentation)
Debtors
Maintenance
Maintain Debtors
Debtor Addresses
Maintain Clerks
Creditors
Cashbook
Bank Reconciliation
MenuController
$systems = System::with('menus','submenus')->get();
but it doesn't work. There are no submenu records. I think the problem is 'menus.id' in function submenus() but dont know how to solve it.
Please help as I have battled more than 3 days to build a menu treeview.
Thanking you in advance
Upvotes: 2
Views: 924
Reputation: 91
You need to put the submenus() function on the menu model file, since your tree structure is
system
menu
submenu
or you can just change the with syntax to
$systems = System::with('menus','menus.children')->get();
and change the submenu foreach with $menu.children
@foreach($menu->children as $submenu)
Upvotes: 0
Reputation: 291
The easiest way to do what you want is to use a nested relation.
Instead of trying to build a ->submenus()
relation, instead just use the already-existing ->children()
relation on your Menu
class:
Route::get('systems', function() {
$systems = System::with('menus.children')->get();
return view('systems')->with('systems', $systems);
});
Then your systems.blade.php
template can just be something like
<pre>
Systems
@foreach($systems as $system)
{{$system->sys_name}} Menus
@foreach($system->menus as $menu)
{{$menu->menu_desc}} Submenus
@foreach($menu->children as $submenu)
{{$submenu->menu_desc}}
@endforeach
@endforeach
@endforeach
</pre>
As an additional advantage to that method, you can get all menus with subsubsubmenus with System::with('menus.children.children.children')->get()
, and so on.
Upvotes: 2