Yii2 有很多条件和多个 table

Yii2 hasmany condition and multiple table

我在下面添加了我的应用程序的一些代码。它仅显示 product_category 个属于此 product_category 的产品的名称和数量。它就像一个魅力。但是我想再次获取仅属于某个城市的类别名称及其产品。例如,我想获取属于 "Wooden" 类别且位于巴库的产品数量。我认为我必须对模型的 getActiveProducts() 函数进行一些更改。任何帮助表示赞赏。 这些是我的表格:

产品

id | name      | offer_category_id
-----------------------------
1  | Khar      |  3
2  | SantaCruz |  2
3  | Furniture |  2
4  | VT        |  1
5  | newFort   |  4

product_category

id | name
--------------
1  | Khar        
2  | Wooden 
3  | Sion       
4  | VT   
5  | newFort

product_adress

id | city     | offer_id
-----------------------------
1  | Baku      |  1
2  | Ismailly  |  2
3  | Absheron  |  5
4  | Paris     |  4
5  | Istanbul  |  3

我的控制器:

$data['productCategory'] = ProductCategory::find()
->joinWith('products')
->all();

查看代码:

<?php foreach($data['productCategory'] as $key=>$value):             
<li>
    <span class="m-offer-count"><?= $value->productsCount; ?></span>
</li>
<?php endforeach; ?>

最后是我的 ProductCategory 型号:

public function getActiveProducts() {
        $all_products = $this->hasMany(Product::className(),['product_category_id' => 'id'])->select(['id'])->where(['status'=>1])->all();
        return $all_product;
}
public function getProductsCount() {
        return sizeof($this->activeProducts);
}
  1. Relation function 应该 return ActiveQuery 对象:

    /**
     * @return \yii\db\ActiveQuery  
     **/
    public function getProducts() {
        return $all_products = $this->hasMany(Product::className(), ['product_category_id' => 'id']);
    }
    

    并且不要向此类函数(声明关系)添加任何其他条件和语句,您将能够在 ActiveQuery::link() 和其他方法中使用它。

  2. 您可以在其他函数中重用您的关系

    这是按城市过滤结果的选项

    /**
     * @param City|null $city filter result by city
     * @return \yii\db\ActiveQuery  
     **/
    public function getActiveProducts($city = null) {
        $query = $this->getActiveProducts()
            ->andWhere(['status' => 1]);
    
        if (!empty($city)) {
            $query->joinWith('address', false)
                ->andWhere(['address.city_id' => $city->id]);
        }
    
        return $query;
    }
    

    假设您在 Product class.

    中有 City class 和 address 关系

    second parameter in joinWith disables eager loading 避免对您的数据库进行不必要的额外查询。

  3. 您不应该 select 完整的相关记录集来获取它们的计数,而是使用 ActiveQuery::count() 函数:

    /**
     * @param City|null $city get the count for particular city
     * @return integer
     **/
    public function getActiveProductsCount($city = null) {
        return $this->getActiveProducts($city)->count();
    }
    
  4. 在您的视图中使用 $city 过滤器

    <?php foreach($data['productCategory'] as $category):             
    <li>
        <span class="m-offer-count">
            <?= $category->getActivePoductsCount($city); ?>
        </span>
    </li>
    <?php endforeach; ?>
    

p.s. 我认为您不需要在控制器中创建 joinWith (如果您不使用它进行进一步查询或eager loading), 仅 select 所有类别:

$data['productCategory'] = ProductCategory::find()->all();

p.p.s. 我相信这里不需要获取数组 a $key => $value 因为你不使用 $key

希望这对您有所帮助...