根据子存在和列值过滤多对多关系

时间:2019-03-08 14:27:42

标签: laravel eloquent

我已经搜索了一段时间,却找不到答案,这就是我的意思:

1- ShowCategory(ID和标题)

class ShowCategory extends Model
{
    public function shows()
    {
         return $this->belongsToMany(Show::class, 'category_show');
    }
}

2-显示(id,标题和有效的)

class Show extends Model
{
    public function categories()
    {
        return $this->belongsToMany(ShowCategory::class, 'category_show');
    }
}

因此存在多对多关系,我需要检索所有至少具有一个与之相关的Show的ShowCategory元素,并按show.active过滤每个ShowCategory-> shows,仅返回有效的show

这就是我想要做的:

 $categories = ShowCategory::whereHas('shows', function($query) {
        $query->where('shows.active', '=', true);
    })->get();

它仅过滤包含节目的ShowCategory,如果只有其中一个节目处于活动状态,它将返回类别,其中包含所有节目,即使其他不活动的我也要过滤那些不活动的节目。

我该怎么办?预先感谢

3 个答案:

答案 0 :(得分:2)

这需要whereHas()with()的组合。首先,whereHas()会将ShowCategory模型过滤为具有有效Show的模型,而with()子句将关系的结果限制为仅返回{{1} }个:

active

注意:您应该可以使用$categories = ShowCategory::whereHas("shows", function($subQuery) { $subQuery->where("shows.active", "=", true); // See note })->with(["shows" => function($subQuery){ $subQuery->where("shows.active", "=", true); }])->get();' 而不是active,但要取决于该列是否在多个表上。

使用该查询,您将获得shows.activeCollection模型,每个模型都已经加载了有效的ShowCategory模型并可以通过Show使用:

->shows

答案 1 :(得分:0)

这就是您所需要的。

$categories = ShowCategory::whereHas('shows', function($query) {
    $query->whereActive(true);
})->get();

答案 2 :(得分:-1)

尝试,这可能是检索相关结果的一种可能方法。

// This will only return ShowCategory which will have active shows.
/* 1: */ \ShowCategory::has('shows.active')->get();

// So, logically this will only have active shows  -__-
$showCategory->shows

Laravel可以通过使用这种.符号来扩展外交关系。

更新

您应将\ShowCategory模型更新为

 public function shows(){
     return $this->belongsToMany(Show::class, 'category_show')->where('active', true);
 }