使用whereHas / whereIn无法过滤withCount关系

时间:2019-09-16 17:02:42

标签: php laravel eloquent

我正在使用多个相关模型构建一个不那么复杂的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]);
});

我得到的结果是正确检索了地图区域,但单位计数与没有“国家/地区”过滤器时相同;每个“计数”和每个“地理位置”过滤条件都一样。

我尽了一切,但我想不出一个不肮脏的解决方案。 预先感谢

1 个答案:

答案 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);
    }
}]);

似乎工作正常。 如果有一种方法可以清除代码以避免重复过滤器,我将很高兴听到:)