2016-07-31 47 views
0

Ich habe unten einige Codes meiner Anwendung hinzugefügt. Es zeigt nur den Namen der Produktkategorie und die Anzahl der Produkte an, die zu dieser Produktkategorie gehören. Es wirkt wie ein Zauber. Aber ich möchte den Kategorienamen und seine Produkte wiederbekommen, die nur zu bestimmten Städten gehören. Beispiel, ich möchte die Anzahl der Produkte bekommen, die zur Kategorie "Holz" gehören und in Baku liegen. Ich denke, dass ich einige Änderungen in der Funktion getActiveProducts() meines Modells vornehmen muss. Jede Hilfe wird geschätzt. Das sind meine Tabellen:Yii2 hasmany Zustand und mehrere Tabelle

Produkt

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 

Mein Controller:

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

anzeigen Code:

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

Und schließlich mein Product Modell:

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); 
} 

Antwort

1
  1. Relation functionActiveQuery Objekt zurückgeben sollte:

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

    Und fügen Sie nicht auf solche Funktionen alle anderen Bedingungen und Anweisungen (die Beziehungen erklären), und Sie werden es benutzen, die in solchen Verfahren wie ActiveQuery::link() und andere können.

  2. Sie können Ihre Beziehung in anderen Funktionen

    hier ist die Option für die Filterung Ergebnisse nach Stadt

    /** 
    * @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; 
    } 
    

    Unter der Annahme, wiederverwenden, dass Sie City Klasse und address Beziehung in Product Klasse.

    Die second parameter in joinWith deaktiviert eager loading, um unnötige zusätzliche Abfragen an Ihre DB zu vermeiden.

  3. Sie sollten nicht vollständigen Satz von Bezugsdatensätzen wählen ihre Zählung zu bekommen, anstatt ActiveQuery::count() Funktion:

    /** 
    * @param City|null $city get the count for particular city 
    * @return integer 
    **/ 
    public function getActiveProductsCount($city = null) { 
        return $this->getActiveProducts($city)->count(); 
    } 
    
  4. Verwendung $city Filter aus Ihrer Sicht

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

ps ich denke, dass Sie nicht joinWith in Ihrem Controller vornehmen müssen (wenn Sie es nicht für eine weitere Abfrage oder eager loading verwenden), nur alle Kategorien auswählen:

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

p.p.s. ich glaube hier, dass keine Notwendigkeit Array zu holen ist ein $key => $value, weil Sie das nicht $key verwenden

Hope this helps ...

+0

Ich löste diese Aufgabe durch eine andere Art und Weise, wenn Sie I'll wollen es teilen –

+0

@ShaigKhaligli Sie können diese Antwort mit Ihrer Lösung aktualisieren. Oder aktualisiere deine Frage. Es ist interessant, wie Sie es gelöst haben, und es kann für jemand anderen hilfreich sein – oakymax