Laravel 急切地加载同一个 table 中的多个模型

Laravel eagerly loading multiple models that are all in the same table

举个例子
假设我们有一个 users table 和一个 posts table.

用户 table 有 idname 列。

帖子 table 有 creator_idapproved_by_id 都存在(参考)用户 table.
我怎样才能用一个查询急切地加载它?

select * from posts where id in (z)
select * from users where id in (x,y) //(creator, approver)

目前我有这些关系:

public function created_by()
{
    return $this->belongsTo(User::class, 'creator_id');
}

public function approved_by()
{
    return $this->belongsTo(User::class, 'approved_by_id');
}

如果我理解正确的话

User::with(['created_by', 'approved_by'])
   ->get()

我保证您 运行 数据集大到足以让预先加载的性能成为一个问题。但是,如果有多个查询困扰您并且您宁愿承担管理查询构建器命令的技术债务,我认为这应该有效:

$post = Post::select('posts.*')
    ->selectRaw('creator.name as creator_name')
    ->selectRaw('approver.name as approver_name')
    ->leftJoin('users as creator', 'posts.creator_id', 'creator.id')
    ->leftJoin('users as approver', 'posts.approved_by_id', 'approver.id')
    ->where('posts.id', $post_id)
    ->get();

我们只是用不同的别名加入用户 table 两次;为避免覆盖列值,它们也需要别名。当然,您的数据将采用不同的格式,您将无法访问 $post->created_by->name 之类的内容,而是依赖于列别名。

等效的 SQL 查询将是:

SELECT posts.*, creator.name AS creator_name, approver.name AS approver_name
FROM posts
LEFT JOIN users AS creator ON (posts.creator_id = creator.id)
LEFT JOIN users AS approver ON (posts.approved_by_id = approver.id)
WHERE posts.id = ?