Доступ к вложенным связанным объектам с помощью оператора where в Laravel с помощью Eloquent - PullRequest
2 голосов
/ 13 февраля 2020

Я пытаюсь получить список задач, связанных с указанным c клиентом, но нет прямой связи между задачей и клиентом. Мне также нужно отфильтровать эти задачи на основе статуса задачи и статуса проекта.

Вот мои модели:

class Client extends Model
{
    // Fields ['id']
    public function projects()
    {
        return $this->hasMany('App\Project');
    }
}

class Project extends Model
{
    // Fields ['id', 'client_id', 'status']
    public function client()
    {
        return $this->belongsTo('App\Client');
    }
    public function tasks()
    {
        return $this->hasMany('App\Task');
    }
}
class Task extends Model
{
    // Fields ['id', 'project_id', 'status']
    public function project()
    {
        return $this->belongsTo('App\Project');
    }
}

В моем контроллере у меня есть прямой доступ к Client $client из запроса .

Цель состоит в том, чтобы вернуть список задач, которые имеют статус «открытые» и являются дочерними элементами проектов, принадлежащих клиенту.

В принципе, я хочу написать что-то вроде этого :

$client->projects->where('status', 'active')->tasks->where('status', 'open');

И я хочу получить обратно то, что получил бы из этого запроса:

SELECT * FROM tasks AS t 
    WHERE t.status='open' 
    AND t.project_id IN (
        SELECT id FROM projects AS p 
            WHERE p.status='active' 
            AND p.client_id=1
    );

Мне удалось решить его с помощью Laravel Query Builder. , но мне нужно решение, которое использует ORM Eloquent напрямую.

DB::table('tasks')
    ->join('projects', function($join) use ($client) {
        $join->on('projects.id', '=', 'tasks.project_id')
            ->where('projects.client_id', '=', $client->id);
    })->select('tasks.*')->get();

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

Смежные вопросы:

laravel orm: где условие на таблице -> связанная таблица -> связанная таблица

Laravel вложенные отношения

1 Ответ

1 голос
/ 13 февраля 2020

То, что вы ищете, это whereHas. Он позволяет запрашивать «результаты, основанные на существовании отношений».

Вы можете попробовать что-то вроде:

Task::where('status', 'open')
    ->whereHas('project', function ($query) use ($client) {
        $query->where('client_id', $client->id)
            ->where('status', 'active');
    })
    ->get();

hasManyThrough также применяется к этой структуре :

// In Client.php
public function tasks()
{
    return $this->hasManyThrough(Task::class, Project::class);
}

$client->tasks()
    ->where('projects.status', 'active')
    ->where('tasks.status', 'open')
    ->get();

Однако не совсем уверен, сработает ли это.

...