Yii: Saving multiple models from a single form and checking for existing record

3.2k views Asked by At

Below is the relation between three tables I have.

enter image description here

Now, while creating a new user through user/create action, the form takes input for both user table fields and the unit name. The unit name here isn't a dropdown (using that is not an option), but a textfield. If the unit name entered in the form doesn't exist in the unit table, I need to insert it in the unit table and then save the relation/reference in the user_unit table. If it exists I just update the user_unit table. I am able to get it kind of working by declaring the unitname property in the User model and then associating it with the form, then in the controller I check if the unit name entered exists in unit table. If it exists then I update the UserUnit model if it doesn't then I create the unit and then update UserUnit. It works, except that I am not able to associate the unit name to the form when updating the record. The userunit relationship is a HAS_MANY one and I guess that is creating some issue here. Could anyone suggest me how to approach solving it?

Here's the user/create action

$model = new User;
$modeluserunit = new UserUnit;
$user_group=Yii::app()->user->group; 
if(isset($_POST['User']))
    {
        $model->attributes=$_POST['User'];
        //$modeluserunit->attributes=$_POST['UserUnit'];
        $valid=$model->validate(); 
        if($valid)  
            {
                if($model->save(false))  
                {
                    $Userunitmodel = Unit::model()->findByAttributes(array('name'=>$model->unitplaceholder,'groupId'=>$user_group));
                    if (count($Userunitmodel)!=0)
                    {
                        $modeluserunit->UserId = $model->id;  
                        $modeluserunit->unitId = $Userunitmodel->id; 
                        if ($modeluserunit->save()) 
                        {
                            Yii::app()->user->setFlash('success', "User created!"); 
                            $this->redirect(array('view','id'=>$model->id));
                        }
                    }
                    else if (count($Userunitmodel)==0) 
                        {
                            $unitmodel = new Unit;
                            $unitmodel->name=$model->unitplaceholder;
                            $unitmodel->communityId=$user_group;
                            if ($unitmodel->save())  
                            {
                                $modeluserunit->UserId = $model->id;  
                                $modeluserunit->unitId = $unitmodel->id; 
                                if ($modeluserunit->save())  
                                {   Yii::app()->user->setFlash('success', "User created!"); 
                                    $this->redirect(array('view','id'=>$model->id));
                                } 
                            }
                        }
                }
            }
    }
    $this->render('create', array(
        'model'=>$model,
        'modeluserunit'=>$modeluserunit,
    )); 

The user/update action

$model=$this->loadModelupdate($id);
if(isset($_POST['User']))
{
$model->attributes=$_POST['User'];
if($model->save())
Yii::app()->user->setFlash('success', "User updated!");     
$this->redirect(array('view','id'=>$model->id));
}

$this->render('update',array(
'model'=>$model,
));

And the loadModel function

$criteria=new CDbCriteria();
$criteria->compare('t.id',$id); 
$criteria->compare('unit.groupId',Yii::app()->user->group); 
$model = User::model()->with(array('UserUnits' => array('with' => 'unit')))->find($criteria);
if($model===null)
throw new CHttpException(404,'The requested page does not exist.');
return $model;

The relationship in the User Model

return array(
            'userUnits' => array(self::HAS_MANY, 'UserUnit', 'userId'),
        );
2

There are 2 answers

0
Deele On

You should use form model for this purpose. At the end of validation, you just create user, then create new unit with given name, and then create new user_unit feeding freshly created user id and unit id.

Read more Yii Definitive Guide - Model and CFormModel.

0
Henry On

Try this at home:

<? /*** stuff for your model User ***/

    // store all ids from rela Model
    public $selectedIds;


    public function relations() 
    {
    return array(
            'userUnits' => array(self::MANY_MANY, 'Unit', 'UserUnit(userId, unitId)','index'=>'id'),
        );
    }


    public function afterFind()
    {
        // "userUnits" is defined in relations()
        $this->selectedIds = array_keys($this->userUnits);
        parent::afterFind();
    }   



    ?>

After your User Model is loaded for update-action, all assigned Groups (ids) are in $selectedIds. So you can iterate over it and build your ActiveForm Inputs.