I’m new to yii framework and i’ve been having problems regarding saving on a specific model.
Here’s the scenario.
I have a table of prices and there’s a condition that there should only be 1 record in the prices table
that has a is_current field with a value of 1, so every other record should have a value of 0. here’s my before save function
public function beforeSave(){
//this record is always new
$this->created_by = Yii::app()->user->id;
//get current price then reset the is_current field
$current_price = ProductPrice::model()->findByAttributes(array('is_current' => 1,'product_id' => $this->product_id));
$current_price->is_current = 0;
$current_price->save();
return parent::beforeSave();
}
the model is ProductPrice so the $current_price is in the beforeSave function of the ProductPrice.
Im getting Fatal error: Maximum execution time of 30 seconds exceeded. i think its calling the beforeSave() over and over again.
could you post beforeSave, afterSave method of ProductPrice Model (is exists in your code) ?
Also the correct way is
public beforeSave(){
if(parent::beforeSave()){
{
//this record is always new
$this->created_by = Yii::app()->user->id;
//get current price then reset the is_current field
$current_price = ProductPrice::model()->findByAttributes(array('is_current' => 1,'product_id' => $this->product_id));
$current_price->is_current = 0;
$current_price->save(); //may should it returns false in not succeed
return true;
}
return false;
}
Yes, $current_price->save() will call beforeSave before saving. And because it is not yet saved, findByAttributes() will find itself as the one to be modified. And it tries to modify it and save, and beforeSave is called before saving, and …
public function beforeSave(){
//this record is always new
$this->created_by = Yii::app()->user->id;
ProductPrice::model()->updateAll(array('is_current' => 0),
'is_current = 1 AND product_id = :product_id',
array(':product_id' => $this->product_id));
return parent::beforeSave();
}
IIRC, CActiveRecord::updateAll() will not call beforeSave, because it doesn’t fetch the records into AR objects.
Thanks for the reply. so my guess was right after all… anyway i already figured out another solution to the problem. I’ll just store an instance of the old price object with is_current set to 1 in the controller then after saving the new price i’ll replace the value of the old price object to 0 and save it.