Updating Relating Models

I have two related models i.e. Candidate and Qualifications. They have one to many relationship between them. I am using CActiveForm and want to perform CRUD operation on the relational data. As you can see from the code below that PK of candidate is auto generated and is being send to qualification model as FK.

Controller




public function actionCreate()

	{

		$model=new Candidate;

        $q=new Qualification;

        if (isset($_POST['Candidate'], $_POST['Qualification'])) {

            $model->attributes=$_POST['Candidate'];

            $q->attributes=$_POST['Qualification'];


            $error = false;

            $transaction = Yii::app()->db->beginTransaction();

            try {

                if (!$model->save()) {

                    throw new CException(CHtml::errorSummary($model));

                }

                $q->candidate_id = $model->id;

                if (!$q->save()) {

                    throw new CException(CHtml::errorSummary($q));

                    echo $error;

                }

                $transaction->commit();

            } catch (Exception $e) {

                $transaction->rollBack();

                $error = $e->getMessage();

            }


            if (!$error) {

                $this->redirect(array('view','id'=>$model->id));

            }

        }

	$this->render('create',array(

			'model'=>$model,

            'qualification'=>$q,

		));

	}




This is working fine for me but now i want to perform update and delete. I am finding hard to implement it. Moreover, i don’t find much of help regarding relational update and delete other than by using extensions.

BTW do you prefer using extensions?

You are almost there. ;)

From the code you posted I assume you are creating/updating/deleting 1 candidate + 1 qualification at a time (even though the relation is 1 -> n) ?

For a modify, your $_POST should contain the id’s of the candidate & qualification.

So you will have to load the candidate & qualification (findByPk), instead of creating a new ones. The rest of the code looks similar to what you have already.

For delete, you probably want 2 seperate delete actions: 1 for a candidate (also deleting qualifications) and 1 for a qualification ?

Just get the id of the model, load it, then call the delete method.

(you might want to reconsider your approach of sending data of 2 models at once when there is a 1->n relation between them)

Hi,

You almost done everything. My suggestions are

In Controller File

  • Get your PK as argument from your update action say $id.
  • Load the model Candidates by pk

($model = Candidate::model()->findByPk($id); 

  • Load the model Qualification

 $q =  Qualification::model()->findAllByAttributes(array('candidate_id' => $id));

In View File

  • Change the qualification form. ( Change all names of the form fields in terms of array . i.e - concat with [] in every form field name )
  • Put qualification form in loop **

** - Don’t forget to put the controller save functionality also in loop for qualification form update !

If works … press + button

You forgot to add the rendering of the form.




$this->render('update',array('model'=>$model, 'qualification'=>$q));  //maybe you have another view name






public function actionUpdate($id)

{


...

        if (!$error) {

            $this->redirect(array('view','id'=>$model->id));

        }


    }


    --> You are not rendering anything here <--


}

Not ‘_form’, render the whole page: ‘update’.

This is the error i am recieving


 Undefined variable: qualification


C:\xampp\htdocs\ayiitest\protected\views\candidate\_form.php(87)

Ok, i’ll help you here too :)

You declare:




<?php $this->renderPartial('_form', array('model'=>$model, 'Qualification'=>$qualification)); ?>



But you say :

Which is normal since you pass


'Qualification'=>$qualification

and you access


$qualification

So i would start by passing correct data into the view:




<?php $this->renderPartial('_form', array('model'=>$model, 'qualification'=>$qualification)); ?>



P.S:

In case you didn’t get it, it’s about case sensitivity, make sure you access the data in your view by exact same name you sent it from your controller.

Thanks a lot. A simple capital ruined my hours …solved