Laravel与同一关系上的多个withCount

时间:2017-02-01 17:09:26

标签: php laravel laravel-5 relationship laravel-5.3

我需要从两个不同的条件中计算结果,来自相同的关系,但它将以相同的名称返回。

Model::where('types_id', $specialism_id)
        ->withCount(['requests' => function ($query) {
            $query->where('type', 1);
        }])
        ->withCount(['requests' => function ($query) {
            $query->where('type', 2);
        }])

我可以使用withCount访问$model->requests_count,但因为它正在查询相同的关系,所以它似乎会覆盖它:

select count(*) 
    from `requests` where `requests`.`id` = `model`.`id` 
    and `type` = '1') as `requests_count`, 
(select count(*) from `requests` where `requests`.`id` = `model`.`id` 
    and `type` = '2') as `requests_count`

如何指定多个withCount的名称?

2 个答案:

答案 0 :(得分:4)

选项1

创建两种不同的关系:

public function relationship1()
{
    return $this->hasMany('App\Model')->where('type', 1);
}

public function relationship2()
{
    return $this->hasMany('App\Model')->where('type', 2);
}

并使用它们:

Model::where('types_id', $specialism_id)->withCount(['relationship1', 'relationship2'])

选项2

创建withCount()类似方法,该方法将使用自定义名称构建属性:

public function withCountCustom($relations, $customName)
{
    if (is_null($this->query->columns)) {
        $this->query->select([$this->query->from.'.*']);
    }
    $relations = is_array($relations) ? $relations : func_get_args();

    foreach ($this->parseWithRelations($relations) as $name => $constraints) {
        $segments = explode(' ', $name);
        unset($alias);
        if (count($segments) == 3 && Str::lower($segments[1]) == 'as') {
            list($name, $alias) = [$segments[0], $segments[2]];
        }
        $relation = $this->getHasRelationQuery($name);
        $query = $relation->getRelationCountQuery(
            $relation->getRelated()->newQuery(), $this
        );
        $query->callScope($constraints);
        $query->mergeModelDefinedRelationConstraints($relation->getQuery());
        $column = $customName; <---- Here you're overriding the property name.
        $this->selectSub($query->toBase(), $column);
    }
    return $this;
}

并使用它:

Model::where('types_id', $specialism_id)
    ->withCountCustom(['requests' => function ($query) {
        $query->where('type', 1);
    }], 'typeOne')
    ->withCountCustom(['requests' => function ($query) {
        $query->where('type', 2);
    }], 'typeTwo')

答案 1 :(得分:2)

您现在可以这样做

Model::where('types_id', $specialism_id)
    ->withCount(['requests as requests_1' => function ($query) {
        $query->where('type', 1);
    }, 'requests as requests_2' => function ($query) {
        $query->where('type', 2);
    }])