雄辩的 ORM 查询仅返回在其集合中具有特定模型的模型
Posted
技术标签:
【中文标题】雄辩的 ORM 查询仅返回在其集合中具有特定模型的模型【英文标题】:Eloquent ORM query to return only models that have specific models in their collections 【发布时间】:2014-05-14 21:22:35 【问题描述】:我正在努力让 Eloquent ORM 产生我需要的结果。我有三个模型,作业、阶段和团队。
工作模式
public function phases()
return $this->hasMany('Eloquent\Models\Phase', 'job_id', 'job_id');
阶段模型
public function job()
return $this->belongsTo('Eloquent\Models\Job', 'job_id', 'job_id');
public function teams()
return $this->hasMany('Eloquent\Models\Team', 'phase_id', 'phase_id');
团队模型
public function phase()
return $this->belongsTo('Eloquent\Models\Phase', 'phase_id', 'phase_id');
当我执行查询时
$query = Eloquent\Models\Job::with("Phases.Teams");
$result = $query->get();
我有 40 个工作,其中包括 50 个阶段和 75 个团队。都很好。
当我执行查询时
$query = Eloquent\Models\Job::with(array("Phases.Teams" => function($query)
$query->whereRaw("teams.team_member_quota > 5");
));
我得到一个包含 40 个工作的集合,其中包括 50 个阶段和 20 个团队。似乎我仍然获得了所有的 Jobs 和 Phases,但只有团队被过滤掉了。
我想收集只有团队的 team_member_quota > 5 的作业,并且其中只有团队的 team_member_quota > 5 的阶段,以及阶段只有团队的 team_member_quota > 5.
Eloquent ORM 可以做到这一点吗?
【问题讨论】:
【参考方案1】:为此您需要whereHas
,但由于它不适用于嵌套关系,因此您需要手动嵌套:
$query = Eloquent\Models\Job::whereHas('phases', function($query)
$query->whereHas('teams', function ($q)
$q->whereRaw("teams.team_member_quota > 5");
);
)
// ->with('phases.teams') // if you still need to load all the relations
;
这将获取具有相关Phases
的Jobs
具有> 5 个成员的Teams
(如果需要,还可以加载这些作业的所有相关模型)
或者定义另一个hasManyThrough
关系:
// Job model
public function teams()
return $this->hasManyThrough('Team', 'Phase');
// then:
$query = Eloquent\Models\Job::whereHas('teams', function ($q)
$q->whereRaw("teams.team_member_quota > 5");
);
对于hasManyThrough
,您需要确保所有模型都定义了$primaryKey
,因为您似乎没有使用默认id
。
【讨论】:
谢谢,您的回答确实限制了那些包含 team_member_quota > 5 的团队的工作。但是,添加简单的 with('phases.teams') 导致这些工作中的所有阶段和团队被退回。但是,您的回答确实使我获得了正确的结果,非常感谢! 是的,当然,这就是您所要求的。如果您需要限制加载的团队也受到限制,只需在with
方法中添加您之前拥有的代码。如果你只需要加载团队,没有阶段,那么使用with(['teams' => function($q) ...
【参考方案2】:
这确实将作业限制为仅包含 team_member_quota > 5 的团队的作业
$query = Eloquent\Models\Job::whereHas('phases', function($query)
$query->whereHas('teams', function ($q)
$q->whereRaw("teams.team_member_quota > 5");
);
);
但是,添加“with”子句
$query->with('phases.teams');
仍会带回每个作业的所有阶段,无论它们是否包含符合条件的团队,以及这些阶段中的所有团队,无论他们的 team_member_quota > 5 与否。
我发现这个“with”子句有效
$query->with(array(
"phases" => function($q1)
$q1->whereHas('teams', function($q2)
$q2->whereRaw('teams.team_member_quota > 5');
);
,
"phases.teams" => function($q)
$q->whereRaw("teams.team_member_quota > 5");
));
仅提供包含符合条件的团队的阶段,以及结果中符合条件的团队。
【讨论】:
以上是关于雄辩的 ORM 查询仅返回在其集合中具有特定模型的模型的主要内容,如果未能解决你的问题,请参考以下文章
我可以在一个地方(一个模型)使用雄辩的ORM和查询生成器吗?