2017-02-01 3 views
1

Мне нужно подсчитать результаты из двух разных условий, исходя из того же отношения, но оно возвращается как одно и то же имя.Laravel multiple withCount на те же отношения

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?

ответ

3

Вариант 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') 
+2

Вариант 1 работал отлично. Большое спасибо Алексею. – Ben

Смежные вопросы