2016-07-19 5 views
0

Ich habe Order- und OrderSearch-Modelle.

In der Liste (actionIndex) mit GridView gibt es eine Filterung und Sortierung. Eine der Spalten in Order ist order_total (Summe aller Produkte in der richtigen Reihenfolge).

Ich muss SUM aller order_total in GridView implementieren. Wenn ich es manuell mache, indem ich ActiveDataProvider-> getModels() mit array_map zähle, verbringe ich 3 Sekunden für 3000 Aufträge (localhost). Ich möchte nicht so viel Zeit verpassen.

Ich sehe zwei Möglichkeiten, um es schneller zu machen:

  1. erstellen Cache für jeden Filter und aktualisieren Sie es durch Lebensdauer (schrecklich)
  2. Das interessanteste, dass ich es richtig in OrderSearch- tun können> Suche () Methode als $ query-Methode. Aber ich verstehe nicht, wie ich es in einem Controller weitergeben kann.

Beispiel für einen Code für die 2. Art und Weise:

class OrderSearch extends Order 
{ 

    public $totalSum; 

    public function search($params) 
    { 
     $query = Order::find(); 

     $dataProvider = new ActiveDataProvider([ 
      'query' => $query, 
     ]); 

     $this->load($params); 

     $this->totalSum = $query->sum('order_total'); // this works very fast 

     return $dataProvider; 
    } 

} 

Danach versuche ich diese Eigenschaft im Controller zu bekommen:

public function actionIndex() 
{ 
    $searchModel = new OrderSearch(); 
    $dataProvider = $searchModel->search(Yii::$app->request->queryParams); 

    $dataProvider->pagination->pageSize = 100; 

    // code below works too slow and depends on pagination page size 
    // $orders = $dataProvider->getModels(); 
    // $totalSum = 1.0; 
    // array_map(function($item) use (&$totalSum) { 
    //  $totalSum += (float)$item->attributes['order_total']; 
    // }, $dataProvider->getModels()); 

    // here I get an error 
    // Unknown Property – yii\base\UnknownPropertyException 
    // Getting unknown property: yii\data\ActiveDataProvider::totalSum 
    $totalSum = $dataProvider->totalSum; 

    return $this->render('index', [ 
     'searchModel' => $searchModel, 
     'dataProvider' => $dataProvider, 
     'totalSum' => $totalSum, 
    ]); 
} 

Wie kann ich benutzerdefinierte Eigenschaft für Data Provider festgelegt?

+3

Verwenden '$ totalSum = $ searchModel [ 'totalSum'];' in Ihrem Controller anstatt '$ totalSum = $ dataProvider-> totalSum;' –

+0

Vielen Dank! Es war einfacher als ich dachte :)))) – dearmisterrobot

Antwort

2

Sie schrieb:

$dataProvider = $searchModel->search(Yii::$app->request->queryParams); 

So $dataProvider die Rückkehr dieser Methode sein wird. Und, wie Sie hier sehen können:

public function search($params) 
{ 
    $dataProvider = new ActiveDataProvider([ 
     'query' => $query, 
    ]); 

    // code 

    return $dataProvider; 
} 

Verfahren search ist ein ActiveDataProvider zurück. Sie sollten nach dieser Methode verwenden, rufen Sie das Attribut der ursprünglichen Klasse:

$searchModel = new OrderSearch(); 
$dataProvider = $searchModel->search(Yii::$app->request->queryParams); // run search, so now we have a totalSum. 
$totalSum = $searchModel->totalSum; 
+0

danke! Das ist eine Entscheidung – dearmisterrobot

0

die $totalSum bekommen und ein Feld hinzufügen.

Änderung

$query = Order::find(); 

zu

$query = Order::find()->select(['*', 'totalSum' => new yii\db\Expression($totalSum)]); 

Uhr zu entkommen, wenn Sie Strings verwenden!

Sie könnten auch erwägen Unterabfragen verwenden, wie http://www.yiiframework.com/doc-2.0/guide-db-query-builder.html

z.B.

$subQuery = Order::find()->sum('order_total'); 
$query = Order::find()->select(['*', 'totalSum' => $subQuery]); 
Verwandte Themen