使用关系条件查询模型

时间:2017-11-10 14:17:05

标签: laravel eloquent

您好我正在制作一个包含类别,页面和横幅的webapp,可以根据类别选择在页面上显示。横幅应属于许多类别,因此我创建了一个数据透视表来连接横幅和类别。

关键是我可以轻松选择使用连接显示哪个横幅,但我希望以纯粹雄辩的风格进行。

我的模特

横幅

class Banner extends Model
{
    ...
    public function categories()
    {
        return $this->belongsToMany(Category::class, 'banner_category');
    }
}

分类

class Category extends Model
{
    ...
    public function banners(){
        return $this->hasMany(Banner::class, 'banner_category');
    }
}

此查询工作正常,但不是那么雄辩

$banners = \DB::table('banners')
            ->join('banner_category', 'banners.id', '=', 'banner_category.banner_id')
            ->where('banner_category.category_id',$category->id)
            ->where('banners.up_at','<=', $today)
            ->where('banners.down_at','>=', $today)
            ->where('visible', 1)
            ->get();

根据之前的研究,我尝试了几种方法,这些方法不起作用,包括以下

$banners = \App\Banner::where('visible', 1)
            ->where('up_at','<=', $today)
            ->where('down_at','>=', $today)
            ->with(['categories' => function($query) use($category->id)
                {
                    $query->where('category_id', '=', $category->id);
                }
            ])
            ->get();

任何建议将不胜感激。谢谢!

2 个答案:

答案 0 :(得分:2)

with函数只会过滤预先加载的结果,而不会过滤主结果集。您正在寻找的功能是whereHas。这只会选择与某种限制有关的结果。

$banners = \App\Banner::where('visible', 1)
    ->where('up_at','<=', $today)
    ->where('down_at','>=', $today)
    ->whereHas('categories', function($query) use ($category) {
        $query->where('category_id', $category->id);
    })
    ->get();

答案 1 :(得分:0)

看起来您的外键是banner_id,而不是banner_category。因此,您的模型应编辑如下:

class Banner extends Model
{
    ...
    public function categories()
    {
        return $this->belongsToMany(Category::class, 'banner_id');
    }
}

class Category extends Model
{
    ...
    public function banners(){
        return $this->hasMany(Banner::class, 'banner_id');
    }
}

这样您就可以使用 whereHas 功能查询模型:

$banners = \App\Banner::with('categories')->where('visible', 1)
            ->where('up_at','<=', $today)
            ->where('down_at','>=', $today)
            ->whereHas('categories', function($query) use ($category) {
                $query->where('category_id', '=', $category->id);
            })->get();

顺便说一句,这与你的&#34;加入查询&#34;不完全相同。因为在模型的结果中,类别的属性将在横幅模型结果中分组为类别变量:

$banners = [
    0 => [
        'id' => xxx,
        'other model fields' => 'its value',
        'categories' => [
            0 => First category model result,
            1 => Second related category,
            ...
        ],
    ...
]

因为在您的QueryBuilder结果中,您将在一行中找到两个模型属性:

$banners = [
    0 => [
        'id' => 'banner id',
        'other banners properties',
        'category properties',
    ],
    ...
]