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

Laravel Eloquent实现匹配项目或关联条目任意标题并返回结果的方法

Laravel 关联模型多字段搜索实现方案

原代码问题分析

你原来的写法问题根源是混淆了with和whereHas的作用:

  • 主查询只限定了projects.title匹配搜索词,所以只要项目标题不匹配,哪怕关联的条目有符合条件的,主查询也不会返回该项目
  • with闭包仅用于过滤预加载的关联数据,不会对主查询的结果筛选产生任何影响,单独用预加载确实无法实现你的需求。

实现逻辑说明

你最终采用的orWhereHas思路是正确的,whereHas的作用就是检测关联模型是否存在符合条件的记录,会直接影响主模型的查询结果,刚好满足「只要项目标题匹配或者关联条目标题匹配就返回项目」的要求。
要完全匹配你的业务规则,还要调整预加载部分的逻辑,完整可运行代码如下:

$search = $this->search;
$projects = Auth::user()->projects()
    // 主查询筛选:项目标题匹配 或者 存在匹配的关联条目
    ->where(function($query) use ($search) {
        $query->where('title', 'LIKE', "%{$search}%")
              ->orWhereHas('items', function($q) use ($search) {
                  $q->where('title', 'LIKE', "%{$search}%");
              });
    })
    // 预加载条目和标签,按需过滤条目
    ->with(['items' => function($q) use ($search) {
        // 如果项目本身标题已经匹配搜索词,返回所有条目;否则只返回匹配的条目
        $q->where(function($q) use ($search) {
            $q->where('title', 'LIKE', "%{$search}%")
              ->orWhereRaw('exists (select 1 from projects where projects.id = items.project_id and projects.title like ?)', ["%{$search}%"]);
        })->with('tags');
    }])
    ->get();

逻辑验证

  • 搜索词仅匹配项目标题:主查询筛选出该项目,预加载时orWhereRaw条件生效,返回项目下所有条目及关联标签
  • 搜索词仅匹配条目:主查询通过orWhereHas筛选出条目的所属项目,预加载时仅返回匹配的条目及关联标签
  • 搜索词同时匹配项目和条目:两种规则同时生效,返回项目和所有符合规则的条目

内容的提问来源于stack exchange,提问作者SeaBass

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 11:09:04