@OlegSedoy

Как построить запрос whereHas?

Есть телефонный справочник, модели Company - Departament - Worker.

Отношения
class Company extends Model
{
    public function departaments()
    {
        return $this->hasMany(Departament::class)->orderBy('sort');
    }
}

class Departament extends Model
{
    public function company()
    {
        return $this->belongsTo(Company::class);
    }

    public function workers()
    {
        return $this->hasMany(Worker::class)->orderBy('sort');
    }
}

class Worker extends Model
{
    public function departament()
    {
        return $this->belongsTo(Departament::class);
    }
}

Вывод справочника начинаю с компаний
@foreach($companies as $company)
	@foreach($company->departaments as $dapartament)
		@foreach($dapartament->workers as $worker)
			{{worker}}
		@endforeach
	@endforeach
@endforeach

Не могу сделать поиск по сотрудникам, чтобы вывод оставался тот же.

Делаю вот так
$this->companies = Company::whereHas('departaments.workers', function ($query){
            $query->where('email', 'like', "%{$this->searchTerm}%")
                    ->orWhere('position', 'like', "%{$this->searchTerm}%")
                    ->orWhere('surname', 'like', "%{$this->searchTerm}%");
        })->get();

Он работает, но так как нужно. Я получаю только компании, в которых найден сотрудник. В выводе появляются все отделы и сотрудники, а нужно, чтобы осталось только те компании и отделы, в которых найден сотрудник.
  • Вопрос задан
  • 886 просмотров
Решения вопроса 1
New_Horizons
@New_Horizons
Бред:
Company::with([
	'departaments' => function (HasMany $q) {
		$q->whereHas('workers', function (Builder $builder) {
			$builder->where('email', 'like', "%{$this->searchTerm}%");
			//остальные фильтры по workers
		});
	},
])->whereHas('departaments.workers', function (Builder $builder) {
	$builder->where('email', 'like', "%{$this->searchTerm}%");
	//остальные фильтры по workers
})->get();


Думаю что-то такое, но на работоспособность не проверял.
Смысл в том чтобы "жадно" загрузить только те департаменты, какие нужно. Для этого юзаем with(), в который передаём callback под ключом departaments

Дока: https://laravel.com/docs/9.x/eloquent-relationship...
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы