How to use where clause through relationships on Eloquent statically?

Viewed 35

In my Laravel app I have 3 model classes: Project, Task and TaskState. This is basically the code:

Project.php

class Project extends Model
{
    // ...

    public function tasks()
    {
        return $this->hasMany('App\Task');
    }
}

Task.php

class Task extends Model
{
    // ...

    public function project()
    {
        return $this->belongsTo('App\Project');
    }

    public function state()
    {
        return $this->hasOne('App\TaskState');
    }
}

TaskState.php

class TaskState extends Model
{
    // ...

    public function task()
    {
        return $this->belongsTo('App\Task');
    }
}

I want to filter all tasks on "open" state from a project. Now I'm using the join clause, but I want to know if it's possible using something like this:

Task::where('state.name', 'open')->get();

I don't understand why this doesn't work, because using the dot on where clauses is possible from "inside" the class. For example, from a getFooAtribute() method:

class Project extends Model
{
    // ...

    public function getOpenTasksSumAttribute()
    {
        // This works. Why not from outside?
        return $this->tasks->where('state.name', 'open')->count();
    }
}

Edit: The whereHas() method solved my problem.

Also the above getOpenTasksSumAttribute() method didn't work in fact, but it worked when I changed the Task model to return this->belongsTo('App\TaskState');.

1 Answers

Don't think any of them should work. Usually the approach is to use whereHas() to do conditional for relationships.

Task::whereHas('state', function ($query) {
    $query->where('name', 'open');
})->get();
Related