How to use Multiple instances of the same model in the same form

You are viewing revision #6 of this wiki article.
This version may not be up to date with the latest version.
You may want to view the differences to the latest version or see the changes made in this revision.

« previous (#5)next (#7) »

When i had created this functionality then i found some difficulties and not got much idea from wiki and forums. so, i think this will be useful for newbie users and save time of other developers when create related functionality. I refer Collecting Tabular Input tutorial but not got clear idea for create/update.

Here in my demo i had two tables as, User(table) can have multiple address ( home, company ) which comes from Address(table)

Model generated by gii and no any change in model.

User Table
---id
---name
---surname
---email
---home_address_id ( data refer to Address table )
---company_address_id ( data refer to Address table )
Address Table
---id
---street
---city
---state

Developer can also use loop for multiple instances here in my demo i explained with two.

Create Controller
public function actionCreate()
	{
		$model=new User;  // User Model
		$addressModel_1 = new Address;  // Address Model
		$addressModel_2 = new Address;  // Address Model
		
		if(!empty($_POST))
		{
			$addressModel_1->attributes=$_POST['Address'][1];  // Set attribute for home address
			$addressModel_2->attributes=$_POST['Address'][2];  // Set attribute for company address
			$model->attributes=$_POST['User'];  // Set attribute for user data
					
			$valid=$addressModel_1->validate();  // Validate all three model
       		$valid=$addressModel_2->validate() && $valid;
       		$valid=$model->validate() && $valid;
			
			if($valid)
			{ 
				$addressModel_1->save();
				$homeAddressId = $addressModel_1->id;
							
				$addressModel_2->save();
				$companyAddressId = $addressModel_2->id;
				
				$model->home_address_id = $homeAddressId;  // Set saved address as user home id
				$model->company_address_id = $companyAddressId;  // Set saved address as user company id
				$model->save();
				$this->redirect(array('view','id'=>$model->id));
			}
		}
		$this->render('create',array(
			'model'=>$model,'addressModel_1'=>$addressModel_1,'addressModel_2'=>$addressModel_2,
		));
	}
Update Controller
public function actionUpdate($id)
	{		
		$model=User::model()->findByPk($id);  // Load user data in model		
		$addressModel_1=Address::model()->findByPk($model->home_address_id);  // Load address data in addressModel_1		
		$addressModel_2=Address::model()->findByPk($model->company_address_id);  // Load address data in addressModel_2

		if(!empty($_POST))
		{
			$addressModel_1->attributes=$_POST['Address'][1];  // Set attribute for home address
			$addressModel_2->attributes=$_POST['Address'][2];  // Set attribute for company address
			$model->attributes=$_POST['User'];  // Set attribute for user data
					
			$valid=$addressModel_1->validate(); // Validate all three model
       		$valid=$addressModel_2->validate() && $valid;
       		$valid=$model->validate() && $valid;
			
			if($valid)
			{ 		
				$addressModel_1->save();
				$addressModel_2->save();
				$model->save();
			}
		}
		$this->render('update',array(
			'model'=>$model,'addressModel_1'=>$addressModel_1,'addressModel_2'=>$addressModel_2,
		));
	}
View Form

For create and update same page rander as _form, from below view code you can get idea how i pass model and set attribute name for elements..

<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
	'id'=>'user-form',
	'enableAjaxValidation'=>false,
)); ?>

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

	<div class="row">
		<?php echo $form->labelEx($model,'name'); ?>
		<?php echo $form->textField($model,'name',array('size'=>50,'maxlength'=>50)); ?>
		<?php echo $form->error($model,'name'); ?>
	</div>
	<div class="row">
		<?php echo $form->labelEx($model,'surname'); ?>
		<?php echo $form->textField($model,'surname',array('size'=>50,'maxlength'=>50)); ?>
		<?php echo $form->error($model,'surname'); ?>
	</div>
	<div class="row">
		<?php echo $form->labelEx($model,'email'); ?>
		<?php echo $form->textField($model,'email',array('size'=>50,'maxlength'=>50)); ?>
		<?php echo $form->error($model,'email'); ?>
	</div>
	
	//////////////////////////////////////////////////////
	<h2>Home Address Below</h2>	

	<div class="row">
		<?php echo $form->labelEx($addressModel_1,'[1]street'); ?>
		<?php echo $form->textField($addressModel_1,'[1]street'); ?>
		<?php echo $form->error($addressModel_1,'[1]street'); ?>
	</div>
	<div class="row">
		<?php echo $form->labelEx($addressModel_1,'[1]city'); ?>
		<?php echo $form->textField($addressModel_1,'[1]city'); ?>
		<?php echo $form->error($addressModel_1,'[1]city'); ?>
	</div>	
	<div class="row">
		<?php echo $form->labelEx($addressModel_1,'[1]state'); ?>
		<?php echo $form->textField($addressModel_1,'[1]state'); ?>
		<?php echo $form->error($addressModel_1,'[1]state'); ?>
	</div>
	
	//////////////////////////////////////////////////////
	<h2>Company Address Below</h2>
	
	<div class="row">
		<?php echo $form->labelEx($addressModel_2,'[2]street'); ?>
		<?php echo $form->textField($addressModel_2,'[2]street'); ?>
		<?php echo $form->error($addressModel_2,'[2]street'); ?>
	</div>
	<div class="row">
		<?php echo $form->labelEx($addressModel_2,'[2]city'); ?>
		<?php echo $form->textField($addressModel_2,'[2]city'); ?>
		<?php echo $form->error($addressModel_2,'[2]city'); ?>
	</div>	
	<div class="row">
		<?php echo $form->labelEx($addressModel_2,'[2]state'); ?>
		<?php echo $form->textField($addressModel_2,'[2]state'); ?>
		<?php echo $form->error($addressModel_2,'[2]state'); ?>
	</div>

	<div class="row buttons">
		<?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
	</div>

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

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

The demo some what look like,

All field validation

There will be single entry in User table and two entry in Address table ( for home and company ) same data update on update scenario.

I hope this will help to many...

10 3
23 followers
Viewed: 93 185 times
Version: Unknown (update)
Category: How-tos
Written by: kiran sharma
Last updated by: Maurizio Domba Cerin
Created on: Aug 1, 2012
Last updated: 12 years ago
Update Article

Revisions

View all history