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

You are viewing revision #7 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 (#6)next (#8) »

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))
	{
		// Set attribute for home address
		$addressModel_1->attributes=$_POST['Address'][1];
		// Set attribute for company address
		$addressModel_2->attributes=$_POST['Address'][2];
		// Set attribute for user data
		$model->attributes=$_POST['User'];  

		// Validate all three model
		$valid=$addressModel_1->validate();
       		$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;

			// Set saved address as user home id
			$model->home_address_id = $homeAddressId;
			// Set saved address as user company id
			$model->company_address_id = $companyAddressId;  
			$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)
{
	// Load user data in model
	$model=User::model()->findByPk($id);
	// Load address data in addressModel_1
	$addressModel_1=Address::model()->findByPk($model->home_address_id);  
	// Load address data in addressModel_2
	$addressModel_2=Address::model()->findByPk($model->company_address_id);  

	if(!empty($_POST))
	{
		// Set attribute for home address
		$addressModel_1->attributes=$_POST['Address'][1];
		// Set attribute for company address
		$addressModel_2->attributes=$_POST['Address'][2];
		// Set attribute for user data
		$model->attributes=$_POST['User'];

		// Validate all three model
		$valid=$addressModel_1->validate(); 
       		$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 render as _form, from below view code you can get the idea on how to pass models and set attribute names 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 looks like,

All field validation

For every single entry in User table there will be two entry in Address table (home and company).

I hope this will help to many...

10 3
23 followers
Viewed: 93 167 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