Question

I have a HAS_MANY relation called "relationName",

So I can get all related models using

$model->relationName;

or using

$model->getRelated('relationName');

I can also get a subset of relatedModels, by adding params

$model->getRelated('relationName', true, array('fieldName'=>'val'));

So, I will get a subset of all related models, which fieldName = "val"

but how can I count them?

This idea looks like bad one (because it will take all models and then count them):

count($model->getRelated('relationName', true, array('fieldName'=>'val')));

I need something which will finally build query with COUNT(), and return result.

Using STAT relation is also looks like bad idea (because I already described relation in code, why should I duplicate the description of relation?)

So, is there any good solution to count related (HAS_MANY) models with dynamic params?

Was it helpful?

Solution 2

Ok, so I had such models: Product (product_id) Order (order_id, product_id) OrderProduct (order_id, product_id)

Product model had relation

'orders'=>array(self::HAS_MANY,'Order',array('order_id'=>'order_id'),'through'=>'orderedProducts'),

My task was - to count each product->orders, without loading all orders models.

As Ross suggested, I created STAT relation

'statOrders'=>array(self::STAT,'Order',array('order_id'=>'order_id'),'through'=>'orderedProducts'),

Eventually when I called $product->statOrders, I got an exception CStatRelation has no 'through' attribute

enter image description here

Which means that if I want to make it work, I have to invent another way to describe relation between products and orders.. It's even worse than duplication.

Finally I came up with this workaround:

$c=$product->getRelated('orders', true, аггау('select'=>'CОUNТ(огdегѕ.огdег_іd) as order_id', 'gгоuр'=>'ргоduсt_іd'));
$count=$c[О]->order_id;

• No need to describe new relation

• It makes clean sql query:

system.db.CDbCommand.query(SELECT COUNT(orders.order_id) as order_id, `orders`.`order_id` AS `t1_c0` FROM `orders` `orders` LEFT OUTER JOIN `orders_products` `orderedProducts` ON (`orderedProducts`.`order_id`=`orders`.`order_id`) WHERE (`orderedProducts`.`product_id`=:ypl0) GROUP BY product_id. Bound with :ypl0='458739')

• You can dynamically add params: enter image description here

• By analogy you can count amount of products in orders (sum products quantity in each order): enter image description here

My current final solution: enter image description here

OTHER TIPS

If you want it to be run as a COUNT() query, your best option is to use a stat relation.

'countOfRelationName' => array(self::STAT, 'Relation', 'field', 'condition'=>'field = val')

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top