Update attributes by a different action controller

Hi, I modified the gridview ‘delete’ button which now it does NOT actually delete the record, instead it would change the record status from 1 to 2 (integer value) and the user will be prompted to provide reason (text area input). So I made a delete action controller that acts very similar with the update function (but it updates different attributes of the same table instead).

I learned if you want to update the record status automatically, you use the beforeSave() function written in the model. But I only know how to distinguish ‘create’ and ‘update’ by using isNewRecord(). But this time it comes from a different ‘update’ controller.

The added action controller


    public function actionDeleteme($id)

    {

       $model = $this->findModel($id);


        if ($model->load(Yii::$app->request->post()) && $model->save()) {

            return $this->redirect(['index']);

        } else {

            return $this->render('deleteme', [

                'model' => $model,

            ]);

        }

    }



The form


    <?php $form = ActiveForm::begin(); ?>


    <?= $form->field($model, 'DeleteReason')->textArea(['rows' => '6']) ?>


    <div class="form-group">

        <?= Html::submitButton('Delete', ['class' => 'btn btn-danger']) ?>

    </div>


    <?php ActiveForm::end(); ?>

The whole attribute model


    public function attributeLabels()

    {

        return [

            'ReservationID' => 'Reservation ID',

            'Date' => 'Date & Time',

            'RoomID' => 'Room Name',

            'PatientID' => 'Patient Name',

            'DoctorID' => 'Doctor Name',

            'status' => 'Status',

            'DeleteReason' => 'Delete Reason',

        ];

    }

Thank you so much for anyone who can help me on this

There’s no need to use “beforeSave()”. You can update the “status” manually, and that’s all.




public function actionDeleteme($id){

    $model = $this->findModel($id);

    $model->status = Reservation::STAUS_DELETED;


    if ($model->load(Yii::$app->request->post()) && $model->save()) {

        return $this->redirect(['index']);

    } else {

        return $this->render('deleteme', [

            'model' => $model,

        ]);

    }

}



Thanks for the reply, I tried your solution. But the solution changes the status before the user fills up the reason form. I’m thinking about changing the status after the user fills out the delete reason form and clicked the submit button.

No need to worry about it. The changed status won’t take effect on the db until you save the model.

Or, you can do it like this, if it satisfies you:




public function actionDeleteme($id){

    $model = $this->findModel($id);


    if ($model->load(Yii::$app->request->post()) && $model->validate()) {

        $model->status = Reservation::STATUS_DELETED;

        $model->save(false);

        return $this->redirect(['index']);

    } else {

        return $this->render('deleteme', [

            'model' => $model,

        ]);

    }

}



Probably we could do it in beforeSave like this:




public function beforeSave($insert)

{

    if (parent::beforeSave($insert)) {

        if (!empty($this->delete_reason)) {

             $this->status = self::STATUS_DELETED;

        }

        return true;

    } else {

        return false;

    }

}



But I don’t see any good reason to do it separately in beforeSave.

The $insert parameter of the beforeSave method (and the value of “isNewRecord()”) has nothing to do with the controller’s action names.

It is true when the model to be saved has been created by "new", and is false when the model has been loaded from the db. So it should be false when you call save from the deleteMe action, although you can safely ignore $insert parameter in this case.

If the "status" would have been an attribute that depends on multiple conditions, and if you would have had 2 or more actions to alter those conditions independently, then updating it in beforeSave do make sense.

Sorry, I didn’t really check the database, I checked the viewing status. it was safe before submission. you were right. Thanks for your solution, it did not need the beforeSave() method.

Thank you for very much for your solution :D

Hi,
How did you manage to change the status from 1 to 2?

I have to do something similar but from 1 to 0 and not delete the record, i hope u can help me :slight_smile:

You have to add what is called a “soft delete”, basically will be an attribute specific for receiving the 0 or 1.

A easy way to do it is by using this extension: https://github.com/yii2tech/ar-softdelete