beforesave() in two different behaviors

hello community,

i’ve got the following problem:

I use two behaviors in a model, the zii CTimestampBehavior and another self coded one. Both behaviors contain a beforeSave() method. But it seems like only one of them is executed, because the CTimestampBehavior only works if i comment out the other one.

How can i bring yii to execute both ones?

sorry for my bad english ;)

greets

juri

The guide says that:

Anyway, I think you can call a behavior’s method with something like




$this->asa('CTimestampbehavior')->beforeSave();



So you can call both of them in the model’s ‘beforeSave’ method. Actually, ‘beforeSave()’ should return a boolean, so maybe you can end with something like:




public function beforeSave()

{

	if (parent::beforeSave())

	{

		return $this->asa('CTimestampBehavior')->beforeSave() && $this->asa('YourBehavior')->beforeSave();

	}

	else

	{

		return false;

	}

}



I don’t think it’s a good solution, though, maybe it’s better to wait for someone with more experience than me (I just started using Yii)

Many classes have a corresponding specialized behavior, f.e.

CActiveRecordBehavior works specifically for CActiveRecord classes.

This is done to implement some behavior methods not as a method but install it automatically as an event handler.

CActiveRecord has an event ‘beforeSave’.

You can add as many behaviors as you want to your AR object, all of them having a ‘beforeSave’ method. These are all installed as event handlers and will therefore all be executed.

You’re right. I tried with two CActiveRecordBehavior, both having an ‘afterDelete’ method, and they are both called :)

In my previous try, I had a CActiveRecordBehavior with an ‘afterDelete()’ method attached to my CActiverecord, and I declared another ‘afterDelete()’ in the model itself. In this case, the behavior’s method is not called (or at least in my case it wasn’t called), and that’s why I tried something like $this->asa(‘MyBehavior’)->afterDelete().

Thanks for the clarification.

Hi, due the fact that combined behaviour + event are difficult to understand (of course, for me…) can you share some code on how to do that? TIA :)

The before/after… methods in CActiveRecord have a different signature (protected instead of public) than the behavior event handlers by the same name.

If the protected parent methods cannot be reached there will be no events triggered.

http://www.yiiframework.com/doc/api/CActiveRecord#afterDelete-detail

/Tommy

Below are 2 sample behavior classes and an AR class to which those behaviors are attached.

The AR class implements a ‘onBeforeSave’ event which is triggered when the CActiveRecord->save() method is called.

CActiveRecordBehavior (which extends the base CBehavior class) has knowledge about the CActiveRecord events that can take place (like onBeforeSave, onAfterSave, onBeforeFind, …). This behavior class automatically attaches methods like beforeSave, afterSave, beforeFind, etc. as an event handler to their respective events. All you need to do is override those event handler methods and attach the behavior to the CActiveRecord object (see CActiveRecord::behaviors() ).




class User extends CActiveRecord

{

	// User table has the following fields (among others):

	// username

	// password

	// createdOn

	// updatedOn


	// attach behavior to this object

	public function behaviors()

	{

		return array(

			'CreateBehavior',

			'UpdateBehavior',

		);

	}


	public function model(...) {...}

	public function rules() {...}

	// Place any other methods here

}






class CreateBehavior extends CActiveRecordBehavior

{

	public function beforeSave($event)

	{

		if($this->isNewRecord)

			$this->createdOn=date('c');

	}

}






class UpdateBehavior extends CActiveRecordBehavior

{

	public function beforeSave($event)

	{

		$this->UpdatedOn=date('c');

	}

}



In the above example two event handlers are attached to the CActiveRecord object:

CreateBehavior::beforeSave($event) and

UpdateBehavior::beforeSave($event)

Thank you very much for your answers.

You’re absolutely right, i’ve made a logical mistake that let me think that not all were executed.