Usually you are not using CActiveRecord->updateAll() and CActiveRecord->deleteAll() without a limiting search condition.
While both of these functions allow you to specify a $condition as a parameter, they do not use the conditions and scopes that you may have defined on the model() as you might be expecting when you are used to findAll(), find(), etc.
This behavior is by design.
Fortunately, there is a way to workaround this.
The trick is to extract the criteria by using applyScopes(). The issue is that applyScope will suppose an alias 't' for the table. The updateAll() and deleteAll() methods do not apply an alias to the table you are updating to or deleting from. Therefore, the extra trick is to set the alias to the table's name before applying the scope.
It goes like this:
Alert::model()->getDbCriteria()->alias=AlertHistory::model()->tableName(); $criteria=new CDbCriteria(); Alert::model()->alert_id($alert_id)->is_ack(1)->forEntity($this->trackerId)->web()->applyScopes($criteria); Alert::model()->updateAll(array('is_ack'=>1),$criteria);
So the above first sets the alias, then sets the $criteria, and finally updates all the related records.
The issue with that is that you have to think about using applyScopes every time. And if you forget it, all your records will be updated (without taking the scopes into account).
Therefore, I prefer updating my models as follows. You can update your Gii basemodel so that it is automatically generated when you generate your models.
class Alerts extends CActiveRecord { [...] /** * Updates records with the specified condition. * * Modifies the standard method in that it takes into account the model conditions to select the records to update. * * @see CActiveRecord::updateAll() */ public function updateAll($attributes,$condition=array(),$params=array()) { //Next line must be added before defining the criteria/scopes. //Alerts::getDbCriteria()->alias=Alerts::model()->tableName(); $crit=new CDbCriteria($condition); $this->applyScopes($crit); return parent::updateAll($attributes,$crit); } /** * Deletes records with the specified condition. * * Modifies the standard method in that it takes into account the model conditions to select the records to update. * * @see CActiveRecord::updateAll() */ public function deleteAll($condition=array(),$params=array()) { //Next line must be added before defining the criteria/scopes. //Alerts::getDbCriteria()->alias=Alerts::model()->tableName(); $crit=new CDbCriteria($condition); $this->applyScopes($crit); return parent::deleteAll($crit); } }
With the above code, all you have to do now is this:
Alert::model()->getDbCriteria()->alias=AlertHistory::model()->tableName(); $criteria=new CDbCriteria(); Alert::model()->alert_id($alert_id)->is_ack(1)->forEntity($this->trackerId)->web()->->updateAll(array('is_ack'=>1));
And what is more is that if you forget to assign the alias, you will get an exception !
So, to help you update your Gii basemodel, here is the extract of what I put in my basemodel for gii (I use Awe/AweModel).
/** * Updates records with the specified condition. * * Modifies the standard method in that it takes into account the model conditions to select the records to update. * * @see CActiveRecord::updateAll() */ public function updateAll($attributes,$condition=array(),$params=array()) { //Next line must be added before defining the criteria/scopes. //<?php echo $modelClass;::getDbCriteria()->alias= echo $modelClass;::model()->tableName(); $crit=new CDbCriteria($condition); $this->applyScopes($crit); return parent::updateAll($attributes,$crit); } /** * Deletes records with the specified condition. * * Modifies the standard method in that it takes into account the model conditions to select the records to update. * * @see CActiveRecord::updateAll() */ public function deleteAll($condition=array(),$params=array()) { //Next line must be added before defining the criteria/scopes. // echo $modelClass;::getDbCriteria()->alias= echo $modelClass;::model()->tableName(); $crit=new CDbCriteria($condition); $this->applyScopes($crit); return parent::deleteAll($crit); }