2016-07-31 98 views
0

我在下面添加了我的应用程序的一些代码。它仅显示属于此product_category的product_category名称和产品数量。它像一个魅力。但我想重新获得仅属于某个城市的分类名称及其产品。例如,我想获得属于“木制”类别并位于巴库的产品数量。我认为我必须对模型的getActiveProducts()函数进行一些更改。任何帮助表示赞赏。 这些都是我的表:Yii2 hasmany条件和多表

产品

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; ?> 

最后我产品分类型号:

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
  1. Relation function应该返回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; 
    } 
    

    假设你有City类和Productaddress关系过滤结果的选项。

    second parameter in joinWith禁用eager loading可避免不必要的额外查询到您的数据库。

  3. 你不应该选择全套的相关记录,以获得他们的数量,使用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; ?> 
    

PS我认为你不需要做joinWith在你的控制器(如果你不使用它作进一步的查询或eager loading),只需选择所有类别:

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

p.p.s.我认为,这里没有必要,因为你不使用$key

希望这有助于获取数组$key => $value ......

+0

我用另一种方式解决了这个任务,如果你想我心底分享 –

+0

@ShaigKhaligli你可以用你的解决方案更新这个答案。或者更新你的问题。你如何解决这个问题很有意思,并且对别人有帮助 – oakymax