How to use a single form to collect data for two or more models?

Assume we want to use a single HTML form to collect input for both model A and model B, and we want to display input errors (if any) in the same error summary box. We can define the following action code:

public function actionCreate()
{
	$a=new A;
	$b=new B;
	if(isset($_POST['A'], $_POST['B']))
	{
		// populate input data to $a and $b
		$a->attributes=$_POST['A'];
		$b->attributes=$_POST['B'];
		
		// validate BOTH $a and $b
		$valid=$a->validate();
		$valid=$b->validate() && $valid;
		
		if($valid)
		{
			// use false parameter to disable validation
			$a->save(false);
			$b->save(false);
			// ...redirect to another page
		}
	}

	$this->render('create', array(
		'a'=>$a,
		'b'=>$b,
	));
}

To add these new fields to your Create form, add your 2nd table fields no stored in a 2nd model.

A's create.php:

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

You usually place the specific fileds in the _form.php file if you are working off Gii created CRUD files.

<?php echo CHtml::beginForm(); ?>

    <?php echo CHtml::errorSummary(array($a,$b)); ?>

    <!-- ...input fields for $a, $b... -->

	<div class="row">
		<?php echo $form->labelEx($a,'a_field'); ?>
		<?php echo $form->textField($a,'a_field'); ?>
		<?php echo $form->error($a,'a_field'); ?>
	</div>

	<div class="row">
		<?php echo $form->labelEx($b,'b_field'); ?>
		<?php echo $form->textField($b,'b_field'); ?>
		<?php echo $form->error($b,'b_field'); ?>
	</div>


<?php echo CHtml::endForm(); ?>

The above approach can also be used if we have more than two models to deal with.

Links

Ajax Validation Version

88 0
79 followers
Viewed: 353 725 times
Version: 1.1
Category: Tutorials
Written by: qiang
Last updated by: Yang He
Created on: Feb 27, 2009
Last updated: 12 years ago
Update Article

Revisions

View all history

Related Articles