4

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'),
        );
tereško
  • 58,060
  • 25
  • 98
  • 150
redGREENblue
  • 3,076
  • 8
  • 39
  • 57
  • I don´t think you need to declare the unitname property in the User model. You can with the render method send two models, the $model (User) and the $Userunitmodel and in the view you can $form->textfield($Userunitmodel, 'name'). Then you can take advantage of the rules() inside Unit model. You may add a 'unique' validator rule for the unit.name or add a beforeSave() to check if the name exists. For the user_unit table there´s a CAdvancedArBehavior that deals with it. – StackUnder Sep 20 '13 at 20:29

2 Answers2

0

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.

Deele
  • 3,728
  • 2
  • 33
  • 51
0

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.

Henry
  • 597
  • 4
  • 12