Eloquent 除了另一个 table 连接之外的递归自连接
Eloquent recursive self join in addition to another table join
首先,标题不太清楚,希望我能在这里解释得更好:
我有一个 MenuItem 模型,它具有递归自连接来表示多级菜单。此外,菜单项实际上可能有一个 Post 模型的外键。模型是这样的:
class MenuItem extends Model
{
use HasFactory;
public function parentItem()
{
return $this->belongsTo(MenuItem::class, 'parent_menu_id', 'id');
}
public function childrenItems()
{
return $this->hasMany(MenuItem::class, 'parent_menu_id', 'id');
}
public function allChildrenItems()
{
return $this->childrenItems()->with('allChildrenItems');
}
public function post()
{
return $this->belongsTo(Post::class, 'post_id', 'id');
}
}
为了递归检索所有菜单项,我这样做了并且效果很好:
$menu = MenuItem::with('allChildrenItems')->whereNull('parent_menu_id')->get();
我必须添加条件 whereNull
以首先仅检索顶级菜单项,递归连接将根据层次结构获取其余项。
问题是我还需要用适当的 post 加入每个菜单项。我尝试将上面的 eloquent 查询更新为这样:
$menu = MenuItem::with('allChildrenItems')->whereNull('parent_menu_id')
->leftJoin('posts', 'posts.id', '=', 'menu_items.post_id')
->get();
但是左连接只适用于顶层 collection whereNull('parent_menu_id')
,并且不会在递归连接(children 菜单项)中被拒绝。
如何在此处为 parent 和 children 项添加联接?
在您的 parentItem
和 childrenItems
关系中,添加 with('post')
以便 post 将添加到每个级别。
public function parentItem()
{
return $this->belongsTo(MenuItem::class, 'parent_menu_id', 'id')
->with('post');
}
public function childrenItems()
{
return $this->hasMany(MenuItem::class, 'parent_menu_id', 'id')
->with('post');
}
首先,标题不太清楚,希望我能在这里解释得更好:
我有一个 MenuItem 模型,它具有递归自连接来表示多级菜单。此外,菜单项实际上可能有一个 Post 模型的外键。模型是这样的:
class MenuItem extends Model
{
use HasFactory;
public function parentItem()
{
return $this->belongsTo(MenuItem::class, 'parent_menu_id', 'id');
}
public function childrenItems()
{
return $this->hasMany(MenuItem::class, 'parent_menu_id', 'id');
}
public function allChildrenItems()
{
return $this->childrenItems()->with('allChildrenItems');
}
public function post()
{
return $this->belongsTo(Post::class, 'post_id', 'id');
}
}
为了递归检索所有菜单项,我这样做了并且效果很好:
$menu = MenuItem::with('allChildrenItems')->whereNull('parent_menu_id')->get();
我必须添加条件 whereNull
以首先仅检索顶级菜单项,递归连接将根据层次结构获取其余项。
问题是我还需要用适当的 post 加入每个菜单项。我尝试将上面的 eloquent 查询更新为这样:
$menu = MenuItem::with('allChildrenItems')->whereNull('parent_menu_id')
->leftJoin('posts', 'posts.id', '=', 'menu_items.post_id')
->get();
但是左连接只适用于顶层 collection whereNull('parent_menu_id')
,并且不会在递归连接(children 菜单项)中被拒绝。
如何在此处为 parent 和 children 项添加联接?
在您的 parentItem
和 childrenItems
关系中,添加 with('post')
以便 post 将添加到每个级别。
public function parentItem()
{
return $this->belongsTo(MenuItem::class, 'parent_menu_id', 'id')
->with('post');
}
public function childrenItems()
{
return $this->hasMany(MenuItem::class, 'parent_menu_id', 'id')
->with('post');
}