Actualizar datos de formulario con varios modelos

Hola comunidad,

soy newbee estoy comenzando Yii desde hace unos meses, siguiendo varios ejemplos de rellenar varios modelos desde un mismo formulario me encuentro con el siguiente problema.He revisado ejemplos y no sé que puede estar pasando.

tengo la siguiente base de datos de ejemplo.

Tb_nino

ID_NINO (PK)

NOMBRE

TB_PADRES

ID (PK)

N_PADRE

N_MADRE

ID_NINO (FK)

Estoy usando el formulario update de la vista de Nino para guardar la información de los padres. El create me funciona correctamente, pero el update es donde tengo las dudas y problemas, al actualizar el formulario primero me muestra el nombre correcto del niño pero los nombres de los padres corresponden al registro anterior guardo de la tabla padres. Cuando actualizo de los padres la información esta no la guarda en la tabla o si no me muestra un error, si actualizo la de nino si se guarda.

Los controladores




public function actionCreate()

	{

           $model= new TbNino;  

           $model_padres=new TbPadres; 

           

                $this->performAjaxValidation(array($model,$model_padres)); 

                if(isset($_POST['TbNino'],$_POST['TbPadres']))

                        { 

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

                            $model_padres->attributes=$_POST['TbPadres']; 

                        $sql='select max(ID_NINO) as maximo from tb_nino;';

                        $connection=Yii::app()->db; 

                        $command=$connection->createCommand($sql);

                        $row=$command->queryRow(); 

                        $row["maximo"]++; 

                        $model_padres->ID_NINO=$row["maximo"]; 

                        $model->ID_NINO=$row["maximo"];

                        if($model->save() && $model_padres->save()) $this->redirect(array('view','id'=>$model->ID_NINO));

                        }  

                  

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

			'model'=>$model,

                        'model_padres'=>$model_padres,

		));

           

	}


	

	public function actionUpdate($id)

	{

		$model=new TbNino; 

                $model_padres=new TbPadres; 

           

                $this->performAjaxValidation(array($model,$model_padres)); 

                        

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

                //$model_padres = TbPadres:: model()->findByPk($model->ID_NINO);

                

		if(isset($_POST['TbNino'],$_POST['TbPadres']))

		{

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

                        $model_padres->attributes=$_POST['TbPadres'];

                        

                        $model_padres->ID_NINO = $model->ID_NINO;

                        

                        $model_padres->setIsNewRecord(false);

                        if($model->save() && $model_padres->update())

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

		}

                

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

			'model'=>$model,

                        'model_padres'=>$model_padres

		));

        }




Y el formulario _FORM





<div class="form">


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

	'id'=>'tb-nino-form',

	'enableAjaxValidation'=>true,

)); 

if($model->isNewRecord==false){

     

     //$model = TbNino:: model()->findByPk($model->ID_NINO);

     $model_padres = TbPadres:: model()->findByPk($model->ID_NINO);

} else 

    {

        echo $form->errorSummary(array($model,$model_padres));

}

?>


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


	

        

       

	<div class="row">

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

		<?php echo $form->textField($model,'NOMBRE',array('size'=>50,'maxlength'=>50)); ?>

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

	</div>


        <div class="row">

		<?php echo $form->labelEx($model_padres,'Nombre_padre'); ?>

		<?php echo $form->textField($model_padres,'Nombre_padre',array('size'=>50,'maxlength'=>50)); ?>

		<?php echo $form->error($model_padres,'Nombre_padre'); ?>

	</div>


        <div class="row">

		<?php echo $form->labelEx($model_padres,'Nombre_madre'); ?>

		<?php echo $form->textField($model_padres,'Nombre_madre',array('size'=>50,'maxlength'=>50)); ?>

		<?php echo $form->error($model_padres,'Nombre_madre'); ?>

	</div>

        

                       

	<div class="row buttons">

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

	</div>


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


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




en en update.php




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



Gracias por vuestro tiempo.

Cuando borro un registro de la tabla de niño y se produce un decalaje en la secuencia de ID_NINO En la tabla de padres, al consultar el siguiente registro me muestra este error, pero solo en algunos registros.

Fatal error: Call to a member function isAttributeRequired() on a non-object in C:\wamp\www\yii\framework\web\helpers\CHtml.php on line 1414

Simple la solución, en tu MODEL tu archivo que te genero yii en base a tu tabla…, agrega dos propiedades osea

