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

Laravel Eloquent:按条件获取关联竞赛,无有效项则返回null

Laravel 关联模型筛选并处理空关联字段

我有一个Language模型集合,每个Language关联多个Competition模型。需求是:为每个Language获取endAt时间晚于或等于当前时间的有效竞赛;若不存在有效竞赛,则对应competitions字段设为null。

初始查询代码

$languages = $this->language->with('competitions')->get();

初始集合结果

[
    [
        'name' => 'english',
        'competitions' => [
            [ 'endAt' => '...' ],
            [ 'endAt' => '...' ],
        ],
    ],
    [
        'name' => 'indonesian',
        'competitions' => [
            [ 'endAt' => '...' ],
            [ 'endAt' => '...' ],
        ],
    ]
];

期望结果

[
    [
        'name' => 'english',
        'competitions' => null,
    ],
    [
        'name' => 'indonesian',
        'competitions' => [
           'endAt' => '...' 
        ],
    ]
];

尝试的无效代码

$languages = $this->language->whereHas('competitions', function (Builder $query) {
    $query->whereDate('endAt', '>=', Carbon::now());
})->get();

解决方案

你之前用whereHas的问题是,它会直接过滤掉没有符合条件竞赛的Language,而我们需要保留所有Language,只是处理关联字段。可以分两步实现需求:

  1. 用with的闭包筛选出每个Language下的有效竞赛
  2. 遍历集合,把空的竞赛数组转为null

代码实现:

use Illuminate\Database\Eloquent\Builder;
use Carbon\Carbon;

// 第一步:筛选有效竞赛
$languages = $this->language->with(['competitions' => function (Builder $query) {
    $query->whereDate('endAt', '>=', Carbon::now());
}])->get();

// 第二步:处理空关联为null
$languages = $languages->map(function ($language) {
    $language->competitions = $language->competitions->isEmpty() ? null : $language->competitions;
    return $language;
});

也可以合并为链式调用,更简洁:

$languages = $this->language
    ->with(['competitions' => fn(Builder $query) => $query->whereDate('endAt', '>=', Carbon::now())])
    ->get()
    ->map(fn($language) => tap($language, fn($lang) => $lang->competitions = $lang->competitions->isEmpty() ? null : $lang->competitions));

这样就能得到你想要的结果:所有Language都被保留,有有效竞赛的显示对应列表,没有的则competitions字段设为null。

内容的提问来源于stack exchange,提问作者R.M. Reza

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 05:55:45