我正在使用多个相关模型构建一个不那么复杂的API,但是我似乎无法使whereHas过滤器按需工作。 所以我有一个像这样的结构:
Mapregions -> (hasMany) Subregions -> (hasMany) Countries
及以下:
Groups -> (hasMany) Brands -> (hasMany) Units
最后:
Unit -> (belongsTo) Country
我正在尝试查询所有的Mapregions并具有每个结构的计数,如下所示:
$mapregions = Mapregion::withCount(['groups', 'brands','units'])->orderBy('id');
这很好用;但是每当我想像这样过滤单位的国家时:
$mapregions = $mapregions->whereHas('countries', function($query) use ($filterCountries){
$query->WhereIn('countries.id', [2]);
});
我得到的结果是正确检索了地图区域,但单位计数与没有“国家/地区”过滤器时相同;每个“计数”和每个“地理位置”过滤条件都一样。
我尽了一切,但我想不出一个不肮脏的解决方案。 预先感谢
答案 0 :(得分:0)
更新: 因此,对于任何寻求解决方案的人;这个有效 这很丑陋,但可以正常工作。 首先,我过滤出Mapregions级别的结果:
$mapregions = $mapregions->WhereIn('id', $filterMap);
$mapregions = $mapregions->whereHas('subregions', function($query) use ($filterSub){
$query->WhereIn('id', $filterSub);
});
$mapregions = $mapregions->whereHas('countries', function($query) use ($filterCountries){
$query->WhereIn('GEO_COUNTRIES.id', $filterCountries);
});
然后我过滤每个withCount关系:
$mapregions->withCount(['groups' => function (Builder $query) use($filterMap, $filterSub, $filterCountries) {
if (!empty($filterMap)){
$query->whereIn('GEO_SUBREGIONS.mapregion_id', $filterMap);
}
if (!empty($filterSub)){
$query->whereIn('GEO_COUNTRIES.subregion_id', $filterSub);
}
if (!empty($filterCountries)){
$query->whereIn('GEO_COUNTRIES.id', $filterCountries);
}
}, 'brands'=> function (Builder $query) use($filterMap, $filterSub, $filterCountries){
if (!empty($filterMap)){
$query->whereIn('GEO_SUBREGIONS.mapregion_id', $filterMap);
}
if (!empty($filterSub)){
$query->whereIn('GEO_COUNTRIES.subregion_id', $filterSub);
}
if (!empty($filterCountries)){
$query->whereIn('GEO_COUNTRIES.id', $filterCountries);
}
},'units'=> function (Builder $query) use($filterMap, $filterSub, $filterCountries){
if (!empty($filterMap)){
$query->whereIn('GEO_SUBREGIONS.mapregion_id', $filterMap);
}
if (!empty($filterSub)){
$query->whereIn('GEO_COUNTRIES.subregion_id', $filterSub);
}
if (!empty($filterCountries)){
$query->whereIn('GEO_COUNTRIES.id', $filterCountries);
}
}]);
似乎工作正常。 如果有一种方法可以清除代码以避免重复过滤器,我将很高兴听到:)