Updating multimodel form

Hello Friends I am using this link for multimodel forms input. Now I can insert the data of two models successfully.But when I am going to update the inserted data it is showing error like Undefined variable: member.Here is my datamodel


 ==== Group =====

  id

  name

  

  ==== Member ====

  id

  group_id

  firstname

  lastname

  membersince

My Group controller code is like this




<?php


class GroupController extends Controller

{

  /**

   * @var string the default layout for the views. Defaults to '//layouts/column2', meaning

   * using two-column layout. See 'protected/views/layouts/column2.php'.

   */

  public $layout='//layouts/column2';


  /**

   * @return array action filters

   */

  public function filters()

  {

    return array(

      'accessControl', // perform access control for CRUD operations

    );

  }


  /**

   * Specifies the access control rules.

   * This method is used by the 'accessControl' filter.

   * @return array access control rules

   */

  public function accessRules()

  {

    return array(

      array('allow',  // allow all users to perform 'index' and 'view' actions

        'actions'=>array('index','view'),

        'users'=>array('*'),

      ),

      array('allow', // allow authenticated user to perform 'create' and 'update' actions

        'actions'=>array('create','update'),

        'users'=>array('@'),

      ),

      array('allow', // allow admin user to perform 'admin' and 'delete' actions

        'actions'=>array('admin','delete'),

        'users'=>array('admin'),

      ),

      array('deny',  // deny all users

        'users'=>array('*'),

      ),

    );

  }


  /**

   * Displays a particular model.

   * @param integer $id the ID of the model to be displayed

   */

  public function actionView($id)

  {

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

      'model'=>$this->loadModel($id),

    ));

  }


  /**

   * Creates a new model.

   * If creation is successful, the browser will be redirected to the 'view' page.

   */

  public function actionCreate()

  {

    $model=new Group;

    $member=new Member;


    // Uncomment the following line if AJAX validation is needed

    // $this->performAjaxValidation($model);


    if(isset($_POST['Group'],$_POST['Member']))

    {

      //Populate input data to $Group and $Member

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

      $member->attributes=$_POST['Member'];

      

      //Validate both $Group and $Member

      //$validate = $model->validate();

      //$validate = $member->validate() && validate;

      

#      if($validate){

#        ($model->save() & $member->save())

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

#      }

      if($model->save() & $member->save())

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

    }


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

      'model'=>$model,

      'member'=>$member,

    ));

  }


  /**

   * Updates a particular model.

   * If update is successful, the browser will be redirected to the 'view' page.

   * @param integer $id the ID of the model to be updated

   */

  public function actionUpdate($id)

  {

    $model=$this->loadModel($id);


    // Uncomment the following line if AJAX validation is needed

    // $this->performAjaxValidation($model);


    if(isset($_POST['Group'],$_POST['Member'])) {

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

    $member->attributes=$_POST['Member'];


      if($model->save()&$member->save())

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

    }


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

      'model'=>$model,

      'member'=>$member,

    ));

  }


  /**

   * Deletes a particular model.

   * If deletion is successful, the browser will be redirected to the 'admin' page.

   * @param integer $id the ID of the model to be deleted

   */

  public function actionDelete($id)

  {

    if(Yii::app()->request->isPostRequest)

    {

      // we only allow deletion via POST request

      $this->loadModel($id)->delete();


      // if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser

      if(!isset($_GET['ajax']))

        $this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));

    }

    else

      throw new CHttpException(400,'Invalid request. Please do not repeat this request again.');

  }


  /**

   * Lists all models.

   */

  public function actionIndex()

  {

    $dataProvider=new CActiveDataProvider('Group');

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

      'dataProvider'=>$dataProvider,

    ));

  }


  /**

   * Manages all models.

   */

  public function actionAdmin()

  {

    $model=new Group('search');

    $model->unsetAttributes();  // clear any default values

    if(isset($_GET['Group']))

      $model->attributes=$_GET['Group'];


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

      'model'=>$model,

    ));

  }


  /**

   * Returns the data model based on the primary key given in the GET variable.

   * If the data model is not found, an HTTP exception will be raised.

   * @param integer the ID of the model to be loaded

   */

  public function loadModel($id)

  {

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

    if($model===null)

      throw new CHttpException(404,'The requested page does not exist.');

    return $model;

  }


  /**

   * Performs the AJAX validation.

   * @param CModel the model to be validated

   */

  protected function performAjaxValidation($model)

  {

    if(isset($_POST['ajax']) && $_POST['ajax']==='group-form')

    {

      echo CActiveForm::validate($model);

      Yii::app()->end();

    }

  }

}



