Laravel模型关联链式查询无匹配结果时如何跳过对应if过滤条件
问题根因
- 现有代码的核心问题是Laravel查询构造器为可变对象:你在
if判断条件中直接对原查询对象$matches调用whereRelation后做计数,不管后续判断是否通过,这个过滤条件已经被写入原查询对象,只要某一个条件无匹配结果,该条件就会残留在查询逻辑中,最终导致返回空结果。
修复方案
判断过滤条件是否生效时,克隆一份当前的查询构造器做计数校验,避免污染原查询,只有对应条件有匹配结果时,才给原查询追加该过滤规则,修复后代码如下:
$matches = Property::with(['media', 'address', 'customer'])->where([ 'agency_id' => session('agency_id'), 'purpose' => $propertyRequirement->purpose, 'category_id' => $propertyRequirement->category_id, 'sub_category_id' => $propertyRequirement->sub_category_id, 'urgency' => $propertyRequirement->urgency ]) ->whereRelation('address', 'city', $propertyRequirement->propertyRequirementDetail->city) ->whereBetween('price', [$propertyRequirement->min_price, $propertyRequirement->max_price]) ->whereBetween('area', [$propertyRequirement->min_area, $propertyRequirement->max_area]); $filterCounter = 9; // location条件校验 if (!empty($propertyRequirement->propertyRequirementDetail->location)) { // 克隆查询做计数,不污染原对象 $tempQuery = clone $matches; if ($tempQuery->whereRelation('address', 'location', $propertyRequirement->propertyRequirementDetail->location)->count() > 0) { $matches->whereRelation('address', 'location', $propertyRequirement->propertyRequirementDetail->location); $filterCounter++; } } if ($propertyRequirement->category_id === 1) { // 最小卫生间数校验 if (!empty($propertyRequirement->propertyRequirementDetail->min_bathrooms)) { $tempQuery = clone $matches; if ($tempQuery->whereRelation('propertyDetail', 'bathrooms', '>=', $propertyRequirement->propertyRequirementDetail->min_bathrooms)->count() > 0) { $matches->whereRelation('propertyDetail', 'bathrooms', '>=', $propertyRequirement->propertyRequirementDetail->min_bathrooms); $filterCounter++; } } // 最大卫生间数校验 if (!empty($propertyRequirement->propertyRequirementDetail->max_bathrooms)) { $tempQuery = clone $matches; if ($tempQuery->whereRelation('propertyDetail', 'bathrooms', '<=', $propertyRequirement->propertyRequirementDetail->max_bathrooms)->count() > 0) { $matches->whereRelation('propertyDetail', 'bathrooms', '<=', $propertyRequirement->propertyRequirementDetail->max_bathrooms); $filterCounter++; } } // 最小房间数校验 if (!empty($propertyRequirement->propertyRequirementDetail->min_rooms)) { $tempQuery = clone $matches; if ($tempQuery->whereRelation('propertyDetail', 'rooms', '>=', $propertyRequirement->propertyRequirementDetail->min_rooms)->count() > 0) { $matches->whereRelation('propertyDetail', 'rooms', '>=', $propertyRequirement->propertyRequirementDetail->min_rooms); $filterCounter++; } } // 最大房间数校验 if (!empty($propertyRequirement->propertyRequirementDetail->max_rooms)) { $tempQuery = clone $matches; if ($tempQuery->whereRelation('propertyDetail', 'rooms', '<=', $propertyRequirement->propertyRequirementDetail->max_rooms)->count() > 0) { $matches->whereRelation('propertyDetail', 'rooms', '<=', $propertyRequirement->propertyRequirementDetail->max_rooms); $filterCounter++; } } // 停车位校验 if (!empty($propertyRequirement->propertyRequirementDetail->parking_space)) { $tempQuery = clone $matches; if ($tempQuery->whereRelation('propertyDetail', 'parking_space', $propertyRequirement->propertyRequirementDetail->parking_space)->count() > 0) { $matches->whereRelation('propertyDetail', 'parking_space', $propertyRequirement->propertyRequirementDetail->parking_space); $filterCounter++; } } // 建造年份校验 if (!empty($propertyRequirement->propertyRequirementDetail->year_build)) { $tempQuery = clone $matches; if ($tempQuery->whereRelation('propertyDetail', 'year_build', $propertyRequirement->propertyRequirementDetail->year_build)->count() > 0) { $matches->whereRelation('propertyDetail', 'year_build', $propertyRequirement->propertyRequirementDetail->year_build); $filterCounter++; } } } // 后续可正常调用 $matches->get() 获取结果
内容的提问来源于stack exchange,提问作者Abdul Rehman
相关产品推荐
相关产品推荐

