记如何在预加载中指定查询的字段

记录下今天在进行关联查询的预加载中一直无法指定需要查询的字段原由。
这里使用的代码为 LaraBBs
首先我们先查询所有用户以及对应用户的所有话题。

$result = User::with('topics')
    ->get()
    ->toArray();
dd($result);

得到如下结果。
file
然后我们来查询第一名用户,也就是 Summer 同学的信息及其所有话题。

$result = User::with('topics')
    ->where('name', 'Summer')
    ->get()
    ->toArray();
dd($result);

得到如下结果。
file
此时我们如果只想看话题的 内容标题
根据 文档 中介绍。
file

$result = User::with('topics:body,title')
    ->where('name', 'Summer')
    ->get()
    ->toArray();
dd($result);

得到如下结果。
file
emmmmm,我的话题内容呢?
仔细看上方文档截图最后一句发现 使用这个方法时,在你想获取的列中应始终有 id 列。
哦,原来始终需要加上 id 列,让我们再来一次。

$result = User::with('topics:id,body,title')
    ->where('name', 'Summer')
    ->get()
    ->toArray();
dd($result);

得到如下结果。
file
emmmmm,为什么还是木有啊。
再让我们通过 debugbar 查看进行了怎样的 sql 语句。
file
sql 语句放入数据库视图管理工具中执行。
file
没毛病啊,能查出来啊。
好吧,让我们仔细分析一下 sql 语句。
所谓的预加载先是通过 select * from 'users' where 'name' = 'Summer' 查出所有用户的信息。
然后通过关联属性将所查出的所有用户 id 取出带入第二个 sql 语句中
select 'id', 'body', 'title' from 'topics' where 'topics'.'user_id' in ('1')
最后要生成我们平时所看到的数据结构应该是将两次查询的结果按照按照两张表的关联进行合并。
在这次的查询中,两张表的唯一关联应该是 users.idtopics.user_id 两字段。
所以,虽然我们能通过最后一条 sql 语句查出数据,但是数据中并不包含关联字段 topics.user_id ,则无法产生关联,也就无法进行数据合并。
再通过一开始说的那句话 使用这个方法时,在你想获取的列中应始终有 id 列。 可知,这里的 id 列应该是关联字段列 user_id
知道原因后再让我们试一下。

$result = User::with('topics:user_id,body,title')
    ->where('name', 'Summer')
    ->get()
    ->toArray();
dd($result);

得到如下结果。
file
哦耶,Summer 同学的话题又回来了不是。
ps:
如果要进行约束预加载,应该这样写。

$result = User::with(['topics' => function ($query) {
    $query->select('id', 'user_id', 'body', 'title')
        ->orderBy('updated_at', 'desc');
    }])
    ->where('name', 'Summer')
    ->get()
    ->toArray();
dd($result);

file

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 5年前 自动加精
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 6

感谢!
我照着文档的例子一直查询不出来指定字段,原来id应该是关联的id(外键)。

5年前 评论

补充嵌套预加载指定字段的实现方法:

$user = User::with(['posts'=>function($query) {
     $query->select('id','user_id','title')->orderBy('updated_at','desc');
     $query->with(['tags'=>function($query) {
          $query->select('tag');
     }]);
}])->where('id',1)->get();

没有添加约束的方法:(不知如何指定tags的字段(Tag与Post是多对多关联))

 $user = User::with(['posts:user_id,title','posts.tags'])->where('id',1)->get();
5年前 评论
来杯优乐美 4年前

感谢,文档的例子是针对反向关联的情况,正向关联不能照着例子写。

5年前 评论

如果是预加载,我需要在数据库上面添加外健说明。user.id和topic.user_id是外健关系吗?还是说语句自己匹配?

4年前 评论

赞👍🏻

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!