Laravel 递归 whereHas on BelongsToMany 关系

Posted

技术标签:

【中文标题】Laravel 递归 whereHas on BelongsToMany 关系【英文标题】:Laravel recursive whereHas on BelongsToMany relationship 【发布时间】:2020-06-12 16:29:04 【问题描述】:

我有一个名为 User 的模型,它上面有一个名为 lineManagers() 的 BelongsToMany 关系。此关系返回User 模型的集合。这种设置的性质允许父子样式关系在多个级别上运行。

BelongsToMany 使用名为 line_manager_user 的表,该表具有将用户 ID 映射到直线经理用户 ID 的简单模式:

| user_id | line_manager_id |
User A -> lineManagers()-> User B
                           User C -> lineManagers() -> User D

根据某些权限,我希望能够为具有特定users.id 的直线经理的用户查询这种关系到多个级别,可能使用whereHas(),但我知道这可能是相当的影响性能。

我尝试了以下查询但无济于事(最后一部分是相关部分):

$query = User::query()
    ->with('lineManagers')
    ->orderBy('first_name')
    ->orderBy('last_name')
    ->havingEmploymentStatus(UserEmploymentStatus::EMPLOYED)
    ->whereHas('lineManagers.lineManagers.lineManagers', function (Builder $query) 
        $query->where('id', $this->getAuthenticatedUser()->id);
    );

我并不特别想要 3 个级别,理想情况下,查询将检索 lineManagers,直到命中一个空集合。不幸的是,这确实需要我在查询级别而不是集合级别完成

【问题讨论】:

我不确定我是否正确理解了您的问题。但对我来说,听起来你必须查询直线经理用户表,然后加入你需要的信息:LineManagerUser::where('user_id', $this->getAuthenticatedUser()->id)->join(User::class, 'user.id','=','line_manager_user.user_id')->get() 【参考方案1】:

如果你让它成为一个调用自身的函数,直到它向下钻取到空集合,你就可以做到。那不管有多少关卡

查看https://www.sitepoint.com/laravel-blade-recursive-partials/

我不建议在刀片文件中这样做,而是将他们的“Plain old php”代码放入一个函数中

【讨论】:

以上是关于Laravel 递归 whereHas on BelongsToMany 关系的主要内容,如果未能解决你的问题,请参考以下文章

Laravel whereHas on Many-to-Many 关系

Laravel eloquent apply whereHas on the latest record of hasMany 关系

Laravel 多对多使用WhereHas搜索,中间表和要搜索表的字段重合时

Laravel 多对多使用WhereHas搜索,中间表和要搜索表的字段重合时

从 Laravel 5.1 升级到 Laravel 5.8 后 whereHas() 变慢

在 Laravel 5 中合并 'with' 和 'whereHas'