public $propiedad;

eso lo pones antes de todo el código del model, y luego en tu CONTROLLER UPDATE, si ya tienes el ID del NINO, ahora buscalo en una consulta, ¿como?, dos formas, haces una consulta nativa y la executas con yii o haces una busqueda por objeto, ¿como?, así:




//por OBJETO, te recomiendo ver la documentación para obtener la búsqueda de atributos

$padre = TU_MODEL::model()->findByAttributes(array('ID_NINO'=>$tu_varibale_id_nino));

//Osea TU_MODEL, será el padre no vayas a poner el del niño OK, y ya con eso si imprimes $padre veras que puedes

//juegar con los datos como desees ahora se usa la propiedad.

$model->propiedad = $padre->nombre;

//Y con esto ya tienes el valor en la propiedad ahora pon una caja de texto en tu FORM, y en vez de poner el

//nombre de un atributo en tu caso nombre de la tabla nino, ponle propiedad y ya le pasas el valor y lo muestras

//de una manera bonita en una caja de texto o un label, o como desees.


//SEGUNDA OPCION

//es lo mismo de las variables pero nada mas con consulta

$sql = "PONES TODO TU SQL QUE DESEES EXTRAER";

$model = Yii::app()->db->createCommand($sql)->queryScalar(); // ó queryAll ó execute // te recomienda checar esa documentación

//y en model ya tienes los datos como en $padre es o mismo pero sacad de dos formas, y ya haces lo que te puse arriba para pasar la propiedad y listo HOMMS!!!



Saludos.

Muchas gracias por la contestación y tu tiempo.

pondre en marcha esto ahora mismo, espero poner el "SOLUCIONADO" en breve.

de nuevo gracias.

Hola,

Dentro del controler de modelo de niño en la función de UPDATE tengo puesto, que imagino que es a lo que te refieres en tu respuesta, perdona pero no entiendo bien lo que comentas acerca de las propiedades y creciacion de las propiedades en el model.




$model_padres = TbPadres:: model()->findByPk($model->ID_NINO);






//por OBJETO, te recomiendo ver la documentación para obtener la búsqueda de atributos

$padre = TU_MODEL::model()->findByAttributes(array('ID_NINO'=>$tu_varibale_id_nino));



Tras realizar la pertinente batería de pruebas con borrados, altas y modificaciones parece que funciona sin problemas, no perdiendo en ningun momento la integridad entre las tablas implicadas. TbNino y tbPadres

Ahora he trasladado este ejemplo a otro proceso con nombres y direcciones, pero sigo teniendo problemas ya que las altas y actualizaciones de datos pueden ir por dos caminos.

desde nombres se puede dar de alta una direccion y desde direccion se puede dar de alta más de una direccion para un nombre,

tbnombre

id nombre (PK)

nombre

email

telefono …

tbdireccion

id direc (PK)

id nombre (FK)

tipo direccion (facturacion, correspondiencia…)

nombre calle

municipio…

cuando desde el formulario de direcciones se produce una baja u alta no hay problema, pero cuando pretendo actualizar desde nombres me muestra un error al intentar actualizar un valor desde el formulario que contiene también la parte de direcciones y otras me muestra un nombre con una direccion anterior a la que le correspondería.




Fatal error: Call to a member function isAttributeRequired() on a non-object in C:\wamp\www\yii\framework\web\helpers\CHtml.php on line 1513



aca el update.php y create.php




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



aca el _form




<?php

/* @var $this TbnombresController */

/* @var $model Tbnombres */

/* @var $form CActiveForm */

?>


<div class="form">


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

	'id'=>'tbnombres-form',

	'enableAjaxValidation'=>true,

)); 

if ($model->isNewRecord==false){

    

    $model_direccion = Tbdireccion::model()->findByPk($model->ID_INTER);

    

}else 

    {   

        echo $form->errorSummary(array ($model,$model_direccion));

}