Group controller create.php file is like this for rendering both models in a single page




<?php

$this->breadcrumbs=array(

	'Groups'=>array('index'),

	'Create',

);


$this->menu=array(

	array('label'=>'List Group', 'url'=>array('index')),

	array('label'=>'Manage Group', 'url'=>array('admin')),

);

?>


<h1>Create Group</h1>


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


Group Controller's _form.php for input field for both model is like this


<div class="form">


<?php $form=$this->beginWidget('CActiveForm', array(

  'id'=>'group-form',

  'enableAjaxValidation'=>false,

)); ?>


  <p class="note">Fields with <span class="required">*</span> are required.</p>


  <?php echo $form->errorSummary($model); ?>


  <div class="row">

    <?php echo $form->labelEx($model,'name'); ?>

    <?php echo $form->textField($model,'name',array('size'=>60,'maxlength'=>80)); ?>

    <?php echo $form->error($model,'name'); ?>

  </div>

  

  <div class="row">

    <?php echo $form->labelEx($member,'firstname'); ?>

    <?php echo $form->textField($member,'firstname',array('size'=>60,'maxlength'=>80)); ?>

    <?php echo $form->error($member,'firstname'); ?>

  </div>


  <div class="row">

    <?php echo $form->labelEx($member,'lastname'); ?>

    <?php echo $form->textField($member,'lastname',array('size'=>60,'maxlength'=>80)); ?>

    <?php echo $form->error($member,'lastname'); ?>

  </div>


  <div class="row">

    <?php echo $form->labelEx($member,'membersince'); ?>

    <?php echo $form->textField($member,'membersince'); ?>

    <?php echo $form->error($member,'membersince'); ?>

  </div>


  <div class="row buttons">

    <?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>

  </div>


<?php $this->endWidget(); ?>


</div><!-- form -->



Now when I am going to update an ID it is showing error and also I want to update the both models for that ID should render in a single page.How to do that?

Am I doing something wrong?

You forgot to define $member in actionUpdate, that’s why error has occured.

Btw, I think that Group can have many members, so it’s not clear for me what you’re trying to do.

Ya I know Group have many members so that’s I have used group_id in Members table and can you please tell me how to define $member in action Update.I had defined that but it not worked.

I think you should have separate controller for updating members, because updating group AND all its members at one place sounds like a bad idea for me.

For example, think about how your form would look like, if you’ll have, say, 100 members in your group.

I am not thinking about that.I want to save the two models at a time with update function.So can you help me out?




$model=$this->loadModel($id);

$member = Member::model()->find(... some condition here ...);

...

if ($model->save() && $member->save()) { ... }



what should be $member as I have member table have group_id in database, as discussed over group has many mmember.

Seems like you have general misunderstanding of what you’re doing.

Try to think over your app design first.

  1. Add to edit form <?php echo $form->hiddenField($member,‘id’);?>

  2. On update action would something like that




$groupAttributes = Yii::app()->request->getParam('Group');

$memberAttributes = Yii::app()->request->getParam('Member');


$group = $this->loadModel($id);

$member = Member::model()->findByPk(array('id' => $memberAttributes['id']));




if (!empty($groupAttributes) && !empty($memberAttributes)) {

  $group->attributes = $groupAttributes;

  $member->attributes = $memberAttributes;


  $isValid = $group->validate();

  $isValid = $member->validate() && $isValid;


  if ($isValid) { 

    if ($group->save()) {

      $member->group_id = $group->id;

      $member->save();

      // redirect here or what you need

    }

  }

}





// render form



Thanks @ Weavora Team for trying to help

But after these modification I got an error like this: Undefined offset: 0

Can you help me out. I am just a newbie in Yii and already have lost 5 days behind this.

In what line you got this error?

No line number was mentioned in the error. It is simply showing Undefined offset: 0 . Is there any thing wrong in the code?I think I have used your code in which $groupAttributes and $memberAttributes has been defined but in actionCreate() it is not defined.

You can check my default code above.The only thing I have changed is the actionUpdate() with your codes.

I guess the problem in


$member = Member::model()->findByPk(array('id' => $memberAttributes['id']));

If you follow to e.g. /group/edit/<groupId>, you can get group by id, but you can’t get member. So there are should be memberId instead of groupId. In this case you could do something like:




$member = Member::model()->findByPk($id);

$group = Group::model()->findByPk($member->group_id);

// or of course just $group = $member->group; if relation defined



sorry @Weavora Team Still I am getting the error