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

Laravel中如何按复合条件筛选关联数据?

关联字段联合筛选失效问题

问题背景

现有代码仅能通过Task的title字段搜索数据,company_id的筛选无法生效。模型结构:

  • Category:id、name
  • Task:id、title、category_id、company_id
  • Company:id、name

现有Blade视图代码

<form action="/admin/manage" method="get">
    <!-- 按Task标题搜索 -->
    <input name="search_name" value="{{ request('search_name') }}">

    <!-- 按公司筛选 -->
    <select name="company_id">
        <option value="" {{ request('company_id') == '' ? 'selected' : '' }}>Select All</option>
        @foreach($companies as $company)
            <option value="{{ $company->id }}" {{ request('company_id') == $company->id ? 'selected' : '' }}>{{ $company->name }}</option>
        @endforeach
    </select>
    <button type="submit">筛选</button>
</form>

现有控制器代码

if($request->search_name || $request->company_id){
    $categories = Category::with(['tasks' => fn($query) => $query->where('title', 'like', '%' . $request->search_name . '%')])
                ->whereHas('tasks', fn ($query) => 
                $query->where('title', 'like', '%' . $request->search_name . '%')
                )->get();
}
else{
    $categories = Category::with('tasks')->get();
}

解决方案

核心是在关联查询的闭包里同时处理两个筛选条件,且通过判断参数有效性避免空值干扰。

修正后的控制器代码

// 初始化查询构造器
$categoriesQuery = Category::query();

// 处理标题搜索:参数存在且非空时添加筛选
if ($request->filled('search_name')) {
    $searchTerm = '%' . $request->search_name . '%';
    $categoriesQuery->whereHas('tasks', function ($query) use ($searchTerm) {
        $query->where('title', 'like', $searchTerm);
    });
}

// 处理公司筛选:参数存在且非空时添加筛选
if ($request->filled('company_id')) {
    $categoriesQuery->whereHas('tasks', function ($query) use ($request) {
        $query->where('company_id', $request->company_id);
    });
}

// 关联加载符合条件的tasks,同步应用筛选规则
$categories = $categoriesQuery->with(['tasks' => function ($query) use ($request) {
    if ($request->filled('search_name')) {
        $searchTerm = '%' . $request->search_name . '%';
        $query->where('title', 'like', $searchTerm);
    }
    if ($request->filled('company_id')) {
        $query->where('company_id', $request->company_id);
    }
}])->get();

代码说明

  1. 使用filled()方法判断参数是否存在且非空,避免空字符串或null导致的错误筛选
  2. 拆分两个筛选条件的逻辑,支持单独筛选或联合筛选两种场景
  3. with()关联查询同步应用筛选规则,确保返回的tasks数据与最终筛选结果一致
  4. 模块化的逻辑结构,后续新增筛选条件时扩展更便捷

内容的提问来源于stack exchange,提问作者Muhammad Trian Syahputra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 09:42:57