?>


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


	<?php  ?>


	<div class="row">

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

		<?php echo $form->textField($model,'NOMBRE_INTER',array('size'=>50,'maxlength'=>50)); ?>

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

	</div>


	<div class="row">

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

		<?php echo $form->textField($model,'CARGO',array('size'=>50,'maxlength'=>50)); ?>

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

	</div>


	<div class="row">

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

		<?php echo $form->textField($model,'TELEFONO',array('size'=>15,'maxlength'=>15)); ?>

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

	</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>


        <!-- -->

        

        <div class="row">

		<?php echo $form->labelEx($model_direccion,'TIPO_DIRECCION'); ?>

		<?php echo $form->textField($model_direccion,'TIPO_DIRECCION'); ?>

		<?php echo $form->error($model_direccion,'TIPO_DIRECCION'); ?>

	</div>


	<div class="row">

		<?php echo $form->labelEx($model_direccion,'TIPO_VIA'); ?>

		<?php echo $form->textField($model_direccion,'TIPO_VIA'); ?>

		<?php echo $form->error($model_direccion,'TIPO_VIA'); ?>

	</div>


	<div class="row">

		<?php echo $form->labelEx($model_direccion,'NOMBRE_VIA'); ?>

		<?php echo $form->textField($model_direccion,'NOMBRE_VIA',array('size'=>50,'maxlength'=>50)); ?>

		<?php echo $form->error($model_direccion,'NOMBRE_VIA'); ?>

	</div>


	<div class="row">

		<?php echo $form->labelEx($model_direccion,'COD_POSTAL'); ?>

		<?php echo $form->textField($model_direccion,'COD_POSTAL',array('size'=>50,'maxlength'=>50)); ?>

		<?php echo $form->error($model_direccion,'COD_POSTAL'); ?>

	</div>


	<div class="row">

		<?php echo $form->labelEx($model_direccion,'POBLACION'); ?>

		<?php echo $form->textField($model_direccion,'POBLACION',array('size'=>50,'maxlength'=>50)); ?>

		<?php echo $form->error($model_direccion,'POBLACION'); ?>

	</div>


	<div class="row">

		<?php echo $form->labelEx($model_direccion,'PROVINCIA'); ?>

		<?php echo $form->textField($model_direccion,'PROVINCIA',array('size'=>50,'maxlength'=>50)); ?>

		<?php echo $form->error($model_direccion,'PROVINCIA'); ?>

	</div>


	<div class="row">

		<?php echo $form->labelEx($model_direccion,'PAIS'); ?>

		<?php echo $form->textField($model_direccion,'PAIS',array('size'=>50,'maxlength'=>50)); ?>

		<?php echo $form->error($model_direccion,'PAIS'); ?>

	</div>

        

        

        

        

	<div class="row buttons">

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

	</div>


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


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



aca el Create y update




public function actionCreate()

	{

		$model=new Tbnombres;

                $model_direccion = new Tbdireccion;

                                           

                                

		// Uncomment the following line if AJAX validation is needed

		$this->performAjaxValidation(array ($model,$model_direccion));


		if(isset($_POST['Tbnombres'],$_POST['Tbdireccion']))

		{

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

                        $model_direccion->attributes=$_POST['Tbdireccion'];

                        $sql='select max(ID_INTER)as maximo from tbnombres;';

                        $connection=Yii::app()->db;

                        $command=$connection->createCommand($sql);

                        $row=$command->queryRow();

                        $row["maximo"]++;

                        $model_direccion->ID_INTER=$row["maximo"];

                        $model->ID_INTER=$row["maximo"];

                       

                       

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

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

		}


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

			'model'=>$model,

                        'model_direccion'=>$model_direccion,

		));

	}




public function actionUpdate($id)

	{

		$model= new Tbnombres;

                $model_direccion = new Tbdireccion;

                

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

                $model_direccion = Tbdireccion:: model()->findByPk($model->ID_INTER);


		// Uncomment the following line if AJAX validation is needed

		$this->performAjaxValidation(array($model,$model_direccion));


		if(isset($_POST['Tbnombres'],$_POST['Tbdireccion']))

		{

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

                        $model_direccion->attributes=$_POST['Tbdireccion'];

                            

                        $model_direccion->ID_INTER = $model->ID_INTER;

                        

                        $model_direccion->setIsNewRecord(false);

			if($model->save() && $model_direccion->update())

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

		}


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

			'model'=>$model,

                        'model_direccion'=>$model_direccion,

                    

		));

	}



Si en el update modifico esta línea para poder leer todos los datos




$model_direccion = Tbdireccion:: model()->findByAttributes(array ('ID_INTER'=>$model));



me muestra error 500.

Por favor aclararme un poco más por donde puedo tener los problemas o donde mirar… perdón por todo este rollo…pero soy muy nuevo en esto…