Eloquent中如何在账户不存在时获取关联资源且仅执行单查询?
解决Eloquent关联查询的空指针问题+实现单查询获取资源
嘿,这个问题我之前也碰到过,你的痛点确实很典型——原来的写法不仅会触发两次数据库查询,还会在用户没有对应Account的时候抛出讨厌的空指针错误。刚好有个完美的方案能同时解决这两个问题,而且只需要一次数据库查询。
最优实现方式
直接从Resource模型入手,利用whereHas方法通过关联的Account来筛选用户对应的资源:
Resource::whereHas('account', function($query) { $query->where('user_id', Auth::id()); })->get();
为什么这是最优解?
- 避免空指针异常:不管当前用户有没有对应的Account,这个查询都会返回一个
Collection(没有资源就是空集合),永远不会出现Call to a member function resources() on null的错误。 - 单查询效率更高:这个写法会生成一条带
EXISTS子查询的SQL语句,只和数据库交互一次。对比你原来的写法:- 原写法先执行
SELECT * FROM accounts WHERE user_id = ? LIMIT 1,再执行SELECT * FROM resources WHERE account_id = ?,两次查询。 - 新写法的SQL是:
SELECT * FROM resources WHERE EXISTS (SELECT * FROM accounts WHERE accounts.id = resources.account_id AND accounts.user_id = ?),仅一次查询。
- 原写法先执行
额外补充:如果需要同时获取Account信息
如果你的业务场景需要同时拿到Account和对应的Resource,可以用预加载+筛选的方式(这会触发两次必要的查询):
$accounts = Account::where('user_id', Auth::id())->with('resources')->get(); $resources = $accounts->pluck('resources')->flatten();
不过如果只是单纯要Resource,还是前面的whereHas方案更高效。
内容的提问来源于stack exchange,提问作者JSowa
相关产品推荐
相关产品推荐

