Calling save within aftersave

Can I call a models save method inside the afterSave method?

There’s a directory path based on the primary key, so an uploaded file can’t be saved until the primary key exists.

The only concern I have is the isNewRecord property. If I save within afterSave it won’t have been set to false yet, will that make the save method attempt to do an insert instead of a delete? Also, if it isn’t false it would cause a loop everytime it hits afterSave.



Would manually setting isNewRecord to false take care of all that, or is there anything else that would need to be set?

Never tried that…I would go with saveAttributes() after a successfull save()… and if needed use a transaction…

But in your case there is no concern with the isNewRecord… you get the primary key value before afterSave()… so you can use it to update the record… but on that update use saveAttributes() this way you prevent the calling of afterSave() again… as per documentation saveAttributes() does not call before/afterSave()


Edit: Just noticed that Mike is right… if you dont set isNewRecord to false… saveAttributes() would add a new record… so you can set isNewRecord to false and call saveAttributes() or use updateByPk() that again does not call before/afterSave()

You could set isNewRecord to false and then use $this->saveAttributes(array(…)) to only update the attributes you need. It will not call afterSave again.

Ah, saveAttributes(), how’d I miss that, good to have. There were a couple places where I just used command builder to save a single attribute instead. That’ll be useful.

OTOH, in this case, I used setIsNewRecord(false) in afterSave and called save again and it worked just fine. The reasoning was for new records I had the code in afterSave, but for updates I had it in beforeSave, so it was duplicated and I simply wanted to reuse the code. Of course, in actually writing it out here, I’m thinking I could have just as easily created a new method an called it in both methods, or just saved both cases in afterSave. Oh, and it is all wrapped in a transaction. First I played with starting a transaction in beforeSave and committing it in afterSave, but it was just simpler to do it in the controller. Actually, I think I’ll go back and make it simpler and just use saveAttributes!


this works best for me.


Good trick, it works like a charm. Perfect for me.