You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel关联关系中搜索并保留无关联数据?

Laravel 关联模型多字段搜索(保留无关联数据)

问题背景

在User模型中定义了与Job模型的一对多关联:

public function jobs(): HasMany
{
   return $this->hasMany(Job::class);
}

需求:同时搜索User表的name字段,以及jobs关联表中的title字段,且需要保留没有任何工作记录的用户。

尝试过的无效方案

  1. 使用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);
  1. 使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 15:17:44