Behavior events don't execute if there is a matched event in the model

I installed the ActiveRecordLogablebehavior and it didn't work.  After a while I narrowed the reason down to that afterSave() in the behavior was not even executing because I also had afterSave() defined in the model.

I think it should execute afterSave() in the behaviors regardless if it's also in the model.

Same with all the other events.

What needs to be decided is the order of execution of the events in the behaviors and models and how to treat their return values.

This is what i'm thinking:

For this example I will use beforeSave()

First execute model beforeSave().  and if it returns false, stop.

Execute behaviors' beforeSave() events one-by-one, stopping as soon as one of the events returns false.

The order the behaviors' events are executed  depends on the order they are attached.

I just realized a fix would be to call parent::beforeSave() in the model's beforeSave.

But I think that is to confusing… ??

I recall in CakePHP you did not have to call the parent events in order to get the behaviors to execute their corresponding events.

Yes, you need to call parent implementation. This is intentional. (In fact, calling parent implementation in an overridden method is quite common)

The reason for this design is that in case some AR really needs high performance, it can rewrite beforeSave() and other similar methods to disable raising events. Raising events takes time. Another benefit is it gives you freedom to control whether behavior should occur first or next.

Ok.  I guess I won't mind it anymore anyways once I get used to it.

I’m confused: :)

  1. Why parent::beforeSave()? Shouldn't it be $this->Owner->beforeSave() with behaviors?

  2. Not sure, if i understood, but is it correct that we have a problem, if we want to use multiple behaviors that all use beforeSave()? Wouldn't Owner->beforeSave() get called multiple times then (once for each behavior)?

What Jonah is talking about is overriding beforeSave() method in the AR class.

Yeah, example:


//does not perform any behavior() beforeSave methods

class Group extends CActiveRecord


	public function beforeSave() {



//does perform any behavior beforeSave() methods

class Group extends CActiveRecord


	public function beforeSave() {

		return parent::beforeSave();



Ok, thanks. That clarifies it.