I had some problems when I tried update a record on my application without upload again a file.
I have a form and on this form there are two fields for upload files, when I create a new record the valdation requires the files, but on update no.
When I try to update a record I receive the error:
Fatal error: Call to a member function saveAs() on a non-object in /Users/san/src/nagloria/trunk/web/public/protected/controllers/admin/RepertoryController.php on line 74
if (isset($model->media_file))
$model->media_file->saveAs(Yii::app()->basePath . "/../files/repertory/media_file/{$model->id}/{$model->media_file->name}");
if (isset($model->thumb))
$model->thumb->saveAs(Yii::app()->basePath . "/../files/repertory/thumbs/{$model->id}/{$model->thumb->name}");
(CUploadedFile::getInstance() returns null if no file was uploaded)
I did your sugestion, the application not showed the error again but happened other error, when I updated a record without upload a file, the aplication stored a NULL value on database field rewriting the file name that was stored on this field first.
I need to persist the file name on database if files aren’t uploaded.
I haven’t tried this myself, but I think manual assignment of the two uploaded fields, if not empty, would be a better solution than to explicitly save the old values.
To me it seems like you massively assign from a form in this statement.
$model->attributes = $form;
Do you use 1.0 or 1.1? If the latter, you have to specify an ‘update’ scenario rule instead.
On second thought, why are the upload fields empty in your ‘update’ scenario? I think I’m going to try this out now. I’m sure somebody else can explain this better.
Edit:
Sorry, in my first answer I erroneously got the impression you saved to local vars. Now I see that you save to the model and I don’t know the semantics of CUploadedFile. Please disregard my answer.
$model->myfile is a string when read back from the db. It is massively assigned as I suspected (default is all attributes). If the getInstance call succeeds, $model->myfile becomes a CUploadedFile object (else it seems to becomes an instance of the current controller !?).
1) safeAttributes
public function safeAttributes()
{
return array(
'create'=>'media_file, thumb, attr_1, attr_2, attr_n',
'attr_1, attr_2, attr_n',
);
}
2) don’t overwrite $model->file if invalid object
$myfile = CUploadedFile::getInstance($model,'myfile');
if (is_object($myfile) && get_class($myfile)==='CUploadedFile')
$model->myfile = $myfile;
3) test before save
if (is_object($model->myfile))
$model->Picture->saveAs($mypath.'/'.$model->myfile->name);
The logic can be improved (don’t create dir when not neccessary, clear $model->myfile if file cannot be saved, filesize rules)