Laravel Eloquent 负载关系中枢轴关系 [已解决]

Posted

技术标签:

【中文标题】Laravel Eloquent 负载关系中枢轴关系 [已解决]【英文标题】:Laravel Eloquent load relationship inside pivot relationship [SOLVED] 【发布时间】:2021-03-06 06:01:30 【问题描述】:

我正在搜索使用“->with()”加载数据透视表中的关系。

表结构:是 5 个表和 Laravel Eloquent 模型

用户 (id)团队 (id)角色 (id)team_user (id, team_id, user_id)team_user_role (id, team_user_id, role_id)

class User extends Model 
    function teams()
        return $this->belongsToMany(Team::class)
            ->using(TeamUser::class);
    


class Team extends Model 
    function users()
        return $this->belongsToMany(User::class)
            ->using(TeamUser::class);
    


class TeamUser extends Pivot 
    function roles()
        return $this->belongsToMany(Role::class)
            ->using(TeamUserRole::class);
    


class Role extends Model 
class TeamUserRole extends Pivot 

好的,我可以做到,而且效果很好,“->with()”函数从 TeamUser 加载角色关系...

TeamUser::with('roles')->first()->roles // return list of Role::class

...但我需要从 User::class "User->teams->roles" 加载此“角色”关系:

User::with('teams')
    ->with('teams.pivot.roles') // Something like this
    ->first()->teams->pivot->roles; // Expected a list of Role::class

这样得到了一个 RelationNotFoundException,这是有道理的,因为 'pivot' 不是一个关系......

那么,在这种情况下,我如何使用 QueryBuilder 访问用户的角色列表?

谢谢。

[编辑]

我用@Mathieu Ferre 的回答解决了这种情况

使用这个依赖

https://github.com/staudenmeir/eloquent-has-many-deep

class User extends Model 
    use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
    
    ...
    
    function roles()
        return $this->hasManyDeep(Roles::class,
            [TeamUser::class, TeamUserRole::class],
            ['user_id', 'team_user_id', 'id'],
            ['id', 'id', 'role_id']
        );
    

【问题讨论】:

User::with('teams.roles') 工作吗? 我试过了,得到了同样的 RelationNotFoundException 【参考方案1】:

你必须在你的模型中使用withPivot() 方法:

class Role extends Model 
    public function 

然后:

User::with('teams')
    ->with('teams.roles') // Something like this
    ->first()->teams->pivot->attributes;

如果您真的想将 Role Pivot 作为一个雄辩的模型来访问:

class User extends Model 
    function teams()
        return $this->belongsToMany(Team::class)
            ->using(TeamUser::class);
    

     function roles()
        return $this->hasManyThrough(Role::class, Team::class);
    




User::with('roles')->get();

查看文档了解更多信息:

https://laravel.com/docs/8.x/eloquent-relationships#has-many-through

如果您需要更深入的关系,您应该考虑这个包:

https://github.com/staudenmeir/eloquent-has-many-deep

【讨论】:

好的,谢谢你的详细回答......我试过withPivot(),但我没有成功,我想我忘记了一些东西。但我很好奇你建议我在哪里使用 withPivot(),我在你的例子中看不到。关于hasManyThrough(),我觉得这确实是我需要的,我会试试的,再次感谢。 我看了一下hasManyThrough(),但这不是我需要的,hasManyThrough() 不使用数据透视表,它只是关系的快捷方式。就我而言,我有“TeamUserRole”,即“belongsTo”数据透视表“TeamUser”和一个“Role”。换句话说,我有一个与另一个数据透视表(TeamUser)有关系的数据透视表(TeamUserRole)。 hasManyDeep() 正是我所需要的!再次感谢您。

以上是关于Laravel Eloquent 负载关系中枢轴关系 [已解决]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Laravel/Eloquent 中获得完整的关系

深入理解 Laravel Eloquent——模型间关系(关联)

laravel 返回与 eloquent 和 laravel 的关系

在最近的关系记录中搜索 - Laravel (Eloquent)

Laravel / Eloquent 模型关系查看器

Laravel 按 Eloquent 关系分组