Laravel合并两个查询为一个,规避条件判断及无组织时报错
解决方案
原代码存在的问题
- 当ID对应的组织不存在时,
Organization::where('id', $id)->first()返回null,调用->specialties()会直接触发致命错误。 - 若组织无关联specialties,
$specialityOrg为空集合,此时$specialityAll未被定义,执行merge($specialityAll)会报错。 - 仅排除第一个关联specialty的名称,逻辑错误——应该排除所有与该组织关联的specialties,而非单个,且用
name做判断易出现重复值问题,用id更准确。
优化后的代码(无if语句,兼容组织不存在的情况)
// 先安全获取组织,避免空指针 $organization = Organization::find($id); // 获取该组织关联的specialties(组织不存在则返回空集合) $specialityOrg = $organization ? $organization->specialties->map(fn($specialty) => [ 'id' => $specialty->id, 'active' => $specialty->active, 'name' => $specialty->name ]) : collect(); // 获取所有未被该组织关联的specialties(组织不存在时返回所有root级specialties) $excludeIds = $specialityOrg->pluck('id'); $specialityAll = Speciality::root() ->when($excludeIds->isNotEmpty(), function ($query) use ($excludeIds) { return $query->whereNotIn('id', $excludeIds); }) ->get() ->map(fn($specialty) => [ 'id' => $specialty->id, 'active' => $specialty->active, 'name' => $specialty->name ]); // 合并两个集合 $speciality = $specialityOrg->merge($specialityAll); return view('organizations.speciality', compact('speciality'));
代码说明
- 用
Organization::find($id)替代where()->first(),语义更清晰,且返回null时不会触发后续方法调用错误。 - 用三元表达式处理组织存在/不存在的情况,直接返回对应集合,避免if分支。
- 用
when()方法动态添加查询条件,替代if语句:仅当有需要排除的ID时,才添加whereNotIn条件。 - 改用
id作为排除依据,避免名称重复导致的逻辑错误。
内容的提问来源于stack exchange,提问作者Waleedviews
相关产品推荐
相关产品推荐

