2010-07-08 3 views
1

J'ai un datamodel, disons: invoices (m:n) invoice_items et actuellement je stocke le total de la facture, calculée en PHP par un total invoice_items, dans une colonne de invoices. Je n'aime pas stocker des données dérivées car cela ouvre la voie à des erreurs plus tard.Colonne logique dans MySQL - Comment?

Comment puis-je créer une colonne logique dans le tableau invoices dans MySQL? Est-ce quelque chose que je ferais mieux de gérer dans le PHP (dans ce cas, CakePHP)?

Répondre

2

Leo,

Une chose que vous pouvez faire est de modifier le afterFind() dans votre modèle. Cela recalculerait le total chaque fois que vous récupéreriez une facture (coûtant le traitement de l'exécution), mais cela signifierait que vous ne le stockez pas dans la table des factures, ce que vous voulez éviter (corrigez si je me trompe).

Essayez ceci:

class Invoice extends AppModel { 
// .. other stuff 
function afterFind() { 
    parent::afterFind(); 
    $total = 0; 
    foreach($this->data['Invoice']['InvoiceItems'] as $item) 
    $total += ($item['cost'] * $item['quantity']); 

    $this->data['Invoice']['total'] = $total; 
} 
} 

j'ai foiré les tableaux sur la relation hasMany (la ligne foreach), mais j'espère que vous obtenez le jist de celui-ci. HTH,

Travis

+0

Ceci est une bonne suggestion. Bien qu'il y ait beaucoup d'enregistrements, cela pourrait devenir lourd, mais au moins c'est un 'CakeWay' –

+0

Je pense que je vais probablement aller avec ceci - merci. Au moins, je le ferai quand j'ai reconstruit ma boîte ubuntu qui a mystérieusement mangé environ 15Go de disque devant mes yeux. Pourrait être quelque chose à faire avec la sortie de courant que nous avions hier :( – Leo

+0

J'aime la façon dont cette solution fausse la table de la façon Cake – Leo

1

Soit vous pouvez retourner le dérivé un quand vous voulez via

SELECT COUNT(1) as total FROM invoice_items 

Ou si les factures peuvent être multiples,

//assuming that invoice_items.num is how many there are per row 
SELECT SUM(num) as total FROM invoice_items 

Ou vous pouvez utiliser une vue, si vous avez une certaine façon vous voulez qu'il soit représenté tout le temps.

+0

Cela fonctionne très bien, mais est la solution programatic. Existe-t-il un moyen de stocker cette requête en tant que colonne? – Leo

3

Il y a quelque chose appelé Les champs virtuels dans CakePHP qui vous permet d'obtenir le même résultat à partir de votre modèle au lieu de compter sur le soutien de MySQL. Les champs virtuels vous permettent de "mélanger" diverses données dans votre modèle et de fournir cela comme une colonne supplémentaire dans votre enregistrement. C'est plus propre que les autres approches ici ... (pas de afterFind() piratage).

En savoir plus ici: http://book.cakephp.org/view/1608/Virtual-fields

+0

1.3 seulement, mais mérite d'être connu. – Leo

Questions connexes