2011-11-17 3 views
7

I modelli sono: stores e product, e sono associati da:cakePHP - come posso contare gli articoli per un modello correlato?

var $belongsTo = array(
    'Store' => array(
    'className' => 'Store', 
    'foreignKey' => 'store_id' 
     )) 

var $hasMany = array(
    'Product' => array(
'className' => 'Product', 
'foreignKey' => 'store_id' 
    )) 

voglio ottenere un elenco di tutti i negozi e il conteggio dei prodotti che hanno. Come dovrei modificare la chiamata: $this->Store->find('all', array(<..some conditions..>)) per restituire quel tipo di dati?

+1

Quale versione di CakePHP? –

+0

cake v1.3 ....... – yossi

risposta

16

Un metodo è quello di utilizzare di Cake built-in counterCache opzione nella vostra associazione. Questa è probabilmente l'opzione più performante, anche se è necessario aggiungere un campo alla tabella.

nella tabella stores, aggiungere un INT campo chiamato product_count

nel modello Product aggiungere l'opzione counterCache alla vostra associazione:

var $belongsTo = array(
    'Store' => array(
    'className' => 'Store', 
    'foreignKey' => 'store_id', 
    'counterCache' => true 
)); 

Ogni volta che si aggiungono o eliminano Product record, verrà aggiornato automaticamente il campo product_count della registrazione associata Store, in modo che non sia necessario modificare le operazioni dello find.

Si noti che se si sceglie questo percorso, sarà necessario aggiornare manualmente il campo product_count per il valore iniziale per essere corretto, in quanto si aggiorna solo dopo le operazioni di aggiunta/eliminazione.

+2

+1 per insegnarmi qualcosa :) –

+0

Funziona automaticamente quando si cuoce un tavolo? – Dooltaz

1

Un semplice trovare tutte preleverà i dati necessari:

$Stores = $this->Store->find('all'); 

Numero di prodotti in uno dei negozi può essere restituito con il seguente codice dove '0' può essere sostituito con il numero del indice di matrice del negozio:

count($Stores[0]['Products']); //returns an integer 

Se si desidera che il conteggio dei prodotti in ogni negozio, si potrebbe prendere in considerazione un ciclo su tutti i negozi così:

foreach ($Stores as $Store) { 
    echo count($Store['Products']); 
} 

Ipotesi che sto facendo:

  1. Volete il conteggio dei prodotti in ogni negozio, non conta complessiva del prodotto.
  2. Non sei troppo interessato alle prestazioni. Se hai più di 50.000 record o giù di lì, potresti voler prendere in considerazione l'abbinamento, ma sarà molto più complicato.
2

Check out find('count').

Tuttavia, questo potrebbe non scala bene se state cercando di coppia questi dati con memorizzare dati (vedere la risposta da therealtomrose).

Ho avuto problemi nell'uso di find('count') e nel raggruppamento dei dati. Sfortunatamente questo è uno di quei casi limite in cui i framework che scrivono query per te falliscono.

3

Credo che qualcosa del genere potrebbe funzionare, tuttavia non posso testarlo da qui. Il contenuto di COUNT() potrebbe richiedere un aggiustamento per lavorare su come Cake costruisce le sue query.

$this->Store->virtualFields = array('product_count' => 'COUNT(Product.id)'); 
$this->Store->find('all', array(
    'fields' => array('Store.id', 'Store.product_count'), 
    'group' => array('Store.id'), 
)); 
2

Dopo CakePHP 2.0 è anche possibile aggiungere conditions al conteggio e multiple counters per model.

aggiungere qualsiasi campo intero alla vostra Store quindi utilizzare questo nel modello Product:

var $belongsTo = array(
    'Store' => array(
     'className' => 'Store', 
     'foreignKey' => 'store_id', 
     'counterCache' => array(
      'anyfield', array('Product.id >' => 0), 
      'stock' => array('Product.status' => 'stock') 
     ) 
    ) 
);