我有一个类似的疑问
$projects = Project::with('tasks')
->select('projects.*')
->join('tasks', 'projects.id', '=', 'tasks.project_id')
只有当任务处于特定状态(例如完成)时,我才需要加入。目前我正在尝试
$projects = Project::with('tasks', 'company')
->select('projects.*')
->join('tasks', 'projects.id', '=', 'tasks.project_id')
->where(function (Builder $query) use ($projectsListRequest){
if (empty($projectsListRequest->taskStatus))
return;
$query->where('tasks.status', $projectsListRequest->taskStatus);
})
但是它也会添加具有不同状态的任务。有什么办法可以解决这个问题吗?我猜连接需要另一个条件。
我猜无论我做什么,任务都会被预先加载,因为模型上的任务方法没有过滤器。但这只是猜测。
我看到您正在使用
tasks
关系。您可以使用此关系仅返回具有使用该whereHas
函数的某些任务的项目。whereHas
允许以某种方式更改查询,将结果限制为具有一个或多个相关模型的模型,在本例中Projects
为。Tasks
此函数至少需要一个参数,即关系,以及一个可选的闭包,可用于改变关系的查找查询。
你可以像这样使用它:
现在,您提到您需要“仅当任务完成时才加入”。这可以使用 Closure 参数来实现,我们可以在其中指定一些位置。
这将仅返回具有状态属性设置为 中的任何内容的任务的项目
$projectsListRequest->taskStatus
。if
此外,由于您在闭包中使用了,因此您可以when
在之前使用,whereHas
以便在中没有状态时不限制项目$projectsListRequest->taskStatus
。当条件为真时,此查询将如下所示
其功能与连接相同,但效率更高。
编辑
事实证明问题出在即时加载上。OP 只想即时加载具有特定状态的任务。
这可以通过将另一个参数传递给
with
函数来实现,该函数采用将用于获取预加载值的查询生成器。使用此查询生成器,我们可以更改查询以仅返回具有给定状态的任务