2014-11-20 4 views
1

У меня есть три модели, провинции, Город и Работа.Родитель, Ребенок, Ребенок Ребенок в Laravel

Область имеет следующее:

public function cities() { 
    return $this->hasmany('City'); 
} 

Город имеет следующее:

public function province() { 
    return $this->belongsTo('Province', 'province_id'); 
} 

public function jobs() { 
    return $this->hasmany('Job'); 
} 

Работа имеет следующие:

public function city() { 
    return $this->belongsTo('City', 'city_id'); 
} 

Я пытаюсь получить общее количество рабочих мест в каждой провинции, а следующее не работает. Был бы признателен, если бы кто-нибудь мог указать, что я делаю неправильно?

$province->cities->jobs->count() 

Спасибо!

+0

Не совсем уверен, здесь, но '$ provice-> города() -> вакансии() -> Количество()' может работать и, если это произойдет, будет намного лучше производительность мудрым , – rmobis

+0

@Raphael_ Я тоже попробовал это раньше, к сожалению, не работал, дает следующую ошибку: Позвоните в неопределенный метод Illuminate \ Database \ Query \ Builder :: jobs() – sam

ответ

0

Это потому, что города являются Collection, вам нужно пройти через каждый из них, чтобы получить номер задания и добавить их.

Внутри контроллера: Вроде так;

$job_count = 0; 

$province->cities->each(function ($city) use ($job_count){ 
    $job_count += $city->jobs->count(); 
}); 

The $job_count будет равно общему числу рабочих мест в каждой из нее городов.

Обращаем ваше внимание, что ссылки на данные о товарах не будут загружены, чтобы уменьшить количество запросов, сделанных в вашей базе данных.

$province = Province::with('cities', 'cities.jobs')... 
+0

Спасибо Matt. Я пытаюсь получить общее количество рабочих мест для провинции, а не города. Какие-либо предложения? – sam

+0

@sam отредактировал ответ. –

+0

Блестящий! Спасибо вам за помощь, спасли мой день! – sam

2

Вы имеете готовый раствор в использовании в Eloquent, нет необходимости в загрузке всех и сложении count на сборниках.

// Province 
public function jobs() 
{ 
    return $this->hasManyThrough('Job', 'City'); 
} 

то просто:

$province->jobs()->count(); 

Он работает просто SELECT count(*) без загрузки избыточных коллекций.


Кроме того, если вам нужно нетерпеливая нагрузка, рассчитывать на сборе провинций, а затем использовать это:

public function jobsCount() 
{ 
    return $this->jobs()->selectRaw('count(*) as aggregate')->groupBy('province_id'); 
} 

public function getJobsCountAttribute() 
{ 
    if (! array_key_exists('jobsCount', $this->relations)) $this->load('jobsCount'); 

    return $this->getRelation('jobsCount')->first()->aggregate; 
} 

С этим вы можете легко получить счетчик для нескольких provinces сразу (только с 2 запросы выполняются):

$provinces = Province::with('jobsCount')->get(); 

foreach ($provinces as $province) 
{ 
    $province->jobsCount; 
} 
Смежные вопросы