Yii2 按属性过滤器过滤产品

我有一个我想按属性过滤的产品数据库。我有一段产品。每个产品都应该有一组属性,例如颜色和重量。我有 3 个产品。第一个产品具有属性:颜色=红色,第二个产品具有颜色=红色和重量=1000kg,最后一个产品具有颜色=黑色;当我选择红色和黑色时,一切正常,但是当我选择红色和重量 1000 公斤的过滤器时,没有显示产品。这是我ProductSearch模型的一部分。


public function search($cat, $params=[])

{

    $query = Product::find();

    $query->joinWith(['productDesc','productCategory','productAttributes']);

    $query->andFilterWhere([

        'product.id'                => $this->id,

        'product.quantity'          => $this->quantity,

        'product.stock_status_id'   => $this->stock_status_id,

        'product.product_status_id' => $this->product_status_id

    ]); // and many more


    // Getting data from url: 

    // category?categories_path=some_category&f=6-Red;7-1000kg;&sort=price_vat

    if(isset($params['f'])) { 

        $filters_raw = explode(';', $params['f']);

        $filters_raw = array_filter($filters_raw);

        $attr_ids    = [];

        $attr_values = [];

        foreach ($filters_raw as $filter_arr) {

            $filters = explode('-', $filter_arr);

            $filter_results[$filters[0]][] = $filters[1];


        }

    }

    if(isset($filter_results)) {

        foreach ($filter_results as $attr_id => $filter_res) {

            $query->andFilterWhere([

                'and', 

                ['product_attribute.attribute_id' => $attr_id],

                ['product_attribute.value'        => $filter_res]

            ]);

        }

    }

}

怎么了?


一只萌萌小番薯
浏览 173回答 1
1回答

桃花长相依

如果一个产品可以有多个属性,简单的连接会为每个属性生成多行(因此一个产品可能会重复多次):| product.id | product_attribute.attribute_id | product_attribute.value || ---------- | ------------------------------ | ----------------------- || 1          | 120                            | red                     || 1          | 121                            | 1000kg                  |因此,如果您创建一个包含两个属性条件的查询,它们将永远不会被满足,因为没有任何行会匹配“颜色 = 红色和重量 = 1000kg”条件。您需要在一行中加入多个属性,以获得如下内容:| product.id | pa1.attribute_id | pa1.value | pa2.attribute_id | pa2.value || ---------- | ---------------- | --------- | ---------------- | --------- || 1          | 120              | red       | 121              | 1000kg    |为此,您需要删除带有属性的直接连接:$query->joinWith(['productDesc','productCategory']);并为每个过滤器分别连接每个属性:foreach ($filter_results as $attr_id => $filter_res) {    $query->joinWith("productAttributes as productAttributes{$attr_id}");    $query->andWhere([        "productAttributes{$attr_id}.attribute_id" => $attr_id,        "productAttributes{$attr_id}.value" => $filter_res,    ]);}
打开App,查看更多内容
随时随地看视频慕课网APP