2012-03-28 9 views
0

Kann eine virtualFields-Variable die Summe eines Felds aus einer verknüpften Tabelle sein?Kann ein virtuelles Feld auf verknüpften Daten in CakePHP basieren?

Zum Beispiel in, sagen wir, ein Rechnungsmodell, könnten Sie haben

public $virtualFields = array(
    'invoiceNett' => 'SUM(InvoiceLine.nett)' 
); 

aber offensichtlich Summieren nur die Zeilen, die zu dieser Rechnung gehören?

Danke.

== Mit CakePHP 2.0

+0

Danke für alle Antworten. Ich nehme an, das läuft jetzt auf "sollte ich?", Anstatt "kann ich?". Das bedeutet, wie gesagt, es hängt von jeder Anwendung ab. – khany

Antwort

0

Sie könnten den afterFind Rückruf verwenden, um die Summe zu erhalten. Dies vermeidet die Speicherung der berechneten Werte, die nach Möglichkeit vermieden werden sollten.

function afterFind($results) 
{ 
    foreach($results as &$result) 
    { 

     /* 
     Use something like: 

     $this->InvoiceLine->find('all', array('fields'  => array('SUM(InvoiceLine.nett) as total'), 
               'conditions' => array('invoice_id' => $result['Invoice']['id']))); 
     */ 
    } 
    unset($result); 
} 
+0

Was ist falsch beim Speichern der berechneten Werte? IMO, es ist ein besserer Weg zu gehen als eine zusätzliche Abfrage jedes Mal, wenn Sie die Daten wollen. – Dave

+1

Das Speichern eines Wertes, der aus anderen Feldern und Werten berechnet wird, birgt das Risiko einer Desynchronisation zwischen dem berechneten Ergebnis und den berechneten Werten. Was passiert, wenn die Datenbank von einem anderen Skript als Ihrer Cake-App geändert wird?Der 'beforeSave' würde nicht aufgerufen und der berechnete Wert wäre dann falsch. Wenn das Speichern eines berechneten Werts wirklich benötigt wird, wäre es besser, einen Trigger in der Datenbank selbst zu verwenden, um die Berechnung durchzuführen. – nIcO

+1

Scheint, dass das stark von der Anwendung und den Daten abhängt, die Sie zählen/hinzufügen. Aber ich sehe Ihren Standpunkt für einige Anwendungen. – Dave

0

Soweit ich weiß, ist der beste Weg, dies zu tun wäre, um ein tatsächliches total Feld zu haben, und aktualisieren Sie es jederzeit die Daten gespeichert werden (wahrscheinlich mit einem afterSave callback method).

So - immer eine InvoiceLine gespeichert ist, führen Sie einen Code, um es zu aktualisieren ist Invoice mit einer neuen Summe.

0

Theoretisch, ja, wenn diese verknüpfte Tabelle eine assoziierte ist, die verbunden ist (belongsTo und hasOne).

Dies wäre jedoch eine schlechte Idee, denn wenn Sie sich entschließen, diese Tabelle nicht einzuschließen, würden Sie einen SQL-Fehler generieren.

Es wäre besser, wenn Sie eine separate Funktion verwenden, um die Daten zu erfassen oder ein virtuelles Feld zu erstellen, bei dem es sich um eine verschachtelte SQL-Abfrage handelt.

0

Definieren der virtuelle Feld in dem jeweiligen Modell mehr Sinn machen würde.

Wenn nicht, brechen Sie das MVC-Muster.

Sie können dieses virtuelle Feld von anderen verwandten Modellen verwenden.

Wenn Sie nicht möchten, dass sie in allen verwandten Modellen verwendet werden, können Sie beim Definieren von Relationen immer das Feld Attribut verwenden.

public $hasMany = array(
    'IwantVirtualField' => array(
     'className' => 'MyModel', 
     ... 
    ) 
); 

In einem Modell, in dem Sie nicht virtuelles Feld public $ belongsTo wollen = array ( 'IwantVirtualField' => Array ( 'classname' => 'MyModel1', 'Felder' => array ('MyModel1.id', 'MyModel1.name') ... ) );

Verwandte Themen