Order of afterSave() calls from ActiveRecord with Behavior

Hi,

I have a model with some relations which I save in the afterSave method of my model.




 protected function afterSave()

	{

       if($this->processAuthors())

          return parent::afterSave();

       else

          return false;

	}



I also have a behavior attached to that model which also should do something on the afterSave event.

E.g. send a email with the changed or entered data’s.

Now it looks like the afterSave of the model is called after the behavior’s afterSave. So my relation always shows the “old state” of the relation.

Is there a possibility to change this? Other than adding the relation process into a behavior or the behavior functionality into the afterSave method in the model?

thx in advance

best regards Horizons

The call to parent::afterSave() will fire the ‘OnAfterSave’ event which in turn will trigger the behavior’s afterSave method. So you can control it, by putting that call a little after what you want to do first.

Not sure, if that’s what you asked though - it’s not related to relations.

My Problem is it’s the other way around.

I also call return parent::afterSave(); in the behaviours.

in my model class Disseminations extends CActiveRecord




protected function afterSave()

{

  if($this->processAuthors())

    return parent::afterSave();

  else

    return false;

}



code in the behavior




class DisseminationsBehavior extends CActiveRecordBehavior {

  public function afterSave($event) {

   some code

   return parent::afterSave($event);     

  }

}



And the running order is DisseminationsBehavior ::afterSave before Disseminations::afterSave.

Hmm. Are you sure? If you look at the source of CActiveRecordsBehavior.php you’ll note, that afterSave() doesn’t do anything. In fact, you should not need to call parent::afterSave() in your behavior at all.

But it’s important that you call it in your model’s afterSave(). Can you please verify: Comment out the call to parent::afterSave() in your model and check wether your behavior’s afterSave() gets still called? It should not!

if i remove the aftersave in the model the behavior isn’t called.

Hmm thats strange, because i sent a email with some data from an relation of my model.

In my case the authors of the dissemination.

The authors of the edit / insert form are processed in the processAuthors() method.

I guess my problem is that the relation isn’t queried again.

I do show the insert / update form where the dissemination fields are filled and also saved. On the form there is also an authors list which the users can add. This authors are saved in processAuthors().

And in the behavior afterSave() I use the model fields and th relation ‘authors’ to fill an email with the data.

In the email the newer data of the model is set, but the relation shows the old state which was shown when the form was loaded. And doesn’t show the changed relations.

Is there something to ‘refresh’ the relation (query again?) after processAuthors() ?

Thx in advance ;)

I have it thx for pointing me at the right direction.

If i refresh the relation after the authors have changed i get the correct data.




if($this->processAuthors())

{

 $this->getRelated('authors', $refresh=true);

 return parent::afterSave();

}

 else

  return false;

}



EDIT:

just case someone has the same problem the relations isn’t refreshed when the model is in IsNewRecord state.

see issue:

http://code.google.com/p/yii/issues/detail?id=2111&q=horizons&colspec=ID%20Type%20Status%20Priority%20Milestone%20Owner%20Stars%20Summary

this can be currently only avoided through in afterSave().





          if($this->scenario=='insert')

          {

            $this->setIsNewRecord(false);

          }

 // refresh the relations used to have the updated data in the relations.

          $this->getRelated('authors', $refresh=true);

          if($this->scenario=='insert')

          {

            $this->setIsNewRecord(true);

          }




thx