简体   繁体   English

Laravel 7 eloquent 使用 pivot 进行过滤的嵌套条件

[英]Laravel 7 eloquent nested conditions for filtering with pivot

I am working on a project and got stuck in a situation.我正在做一个项目并陷入困境。 Let's say I have 4 tables;假设我有 4 张桌子; vendors, products, category_products (pivot), category.供应商、产品、category_products(枢轴)、类别。 Let's assume each table has this column below:假设每个表在下面都有这一列:

  • vendors id name etc.供应商 ID 名称等

  • products id vendor_id name stock etc.产品 id vendor_id 名称 库存等。

  • category_products id product_id category_id timestamps category_products id product_id category_id 时间戳

  • category id name类别 ID 名称

Models: Vendors型号:供应商

    public function products(){
        return $this->hasMany('App\Models\Sewa\Products', 'vendor_id')->with('product_images');
    }

Products产品

    public function product_category(){
        return $this->hasOne('App\Models\Sewa\ProductCategories', 'product_id');
    }

ProductCategories产品类别

    public function category(){
        return $this->belongsTo('App\Models\Sewa\Categories', 'category_id');
    }

    public function product(){
        return $this->belongsTo('App\Models\Sewa\Products', 'product_id');
    }

Category类别

    public function product_category(){
        return $this->hasMany('App\Models\Sewa\ProductCategories', 'category_id');
    }

I was trying to filter products from vendors by their category and price.我试图按类别和价格过滤来自供应商的产品。 But each product only has one category, but a category can be used in many products.但是每个产品只有一个类别,但一个类别可以用于许多产品。 What I did is:我所做的是:

$vendors = Vendors::with('products.product_category.category')->whereHas('products', function($query) use($request){
    if($request->category !== 'all'){
        $query->whereHas('product_category', function($query) use($request){
            $query->where('category_id', $request->category);
        });
    }

    if($request->price === 'low'){
        $query->whereBetween('price', [0, 10000]);
    }

    if($request->price === 'middle'){
        $query->whereBetween('price', [10000, 250000]);
    }

    if($request->price === 'high'){
        $query->where('price', '>', 250000);
    }
});

I tried to get category id = 1, but I got whole records.我试图让类别 id = 1,但我得到了全部记录。 I really don't know why it's ignored the where clause conditions.我真的不知道为什么它忽略了 where 子句条件。 What did I do wrong here?我在这里做错了什么?

Docs: https://laravel.com/docs/8.x/eloquent-relationships#constraining-eager-loads文档: https://laravel.com/docs/8.x/eloquent-relationships#constraining-eager-loads

use your constraints of the relations like this:使用您的关系约束,如下所示:

$vendors = Vendors::with(['products.product_category.category' => function($request){
    // your condition
}])->whereHas('products', function($query) use($request){
    if($request->category !== 'all'){
        $query->whereHas('product_category', function($query) 
use($request){
             $query->where('category_id', $request->category);
        });
    }

    if($request->price === 'low'){
        $query->whereBetween('price', [0, 10000]);
    }

    if($request->price === 'middle'){
        $query->whereBetween('price', [10000, 250000]);
    }

    if($request->price === 'high'){
        $query->where('price', '>', 250000);
    }
});

I got my answer thanks to my friend.感谢我的朋友,我得到了答案。 So basically, it's still a many-to-many relationship.所以基本上,它仍然是一个多对多的关系。 Correct me if I'm wrong.如我错了请纠正我。 I changed several things;我改变了几件事;

Model Model

Products产品

public function product_category(){
    return $this->hasMany('App\Models\Sewa\ProductCategories', 'product_id');
}

I changed hasOne() to hasMany() , but both works perfectly.我将hasOne()更改为hasMany() ,但两者都可以正常工作。 But in this case, my friend told me to use many-to-many relationships even though each product only has one category.但是在这种情况下,我的朋友告诉我使用多对多关系,即使每个产品只有一个类别。

Controller Controller

$vendors = Vendors::with(['products' => function($query) use($request){
    if($request->category !== 'all'){
        $query->whereHas('product_category', function($query) use($request){
            $query->where('category_id', $request->category);
        });
    }

    if($request->price === 'low'){
        $query->whereBetween('price', [0, 10000]);
    }

    if($request->price === 'middle'){
        $query->whereBetween('price', [10000, 250000]);
    }

    if($request->price === 'high'){
        $query->where('price', '>', 250000);
    }
}, 'products.product_category.category']);

This logic solved my problem.这个逻辑解决了我的问题。 Instead of using whereHas() in the first place, I use eager loading with conditions in it like @Psycho mentioned.我没有首先使用whereHas() ,而是使用像@Psycho 提到的那样带有条件的急切加载。 Thanks for my friend and @Psycho.感谢我的朋友和@Psycho。

Note: If this code looks 'messy' please let me know so I and everyone who reads this can improve to be a better programmer.注意:如果这段代码看起来“乱七八糟”,请告诉我,这样我和读到这篇文章的每个人都可以提高成为更好的程序员。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM