Mohammad
Mohammad

Reputation: 3547

how to assign string to a file attribute after saving the file instance?

I am trying to save my uploaded file with a new name, so I must update the file attribute again to give it the new name to avoid the mismatching between the file name in the db and the name of the real file in my directory.

But the file attribute type is file, so I'll get an error saying please upload a file every time I do this process, here is my create action code:

if(isset($_POST['Customers'])) {

    $model->attributes=$_POST['Customers'];
    $model->image = UploadedFile::getInstance($model, 'image');

    if($model->save()){

        $model->image->saveAs(getcwd()."/images/customers/CUST-".$model->id."-".$model->image);
        $model->image = "CUST-".$model->id."-".$model->image;

        if($model->save())
            return $this->redirect(['view', 'id' => $model->id]);
    }
}

Upvotes: 0

Views: 59

Answers (2)

Beowulfenator
Beowulfenator

Reputation: 2300

Here's your solution: you need two different fields.

One field is to store the name of the file. This field will be saved into the database. This field should not be set in your rules at all, because you'll never be getting it from forms.

Another field is to receive the actual file upload. This field needs to exist in your rules as type file and also be declared in your model class as a property.

Let's assume that your customer table already has a column named image.

class Customer extends ActiveRecord
{
    public $imageFile;

    //...

    public function rules()
    {
        return [
            //...
            [['imageFile'], 'file'],
            [['imageFile'], 'required'],
            //...
        ];
    }

    //...
}

Now, in your controller:

if (Yii::$app->request->isPost) {
    $model->load(Yii::$app->request->post());
    $model->imageFile = UploadedFile::getInstance($model, 'imageFile');

    if ($model->save()) {
        $model->refresh();

        //set image name
        $model->image = "CUST-".$model->id."-".$model->imageFile->name;

        //save file
        $model->imageFile->saveAs(getcwd()."/images/customers/".$model->image);

        //update model with file name
        $model->save();
    }
}

return $this->redirect(['view', 'id' => $model->id]);

It would also be a good idea to use aliases to get your upload folder. Something like Yii::getAlias("@uploads/{$model->image}").

Upvotes: 1

Double H
Double H

Reputation: 4160

Saving A model after Image SaveAs call .. Should Be Like

if(isset($_POST['Customers'])) {

$model->attributes=$_POST['Customers'];
$model->image = UploadedFile::getInstance($model, 'image');

if($model->validate()){

    $model->image->saveAs(getcwd()."/images/customers/CUST-".$model->id."-".$model->image);
    $model->image = "CUST-".$model->id."-".$model->image;

    if($model->save())
        return $this->redirect(['view', 'id' => $model->id]);
}
}

Upvotes: 0

Related Questions