fireball70's avatar

Relationship filtering

Can’t tackle with this:

  1. Hospital has many doctors.
  2. Doctors belongs to specialty.

Get all hospitals wich has at least one specialist from every id in array with specialty ids.

0 likes
3 replies
LaryAI's avatar
Level 58

To solve this problem, you can use the whereHas method in Laravel Eloquent to filter the hospitals based on the existence of related doctor models that belong to each specialty ID in the given array. Here's how you can do it:

$specialtyIds = [1, 2, 3]; // Replace with your array of specialty IDs

$hospitals = Hospital::where(function ($query) use ($specialtyIds) {
    foreach ($specialtyIds as $specialtyId) {
        $query->whereHas('doctors', function ($doctorQuery) use ($specialtyId) {
            $doctorQuery->where('specialty_id', $specialtyId);
        });
    }
})->get();

This code assumes that you have the following relationships set up in your Eloquent models:

class Hospital extends Model
{
    public function doctors()
    {
        return $this->hasMany(Doctor::class);
    }
}

class Doctor extends Model
{
    public function specialty()
    {
        return $this->belongsTo(Specialty::class);
    }
}

The whereHas method is used to filter the hospitals by checking if they have related doctors with the specified specialty ID. The loop ensures that this check is done for each specialty ID in the provided array. If a hospital does not have at least one doctor for each specialty ID, it will not be included in the result.

Keep in mind that this query can become quite complex and potentially slow if the array of specialty IDs is large or if there are many doctors and hospitals in the database. It's important to consider indexing and query optimization for production use.

gych's avatar

Have you already tried and created the relations ?

fireball70's avatar

@gych Yes, exactly as Lary's solution. I didn't try it yet, but I think it will work. I did not think of this solution and I think that there is a better approach.

Please or to participate in this conversation.