Search code examples
laraveleloquenteloquent-relationship

Laravel: How to query a Model Relationship only if it exists


I have a model Survey with a column installer_id which is related to hasOne another model Installation which is related to hasMany another model Assignment.

I want to write a query to fetch all Survey where the installer_id is not null, and where IF an Assignment exists check all the assignments if any status is != 2 ie status = 0 or 1 return the survey.

I tried this query but it does not capture the "if an assignment exists then check the status" part

 $surveys = Survey::whereNotNull('installer_id')
            ->orWhereHas('installation',function ($query) {
                return $query->whereHas('assignments',function ($q){
                    return $q->where('status','!=', 2 );
                });
        })->get();

I also tried to define a hasManyThrough relationship in the model.

    public function assignments()
    {
        return $this->hasManyThrough(Assignment::class,Installation::class);
    }

and then using this query

 $schedulables = Survey::whereNotNull('installer_id')
            ->orWherehas('assignments',function ($query){
                return $query->where('assignments.status','!=', 2 );
            })->get()

Please any suggestions and help would be appreciated


Solution

  • Original answer

    What i needed was the whereDoesntHave method.

    $surveys = Survey::whereNotNull('installer_id')
        ->whereDoesntHave('installation.assignments', fn ($query) => $query->where('status', 2))
        ->get();