我正在开发 Laravel 应用程序,我需要根据标题与练习、测验和竞赛的关系来过滤标题。具体来说,我想检索具有相关实践但没有任何相关测验或竞赛的标题。但是,我遇到了一个问题,即同时具有练习和测验(或竞赛)的标题被排除在结果集中。
这是我的代码的简化版本:
public function index(Request $request): JsonResponse
{
$user = User::find(auth()->id());
// ... other request handling code
$titlesQuery = Title::with(['practices', 'quizzes', 'contests']);
if (!$user->is_accepted) {
$titlesQuery->whereHas('practices')
->whereDoesntHave('quizzes')
->whereDoesntHave('contests');
}
// Additional filters and search terms
return $titlesQuery->paginate($limit);
}
问题:
我面临的问题是,当我运行此查询时,任何包含测验的标题(即使它也有练习)都被完全排除在结果之外。我只想排除没有任何练习的带有测验或竞赛的标题,并仅在必要时返回练习。
示例场景 例如,如果我有以下记录:
标题 A 既有练习又有测验。
Title B 只有一个练习。
标题 C 有一个测验。
Title C 有一场比赛。
我希望返回我的查询:
标题 A(应返回练习并排除测验)
标题 B(应包含在内)
标题 C(不应包含在内,因为它是测验)
Title D(不应包含在内,因为这是一场竞赛)
其他信息
我的标题模型具有通过练习、测验和竞赛定义的关系。 我想维护稍后在查询中应用的其他过滤器(例如搜索、类别和子类别)。
我的模特关系:
//Title:
public function quizzes()
{
return $this->hasMany(Quiz::class);
}
public function practices()
{
return $this->hasMany(Practice::class);
}
public function contests()
{
return $this->hasMany(Contest::class);
}
//Quiz, Practice, Contest
public function title()
{
return $this->belongsTo(Title::class);
}
我尝试过的事情 我尝试重组我的查询,首先使用 whereHas 进行练习,然后使用 whereDoesntHave 进行测验和竞赛,但它仍然排除有测验的标题,而我只想在它们没有练习时排除它们。
我还尝试运行子查询,例如:
$titlesQuery->whereHas('practices')
->where(function ($query) {
// Exclude titles that have quizzes or contests
$query->whereDoesntHave('quizzes')
->whereDoesntHave('contests');
});
任何有关如何实现这一目标的指导将不胜感激!
你应该使用子查询,但不是你写的方式,试试这个方法:
$titlesQuery->whereHas('practices',function($q){
$q->whereDoesntHave('quizzes')
->whereDoesntHave('contests');
});