简体   繁体   English

Laravel Eloquent - 过滤器关系

[英]Laravel Eloquent - Filter Relationship

I have two main models in my Laravel project.我的 Laravel 项目中有两个主要模型。 ProductMaster is where the main product data is and Product is the model which holds the variation of each product and the price for each client. ProductMaster 是主要产品数据所在的位置,而 Product 是保存每个产品的变化和每个客户的价格的模型。 I am not allowed to change this model, in case you wonder.我不允许更改此模型,以防万一。

My question is how to make a eloquent query to get the ProductMaster data with Products that are filtered by client (and other parameters too).我的问题是如何进行雄辩的查询以获取包含由客户端(以及其他参数)过滤的产品的 ProductMaster 数据。 I tried whereHas but it didn't work.我试过 whereHas 但没有用。

This are my Models:这是我的模型:

namespace App\Models;
use Illuminate\Database\Eloquent\Model;

class ProductMaster extends Model
{
    protected $table = 'product_masters';

    protected $primaryKey = 'id';

    protected $fillable = ['code','title'];
    
    public function products(){
        return $this->hasMany(Product::class,'master_id');
    }
}


namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Models\ProductMaster;

class Product extends Model
{

    protected $table = 'products';
    protected $primaryKey = 'id';

    protected $fillable = ['sku', 'stock', 'brand', 'size', 'priceList', 'master_id', 'client'];

    public function productMaster(){
        return $this->belongsTo(ProductMaster::class,'master_id');
    }

}

And this is the query I tried to do:这是我试图做的查询:

        //QUERY WITH FILTERS
        $products = ProductMaster::whereHas('products', function($query) 
            use($filterBrand, $filterCats, $filterSizes, $clientCode)
            {
                $query->where('client', $clientCode);
                $query->whereIn('brand', $filterBrand);
                $query->whereIn('size', $filterSizes);
            })
        ->where('title', 'LIKE', '%' . $request->find . '%')
        ->orderby($order[0], $order[1])
        ->paginate(6)
        ->withQueryString();

This query works but I don't get exactly what I need.这个查询有效,但我没有得到我需要的。 This gives me all ProductMaster that have products where has that parameters, but in collection $products it puts ALL products that have that master_id and not only the products that has that parameters.这给了我所有具有具有该参数的产品的 ProductMaster,但在集合 $products 中,它放置了具有该 master_id 的所有产品,而不仅仅是具有该参数的产品。

This is the sql:这是sql:

select * from `product_masters` where exists (select * from `products` where `product_masters`.`id` = `products`.`master_id` and `client` = ? and `products`.`brand` in (?) and `category` in (?) and `client` = ?) and `title` LIKE ? order by `title` asc

Here is some sample data: SQL Fiddle这是一些示例数据: SQL Fiddle

Anyone can help me?任何人都可以帮助我吗? Thanks.谢谢。

If you want to filter the the products to eager load and also filter to load only the product masters that hace those products your query should be like this:如果您想过滤要预先加载的产品并过滤以仅加载拥有这些产品的产品母版,您的查询应该是这样的:


$products = ProductMaster::
with([
 'products' =>
 fn($query) => $query
 ->where('client', $clientCode)
 ->whereIn('brand', $filterBrand)
 ->whereIn('size', $filterSizes)
])
->whereHas('products', 
 fn($query) => $query
 ->where('client', $clientCode)
 ->whereIn('brand', $filterBrand)
 ->whereIn('size', $filterSizes)
)
        ->where('title', 'LIKE', '%' . $request->find . '%')
        ->orderby($order[0], $order[1])
        ->paginate(6)
        ->withQueryString();

You could even pass that query on both with and whereHas functions to a private function inside your controller to keep the clone more clean.您甚至可以将 with 和 whereHas 函数的查询传递给控制器​​内的私有函数,以保持克隆更干净。

Could you please try this and let me know if its working or not ?你能试试这个,让我知道它是否有效吗? And also I think you missed the category filtering in one of the whereIn clause.而且我认为您错过了 whereIn 子句之一中的类别过滤。

$q = ProductMaster::with('products')->where(function($query) use ($filterBrand, $filterCats, $filterSizes, $clientCode) {
     $query->whereHas('products', function($query) use ($filterBrand, $filterCats, $filterSizes, $clientCode) {
        $query->where('client', $clientCode);
        $query->whereIn('brand', $filterBrand);
        $query->whereIn('size', $filterSizes);
        $query->whereIn('category', $filterCats);
    });
 });

 $products = $q->where('title', 'LIKE', '%' . $request->find . '%')
                ->orderby($order[0], $order[1])
                ->paginate(6)
                ->withQueryString();

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

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