Model saving vs. model validation when uploading files

Newbies to Yii and ActiveRecord design pattern, are often confused, what is difference between $model->save() and $model->validate(). though difference should be obvious, there are many code examples in the forum and Yii wiki, that proves, that many people still doesn't understand it. Especially, when it comes to performing additional operations around saving model, like file upload.

First of all, $model->save() calls $model->validate() internally, so changing one to another won't fix anything, if validators are incorrectly defined. The only (general) difference between these two functions is that first validates model and saves it to database, while second one only validates and does not perform any DB query. If model's rules are correctly defined, then $model->save() preforms validation and does not allow to save model, if there are any validation errors. That's how ActiveRecord works ever since and this has to work in either current or in any other version of framework.

If you're performing any additional operations while saving model (like handling files uploaded by a user), you most certainly have to use $model->validate() instead of $model->save(). If you use $model->save(), model will be written to database (if it passes validation, of course), even if following $model->image->saveAs('filename'); or any other command will fail. This way, you'll have empty (dead) entry in database, that does not reference any physical file, if moving file from temporary to permanent location etc. fails

In this or any other contexts there should be only page redirection after $model->save(). All other operations, on database or related, must be performed before model is saved, that is after $model->validate(), but before $model->save()!

This is to avoid situation, where database is updated even after error of different type, than validation error.

Leave a Reply