Hi all,
We are enforcing a data protection policy on our application where records get marked as "frozen" after a certain amount of time (frozen = 1 in table), meaning that they cannot be modified or deleted.
My first instinct was to use a named scope on all update/delete methods for AR records, but after testing, found that these methods to not respect named scopes (contrary to the changelog for 1.0.6). Here is some example code of what I was trying to do:
public function scopes()
{
return array(
'protectPolicy'=>array(
'condition'=>'frozen=0'
),
);
}
ImportantData::model()->protectPolicy()->updateAll(array('target_column'=>'new_value'));
Alas, all records get updated with this approach
I know I can extend ActiveRecord class and override all update*/delete* methods by copying the current code and adding my own lines as so:
public function updateAll($attributes,$condition='',$params=array())
{
Yii::trace(get_class($this).'.updateAll()','system.db.ar.CActiveRecord');
$builder=$this->getCommandBuilder();
$criteria=$builder->createCriteria($condition,$params);
//added by jreznik
if($this->hasAttribute('frozen'))
{
$criteria->mergeWith(array('condition'=>'frozen=0'));
}
$command=$builder->createUpdateCommand($this->getTableSchema(),$attributes,$criteria);
return $command->execute();
}
However, I would consider this “invasive” since I can’t call parent::updateAll(); (et al), because the added code needs to be in the middle, and any future updates in the framework to these methods won’t be used in my code since this is copied from the current version.
Is there a better, more elegant way of doing this? I only want this to apply to update*/delete* and NOT select.