1
votes

I have the following tables and I want to click delete at Pak button which can delete all 3 tables relations.

How can I achieve that?

table Pak : id_pak, pak_name/////
table Church : id_church, church_name, id_pak/////
table Member : id_member, name_member, id_church////

public function actionDelete($id)
{
    $this->findModel($id);
    $select = Church::find()
            ->select('church_name')
            ->where(['id_pak' => $id])
            ->all();

    $a3 = Church::find()
        ->select('id_church')
        ->where(['id_pak' => $id])
        ->all();

    $select2 = Member::find()
            ->select('member_name')
            ->where(['id_church'=> $a3])
            ->all();
    Church::find()->where(['id_pak' => $id])->one()->delete();
    Pak::find()->where(['id_pak' =>$id])->one()->delete();
    Member::find()->where(['id_church'=> $a3])->one()->delete();
    return $this->redirect(['index','select'=>$select,'select2'=>$select2]);
}
2
are you using innoDB engine with constraints defined? - Muhammad Omer Aslam

2 Answers

0
votes

Using Constraints with innoDB Engine

If you are using InnoDB and have added the constraints on delete cascade correctly and defined the respective relations in the models you don't need to worry about the related records in the other tables you just need to find the model in the Pak and delete it.

public function actionDelete($id)
{
    $this->findModel($id)->delete();

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

protected function findModel( $id ) {
    if ( ($model = Pak::findOne ( $id )) !== null ) {
        return $model;
    }

    throw new NotFoundHttpException ( 'The requested page does not exist.' );
}

Removing Manually

Or if you are not using innoDB or not using constraints for any reason then you can override the beforeDelete() in the ActiveRecord Model for Pak and remove all the child rows for the Pak Model in the Church and override beforeDelete() inside the Church to delete all child rows in Member model and return true from there to continue deleting the actual record in the Pak model

I assume that you have the following relations defined in the Pak model

public function getChurch(){
    return $this->hasOne(Church::className(), ['id_pak'=>'id_pak']);
}

and the following inside the Church model

public function getMember(){
    return $this->hasOne(Member::className(),['id_church'=>'id_church']);
}

Then override the beforeDelete() in the Pak model

public function beforeDelete() {
    $this->church->delete();
    return parent::beforeDelete ();
}

and override the beforeDelete() in the Church Model

public function beforeDelete() {
    $this->member->delete();
    return parent::beforeDelete ();
}

and in your actionDelete() just find the model and call delete

public function actionDelete($id)
{
    $this->findModel($id)->delete();

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

There is also a nice article on implementing recursiveDelete() method in a parent model here.

0
votes

Following code may help you to solve your problem.

public function actionDelete($id)
{
    $select = Church::find()
            ->select('church_name')
            ->where(['id_pak' => $id])
            ->all();

    $a3 = Church::find()
        ->select('id_church')
        ->where(['id_pak' => $id])
        ->all();

    $select2 = Member::find()
            ->select('member_name')
            ->where(['id_church'=> $a3])
            ->all();

    // ---------- start ---------------
    $park = Park::find()->where(['id_pak' => $id])->one();
    if ( $park->delete() ){
        Pak::deleteAll('id_pak = :id', [':id' => $id]);
        foreach ($a3 as $value) {
            Member::deleteAll('id_church = :id', [':id' => $value->id_church ]);
        }
    }
    // ---------- end ---------------

    return $this->redirect(['index','select'=>$select,'select2'=>$select2]);
}