2012-03-28 10 views
0

virtualFields varをリンクテーブルのフィールドの合計にすることはできますか?例えば仮想フィールドはcakephpのリンクされたデータに基づいていますか?

は、請求書モデル、たとえば、で、あなたは

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

を持っていますが、明らかにそれだけで請求書に属している行を合計するだろうか?

ありがとうございました。

+0

すべての回答ありがとうございます。これは今、私ができるのではなく、「すべきか」と沸騰していると思います。これは、それぞれのアプリケーションに依存することを意味します。 – khany

答えて

0

afterFindコールバックを使用して合計を取得できます。これにより、計算された値の保存が回避されます。可能な場合は避ける必要があります。

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

計算された値を保存すると何が問題になりますか? IMOでは、データを必要とするたびに余計なクエリを実行するよりも、より良い方法です。 – Dave

+1

他のフィールドと値から計算された値を格納すると、計算結果と計算値の間の非同期が発生します。データベースがあなたのCakeアプリケーションとは別のスクリプトから変更された場合はどうなりますか?'beforeSave'は呼び出されず、計算された値は間違っていました。計算値の格納が本当に必要な場合は、データベース自体でトリガーを使用して計算を実行する方がよいでしょう。 – nIcO

+1

そのように思えるのは、アプリケーションとカウント/追加しているデータに大きく依存しています。しかし、私はいくつかのアプリケーションのためにあなたのポイントを参照してください。 – Dave

0

CakePHPの2.0を使用して

==は、私の知る限りでは、それを行うための最善の方法は、実際のtotalフィールドを持つようになり、いつでもデータが(afterSave callback methodとそう)に保存され、それを更新します。

したがって、InvoiceLineが保存されると、コードを実行して、関連付けられたInvoiceを新しい合計で更新します。

//InvoiceLine model 
public function beforeSave() { 
    //code to update Invoice's "total" field 
} 
0

理論的には、そのリンクされたテーブルが結合されたアソシエート(belongsToおよびhasOne)である場合は、はいです。

しかし、このテーブルを含めることを決定した場合、SQLエラーが生成される可能性があるため、これはお勧めできません。

データを取得するか、ネストされたSQLクエリである仮想フィールドを作成することをお勧めします。

0

より理にかなってそれぞれのモデルに仮想フィールドを定義します。

そうしないと、MVCパターンが破られます。

他の関連モデルからその仮想フィールドを使用することができます。

関連するすべてのモデルでそれらを使用したくない場合は、リレーションを定義しながらフィールド を使用することができます。あなたは仮想フィールド 公共$ belongsToの=配列( 'IwantVirtualField' =>配列( が 'className' => 'MyModel1'、 'フィールド' =>配列を望んでいないモデルでは

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

( 'MyModel1.id'、 'MyModel1.name') ... ) );

関連する問題