Save To 2 Tables From One Controller

I have a situation where I have parent/child tables.

Parent

  • id (PK - related to parentid in child table)

  • parentname (same as child.childname)

Child

  • id

  • parentid

  • otherid (relationship to another table)

  • childname

the form I have created collects data for the child form.

Without going into the various reasons why this is the way it is just trust me that this is the way it needs to be. the structure isnt the issue here.

the childname field in the form is an autocomplete field where the user can select an existing childname (from the list of parentnames) or write in a new one. A child name selected from autocomplete assigns its db id (the parentid) to the parentid field in the form. if it does not exist, the value assigned is -1.

if the childname property does not exist in the parent (ie: parentid = -1), the parent record needs to be created, the new ID retrieved, then used as a relational join in the new child record.

the child table also has a field called "otherid" that does not exist in the parent table but is collected in the form.

if the child name exists in the parent table then no parent record needs to be created, just the child record is to be created using the existing parentid.

So, in the childController.actionCreate function I have the following code:




                $model=new child;


		if(isset($_POST['child']))

                {

                    $child = $_POST['child'];


                    $parentid = $child['parentid'];

                    

                    // if less than 0, parent record needs to be created

                    if($parentid<0)

                    {

                        $parentmodel = new parent;


                        $parentmodel->parentname = $_POST['child_childname'];


ERROR HERE -->          $parentmodel->save(false);


                        // put the ID into the child array

                        $child['parentid'] = $parentmodel->id;


                    }

                    $model->attributes=$child;

                    $model->save();

                }



This code produces an error that says "Property parent.otherid is not defined".

which is 100% correct, parent.otherid does not exist. it only exists in the child table. so even though I am specifying the parent model in the error line, it ends up assuming the controller for the child.

How can I save an item to the parent table from the childController.actionCreate function?

thanks in advance

Greg J

‘parent’ is a reserved php word, I wonder how you get it working at all.

the use of "parent" and "child" are for the example and clarity. they arent the real names of the tables.

Plz paste the exact code of action.

here ya go! contents of XrefCompteamController.actionCreate




    $model=new XrefCompteam;


    if(isset($_POST['XrefCompteam']))

    {

        $xrefteam = $_POST['XrefCompteam'];


        // if the team entered is a new team, create it in the Team table first and retrieve the ID

        $teamid = $xrefteam['teamid'];

                   

        //Team id doesnt exist - need to create record in Team first and get its ID

        if($xrefteam['teamid']<0)

        {

           $tmodel = new Team;


           //get the orgid from Comp, need it for new Team record

           $orgid = Comp::model()->find('id='.$xrefteam['compid']);


           //create the team attributes array to create the record

           $tmodel->orgid = $orgid->orgyear->orgid;

           $tmodel->teamname = $_POST['XrefCompteam_team'];

           $tmodel->contactpersonid = 0;

           $tmodel->venueid = $xrefteam['venueid'];


           $tmodel->save(false);


           // put the ID into the XrefCompteam array

           $xrefteam['teamid'] = $tmodel->id;


       }

       $model->attributes=$xrefteam;

       $model->save();

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

    }



Contents of $_POST




Array

(

    [XrefCompteam] => Array

        (

            [compid] => 1

            [teamid] => -1

            [teamlabel] => new team

            [seq] => 0

            [venueid] => 2

            [tables] => 1

            [statusid] => 1

        )


    [XrefCompteam_team] => new team

    [yt0] => Create

)



ERROR MESSAGE = Property "Team.compid" is not defined.

Can you post src of models/Team.php also?

PS. $orgid = Comp::model()->find(‘id=’.$xrefteam[‘compid’]); // SQL INJECTION IS POSSIBLE

I found the issue. some time ago I had a field in Team called compid. it was removed and replaced with orgid however the model was never updated so thats where the reference from compid was coming from, and not the $_POST array.

ISSUE RESOLVED - thanks for the pointer, didnt think to look there.

regarding the SQL INJECTION comment…

When I create a record in xrefCompteam i need the compid (and will be the case in several other forms) so like update, the create command needs to take a parameter so the form can be opened and we know which comp the team is to be saved into.

So at the moment I have the following URL:

domain.com/xrefcompteam/create/1

then in controller XrefCompteam.actionCreate I have this:




if(isset($_GET['id'])) {

    $model->compid = $_GET['id'];

}



So if I may ask for some direction here, how best should I ensure that the compid that is being passed to the create function then the form is a valid id from the comp table? I tried passing the parameter as an argument I do need to use this method for several other forms so I need to get this right.

PS. would this code be better?




$orgid = Comp::model()->findByPK($xrefteam['compid']);



Thanks in advance

Greg J


function actionCreate($id = null)

{

...

$orgid = Comp::model()->findByPk($id);

// or

$orgid = Comp::model()->find('id = :id', array(':id' => $xrefteam['compid']); // param binding

}

Hi Orey,

Thanks awesome! thanks for the prompt response, however the $id as a parameter of actionCreate doenst seem to work. I tried this before but the $id isnt getting passed to the function from url xrefcompteam/create/1. I can only seem to get it from $_GET.

Regards

Greg J

That’s strange, check the Yii version. Named params were introduced long long time ago.

Anyway, you can use $_GET as usual, just make sure you are not allowing the user to pass something nasty.

Actually, param binding works for most cases.

Hi ORey,

I worked out what was going wrong here, I was creating the id in the link rather than using a named parameter.

I had array(’/xrefcompteam/admin/’.$compid) rather than array(’/xrefcompteam/admin’, ‘id’=>$compid)

Now works perfectly!

This was definitely a rookie error. Still getting my head around this awesome framework, so much to learn…

cheers

Greg J