使用 Eloquent 在 Laravel 中使用 where 子句访问嵌套的相关对象
Access nested related objects with where clause in Laravel using Eloquent
我正在尝试获取与特定客户端关联的任务列表,但任务与客户端之间没有直接关系。我还需要根据任务状态和项目状态过滤那些任务。
这是我的模型:
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
。
目标是 return 状态为 'open' 并且是客户拥有的项目的子项的任务列表。
基本上,我想写这样的东西:
$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 的查询生成器解决它,但我想要一个直接使用 Eloquent 的 ORM 的解决方案。
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 nested relationships
您要找的是whereHas
。它可以让你查询 "results based on the existence of a relationship".
您可以尝试类似的方法:
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();
但是不完全确定这是否可行。
我正在尝试获取与特定客户端关联的任务列表,但任务与客户端之间没有直接关系。我还需要根据任务状态和项目状态过滤那些任务。
这是我的模型:
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
。
目标是 return 状态为 'open' 并且是客户拥有的项目的子项的任务列表。
基本上,我想写这样的东西:
$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 的查询生成器解决它,但我想要一个直接使用 Eloquent 的 ORM 的解决方案。
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 nested relationships
您要找的是whereHas
。它可以让你查询 "results based on the existence of a relationship".
您可以尝试类似的方法:
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();
但是不完全确定这是否可行。