CakePHP - how do I calculate the number of items for the corresponding model?

Models: stores and product , and they are related:

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

I want to get a list of all the stores and the number of products that they have. How can I change the call: $this->Store->find('all', array(<..some conditions..>)) to return this data type?

+7
source share
5 answers

One way is to use the built-in counterCache Cake option in your association. This is probably the most efficient option, although this requires adding a field to the table.

In the stores table, add an INT field called product_count

In your Product model, add the counterCache parameter to your association:

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

Whenever you add or remove Product records, it automatically updates the product_count field of the associated Store record, so there is no need to modify find operations.

Please note: if you choose this route, you need to manually update the product_count field so that the initial value is correct, since it is updated only after the add / remove operations.

+16
source

I believe something like the following will work, however I cannot check it out here. Content COUNT() may require customization to work with how Cake creates its requests.

 $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'), )); 
+3
source

Check out find('count') .

However, it may not scale well if you want to combine this data with storage data (see thealtomrose answer).

I am having problems using find('count') and grouping data. Unfortunately, this is one of those extreme cases when the frameworks that write requests for you fail.

+2
source

After CakePHP 2.0, you can also add conditions to your account and multiple counters per model .

Add any integer field to the Store , then use it in your Product model:

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

A simple find will select the data you need:

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

The number of products in one of the stores can be returned using the following code, where "0" can be replaced by the number of the storage array index:

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

If you want to count the number of products in each store, you can consider the cycle for all stores in this way:

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

Assumptions I make:

  • You want the quantity of goods in each store, not the quantity of goods in general.
  • You are not too concerned about work. If you have more than 50,000 records or so, you might consider pairing this back, but it will be much more complicated.
+1
source

All Articles