急切加载时为 Eloquent 关系别名

Posted

技术标签:

【中文标题】急切加载时为 Eloquent 关系别名【英文标题】:Alias an Eloquent relationship when eager loading 【发布时间】:2019-01-22 21:28:33 【问题描述】:

是否有办法在急切加载时为 Eloquent 关系设置别名?例如,我可能有如下查询。

User::with(['roles' => function ($query)  $query->where('type', ADMIN); ]);

但是,如果我也想预先加载状态为 ACTIVE 的角色怎么办?我能想到的唯一方法是复制 User 模型上的角色关系并给它一个不同的名称。查询将如下所示。

User::with([
  'roles' => function ($query)  $query->where('type', ADMIN); ,
  'otherRoles' => function ($query)  $query->where('status', ACTIVE) ]
);

我可以在我的用户模型上使用诸如 adminRolesactiveRoles 之类的方法,但这真的不是我想要的,因为有很多可能的参数。

【问题讨论】:

【参考方案1】:

您已表明您不想在用户模型上使用其他方法,但这是您除了使用已经使用的闭包之外的最佳方法。您可以通过让 adminRoles 等新方法利用现有的关系方法以及相关模型提供的范围来稍微改进代码。

class User extends Eloquent 

    public function roles()
    
        return $this->hasMany(Role::class);
    

    public function adminRoles()
    
        return $this->roles()->admin();
    

然后定义要在 Role 模型上使用的范围。

class Role extends Eloquent

    public function scopeAdmin($query)
    
        $query->where('type', static::ADMIN);
    

您现在可以立即加载这些作用域关系。

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

【讨论】:

【参考方案2】:

不幸的是,当在 Laravel (8.x) 中当前无法进行预加载时,会出现别名关系。看起来它不会在不久的将来实施,因为 Taylor 已经关闭了两个 PR。

https://github.com/laravel/framework/pull/37656#issuecomment-870604176

https://github.com/laravel/framework/pull/31976#issuecomment-599538731

【讨论】:

以上是关于急切加载时为 Eloquent 关系别名的主要内容,如果未能解决你的问题,请参考以下文章

laravel eloquent - 在嵌套急切加载的关系上不使用

Laravel Eloquent 中的急切加载

Laravel 在急切加载时使用 Eloquent 选择特定列

急切加载 Laravel Eloquent 相关模型

在 Eloquent 急切加载中选择特定字段不起作用

Eloquent:急切加载选择约束?可能?