如何在Laravel关联关系中搜索并保留无关联数据?
Laravel 关联模型多字段搜索(保留无关联数据)
问题背景
在User模型中定义了与Job模型的一对多关联:
public function jobs(): HasMany { return $this->hasMany(Job::class); }
需求:同时搜索User表的name字段,以及jobs关联表中的title字段,且需要保留没有任何工作记录的用户。
尝试过的无效方案
- 使用
with闭包过滤关联数据
此方法仅会过滤关联的jobs数据,无法筛选出符合条件的用户本身,达不到预期搜索效果:
$users = User::with(['jobs' => function($query) { $query->when(request()->has('search'), function($query) { $query->orWhere('title', 'like', '%' . request('search') . '%'); }); })->where(function($query) { if (request()->has('search')) { $query->orWhere('name', 'like', '%' . request('search') . '%'); // 可添加更多用户表字段 } }) ->paginate(10);
- 使用
whereHas筛选关联用户whereHas会强制要求用户必须存在符合条件的jobs关联,导致没有工作记录的用户被过滤掉,不符合需求。
可行解决方案:使用orWhereHas
通过orWhereHas将用户自身字段匹配条件与关联模型匹配条件用OR逻辑连接,即可实现需求:
$users = User::with(['jobs']) ->where(function($query) { if (request()->has('search')) { // 匹配用户表字段,可添加更多字段条件 $query->orWhere('name', 'like', '%' . request('search') . '%'); // 匹配关联jobs的title字段(用户可无jobs) $query->orWhereHas('jobs', function($query) { $query->where('title', 'like', '%' . request('search') . '%'); }); } }) ->paginate(10);
方案说明
orWhereHas的逻辑是:用户自身字段匹配 或者 存在符合条件的jobs关联,因此既会包含name匹配的无工作用户,也会包含jobs标题匹配的有工作用户。- 关联查询内部使用
where而非orWhere,避免多条件时出现逻辑错误。
内容的提问来源于stack exchange,提问作者calin24
相关产品推荐
相关产品推荐

