嵌套关系在第一次结果后停止工作

时间:2017-06-11 19:44:02

标签: php laravel eloquent laravel-5.3

以下是我目前的查询:

$messages = Message::select('messages.*')
    ->where('post_id', 1)
    ->where('parent_id', 0)
    ->with(['children' => function ($query)
    {
        $query->take(3);
    }])
    ->paginate(10);

以下是children课程中的Message.php关系:

public function children() {
    return $this->hasMany('App\Message', 'parent_id', 'id');
}

这是我想要获得的输出:

- Message 1
    - Message 1.1
    - Message 1.2
    - Message 1.3
- Message 2
    - Message 2.1
    - Message 2.2
    - Message 2.3
- Message 3
    - Message 3.1
    - Message 3.2
    - Message 3.3
- etc

但相反,它正在归还:

- Message 1
    - Message 1.1
    - Message 1.2
    - Message 1.3
- Message 2
- Message 3
- etc

查询似乎只返回第一个结果的子项,但是之后没有其他结果。

我做错了什么?如何修复查询以获得我需要的结果?

1 个答案:

答案 0 :(得分:1)

首先,回答问题"我做错了什么?",如果你按照documentation进行Eloquent急切加载,你会看到你构建的查询翻译对此:

select * from messages

select * from children where id in (1, 2, 3, 4, 5, ...) limit 3

(请注意,我编写了children表名,因为我不知道您使用的是什么名称。)

检索记录后,Eloquent将使用您要求的内容构建其对象:所有邮件及其所有子邮件 - 限制为3行。这就是为什么你只得到第一个Message的孩子。

现在,如果你想坚持使用预先加载,你可以简单地在with方法中删除闭包:

$messages = Message::select('messages.*')
    ->where('post_id', 1)
    ->where('parent_id', 0)
    ->with('children') /* the constraint is gone */
    ->paginate(10);

使用此分页结果,您可以访问所有 Messages所有各自的孩子。接下来,例如在控制器中,您可以通过过滤它或手动将每个子组限制为3来修改结果。或者,您可以快速而又脏,并在视图中直接使用带有break的循环。

但不要快速而肮脏。