【问题标题】:Eloquent recursive self join in addition to another table join除了另一个表连接之外,雄辩的递归自连接
【发布时间】:2021-05-26 13:20:45
【问题描述】:

首先,抱歉标题不太清楚,我希望我能在这里更好地解释一下:

我有一个 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 以首先仅检索顶级菜单项,递归连接将根据层次结构带来其余项。

问题是我还需要将每个菜单项加入到正确的帖子中。我尝试将上述雄辩的查询更新为:

$menu = MenuItem::with('allChildrenItems')->whereNull('parent_menu_id')
                ->leftJoin('posts', 'posts.id', '=', 'menu_items.post_id')
                ->get();

但左连接仅适用于顶级集合whereNull('parent_menu_id'),并且不会在递归连接(子菜单项)中受到反感。

如何在此处为父项和子项添加联接?

【问题讨论】:

    标签: laravel eloquent laravel-8 eloquent-relationship


    【解决方案1】:

    在您的parentItemchildrenItems 关系中,将with('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');
    }
    

    【讨论】:

    • 哇!有效!我们可以这样做吗?这是我们可以用通用方式做的事情吗?
    • 说实话,我自己还没有尝试过,但从逻辑上讲,这是它应该工作的方式,所以除了我无法确定之外。
    • 向 laravel 的创建者和贡献者致敬!
    猜你喜欢
    • 1970-01-01
    • 2018-07-18
    • 2014-07-01
    • 2020-05-08
    • 2018-05-08
    • 2018-06-03
    • 2019-06-09
    • 2018-02-10
    • 1970-01-01
    相关资源
    最近更新 更多