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

Laravel搜索功能优化:隐藏skill为空的Worker数据及JSON空字段

解决Laravel搜索中Skill为空数组的Worker不显示问题

我来帮你搞定这个问题!你现在遇到的核心问题是:whereHas('skill')只是检查Worker是否存在任意Skill关联,但你在with里又过滤了特定sub_skill_id的Skill,导致有些Worker虽然有其他Skill,但没有匹配你要找的sub_skill_id,所以返回的Skill数组是空的,但Worker本身还是被查出来了。

解决方案:同步whereHas和with的过滤条件

要让只有包含匹配sub_skill_id的Skill的Worker才被返回,你需要把whereHas的闭包条件和with里的保持一致,这样就能确保查询出来的Worker一定有符合条件的Skill,不会出现Skill为空数组的情况。

修改后的控制器代码如下:

$subSkillId = $request->input('sub_skill_id');

$workers = Worker::with(['skill' => function($query) use ($subSkillId) {
    $query->where('worker_skills.sub_skill_id', $subSkillId);
}])
->whereHas('skill', function($query) use ($subSkillId) {
    $query->where('worker_skills.sub_skill_id', $subSkillId);
})
->get();

如果你的Laravel版本支持短闭包(Laravel 8+),可以简化成更简洁的写法:

$subSkillId = $request->input('sub_skill_id');

$workers = Worker::with(['skill' => fn($q) => $q->where('sub_skill_id', $subSkillId)])
    ->whereHas('skill', fn($q) => $q->where('sub_skill_id', $subSkillId))
    ->get();

这样修改后,只有那些拥有匹配sub_skill_id的Skill的Worker才会被查询出来,它们的skill字段也会正确加载对应的关联数据,不会出现空数组的情况。


额外问题:如何在JSON中隐藏空字段

如果在其他场景下,你需要隐藏模型中空的关联字段或属性,可以用以下几种方法:

1. 使用模型的$hidden属性(全局隐藏)

在Worker模型中定义$hidden数组,指定默认要隐藏的字段:

class Worker extends Model
{
    protected $hidden = ['skill']; // 默认隐藏skill字段
}

不过这种方法是全局的,如果你需要动态控制,推荐下面的方法。

2. 使用makeHidden()方法(动态隐藏)

在查询结果后,动态隐藏空的字段:

$workers = $workers->map(function($worker) {
    if ($worker->skill->isEmpty()) {
        $worker->makeHidden('skill');
    }
    return $worker;
});

3. 使用API资源(推荐用于API场景)

创建一个WorkerResource类,在资源里控制返回的字段:

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class WorkerResource extends JsonResource
{
    public function toArray($request)
    {
        $data = [
            'id' => $this->id,
            // 其他Worker字段...
        ];

        // 只有当skill非空时才添加到返回数据中
        if (!$this->skill->isEmpty()) {
            $data['skill'] = $this->skill;
        }

        return $data;
    }
}

然后在控制器中返回资源集合:

return WorkerResource::collection($workers);

这样就能灵活控制JSON返回的字段,空的关联字段不会出现在响应中。

内容的提问来源于stack exchange,提问作者Nasihun Amin Suhardiyan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:13:45