1 Form 2 Models [Resolvido]

Oi,

No sistema que eu estou desenvolvendo, eu tenho 2 tipos de usuários, os clientes e os consumidores (tabelas separadas no banco). Para utilizar um sistema de login único, eu criei a tabela usuários com os campos id, username, password, session. Clientes e consumidores possui a chave estrangeira id_usuario.

Pelo gerador de código, eu gerei o model para usuário, e model e crud para clientes e consumidores, e adicionei usuário e password no form de cadastro de clientes e consumidores.

Minha duvida é como eu faço para separar as informações do usuário das da classe do form, e como salvar essas informações corretamente.

Fora da duvida do tópico, eu estou iniciando com PHP e YII, e todo conhecimento que eu tenho até o momento foi acompanhando os videos em espanhol do Gustavo Salgado. Eu tenho muitas duvidas, e varias delas podem ser bem triviais, então se alguém tiver a disposição para me ajudar com as duvidas, eu peço que me passe o e-mail para que eu possa entrar em contato.

Valeu.

Begnini seja bem vindo.

Como você já criou os cruds, era bom você se familizar com as actions que tem em cada Controller, por exemplo o ClienteController e ConsumidorController, em ambos vem por padrão o actionIndex, actionAdmin, actionView, actionCreate, actioUpdate e actionDelete.

Bom quando você for cadastrar um novo cliente, observar no ClienteController na actionCreate que vai ter uma estrutura parecida com essa aqui:




public function actionCreate()

{

	$model=new Cliente;

	if(isset($_POST['Cliente']))

	{

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

		if($model->save())

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

	}


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

		'model'=>$model,

	));

}



Na view/cliente/create.php vai está assim:




...

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



E no seu view/cliente/ _form vai está a estrutura do formulário.

Pois bem, agora vamos adicionar o Model do Usuário.

No seu ControllerCliente e actionCreate, faça a seguinte alteração.




public function actionCreate()

{

	$model=new Cliente;

	$user=new Usuario;

	

	if(isset($_POST['Cliente']) && isset($_POST['Usuario']))

	{

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

		$user->attributes=$_POST['Usuario'];

		

		if($model->validate() && $user->validate()){ // É bom validar sempre os dois model, caso 1 model esteja sem validação, pode haver inconsistência de dados

			

			$user->save(); // Primeiro salva o usuário para pegar o ID dele.

			

			$model->id_usuario = $user->id; // Pegando o ID do usuário cadastrado, e vinculado ao id_usuario da tabela Cliente

			

			$model->save(); //Salvando os dados do CLiente já com o ID do Usuário

			

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

		}

	}


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

		'model'=>$model,

		'user'=>$user

	));

}



Precisamos agora adicionar a váriavel user no renderPartial() da sua view/cliente/create.php, nunca se esqueça de sempre colocar a váriavel na view correspondente ao render, por que pode dar erro de validação no formulário.




...

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



Agora no formulário é só criar os campos correspodente a tabela de Usuario.




<div class="row">

	<?php echo $form->labelEx($user,'usuario'); ?>

	<?php echo $form->textField($user,'usuario',array('size'=>80,'maxlength'=>128)); ?>

	<?php echo $form->error($user,'usuario'); ?>

</div>


<div class="row">

	<?php echo $form->labelEx($user,'senha'); ?>

	<?php echo $form->passwordField($user,'senha',array('size'=>80,'maxlength'=>128)); ?>

	<?php echo $form->error($user,'senha'); ?>

</div>



Observar que não é usado o $model nos campos, e sim o $user, que são os campos referente ao model Usuario.

Qualquer dúvida posta ae.

Valeu Newerton, deu certo.

Unica coisa que estava faltando aqui era alterar o renderPartial().

Estou com um problema bem parecido. A diferença é que no segundo model preciso gravar N vezes.

Tenho 3 Checkbox, então e eu marcar 2 tenho que fazer 2 inserts no segundo model por exemplo. Tentei colocar um for no segundo save() mas msm assim continua em gravar.

O primeiro problema é a validação, pois msm eu marcado 1 ou + checkbox me retorna o erro de que o tal valor ñ pode ser vazio e tem q ser um inteiro. Msm que no form os valores sejam números no value do checkbox, tentei utilizar o dropDownList() usando o size e multiple e o erro tb acontece.

Não sei mais oq fazer nem como debugar isso. Li tb o tutorial - Coletando Entradas Tabulares mas me parece q isso ñ vai funciona para oq que quero.

Cálcio,

Posta o nome seu checkBoxList e o action.

Vou resumir meio por cima:


if($model->save()){


  foreach($_POST['Model']['checkbox'] as $key => $value)

  }

    $newmodel = new Model;

    $newmodel->valor = $value;

    if($newmodel->validate())

       $newmodel->save();

  }


}

E aí Newerton blz?

Brother se for oq é printado no HTML é esse CollaboratosHasTypeCollaborators[idCollaboratorType][].

Baseado nesse wiki How to use a single form to collect data for two or more models? e no que vc postou para o amigo acima eu tentei jogar esse um for dessa maneira


for($i = 0; $i <= count($_POST['CollaboratosHasTypeCollaborators']['idCollaboratorType']); $i++)

	{

	// Pegando o ID do colaborador cadastrado, e vinculado ao idCollaborator da tabela CollaboratosHasTypeCollaborators

	$modelCollaboratosHasTypeCollaborators->idCollaboratorType = $model->idCollaborator;

	$modelCollaboratosHasTypeCollaborators->save(false);

}

Vale lembrar que no model que me baseio para montar esse form eu tenho um relation MANY_MANY


public function relations()

{

// NOTE: you may need to adjust the relation name and the related

// class name for the relations automatically generated below.

return array(

	'collaboratorsType' => array(self::MANY_MANY, 'CollaboratorsType', 'collaboratosHasTypeCollaborators(idCollaborator, idCollaboratorType)'),

	);

}

Se for de importância posto aqui meu actionCreate.


public function actionCreate()

	{

		$model=new Collaborators;

		$modelCollaboratosHasTypeCollaborators = new CollaboratosHasTypeCollaborators;


		// Uncomment the following line if AJAX validation is needed

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


		if(isset($_POST['Collaborators']) && isset($_POST['CollaboratosHasTypeCollaborators']))

		{

//			var_dump($_POST['CollaboratosHasTypeCollaborators']);

//			echo count($_POST['CollaboratosHasTypeCollaborators']['idCollaboratorType']);

//			for($i = 0; $i <= count($_POST['CollaboratosHasTypeCollaborators']['idCollaboratorType']); $i++)

//			{

//				//$modelCollaboratosHasTypeCollaborators->save(false);

//				echo "Foram marcado(s) $i checkbox(ers)";

//			}

//			exit;

			

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

			$modelCollaboratosHasTypeCollaborators->attributes=$_POST['CollaboratosHasTypeCollaborators'];

			

			$valid = $model->validate();

			$valid = $modelCollaboratosHasTypeCollaborators->validate() && $valid;

			

			if($valid)

			{

				$model->save(false);

				

				for($i = 0; $i <= count($_POST['CollaboratosHasTypeCollaborators']['idCollaboratorType']); $i++)

				{

					// Pegando o ID do colaborador cadastrado, e vinculado ao idCollaborator da tabela CollaboratosHasTypeCollaborators

					$modelCollaboratosHasTypeCollaborators->idCollaboratorType = $model->idCollaborator;

					$modelCollaboratosHasTypeCollaborators->save(false);

				}

				

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

			}

		}


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

			'model'=>$model,

			'modelCollaboratosHasTypeCollaborators'=>$modelCollaboratosHasTypeCollaborators,

		));

	}

Cálcio,

Se fizer desta forma aqui, funciona?


foreach($_POST['CollaboratosHasTypeCollaborators']['idCollaboratorType'] as $key => $value)

{

	$modelCollaboratosHasTypeCollaborators->idCollaboratorType = $value;

	$modelCollaboratosHasTypeCollaborators->save(false);

}



Fiz dessa forma, dei tb uma mudada para tentar fazer funcionar + nada. Sempre reclama dizendo q ñ os campo q preciso da chkbox etão vazios.

Coloquei a validação pra dentro dor for, ele passa + não grava.

Não possível q com relations ñ consiga fazer isso. Até pensei em fazer um insert da forma tradicional, ma vai acabar parando na validação e ñ posso tirá-la.

Amigos o que estou fazendo de errado.

Tenho uma tabela de Candidados e uma de Entrevistas, a FOREIGN KEY de entrevistas é a idcandidatos.

Pois bem, no create de candidatos apenas irei salvar seus dados, ou seja não precisarei alterar o create do CandidatoController. Contudo gostaria de criar um novo Scenário entrevista, onde irei salvar as informações da tabela entrevistas com o id de candidatos. Coloquei um button na gridview de candidatos/admin.php para que o usuário possa clicar e o sistema direcioná-lo para a tela das entrevistas.

Seguindo este tópico, fiz assim:

CandidatosController




	public function actionEntrevistas() {

    	$model = $this->loadModel();

    	$entrevista = new entrevista();


    	if (isset($_POST['candidatos']) && isset($_POST['entrevista'])) {

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

        	$entrevista->attributes = $_POST['entrevista'];


        	$model->scenario = 'entrevistas';


        	if ($model->validate() && $entrevista->validate()) {

            	$model->save();

            	$model->idcandidatos = $entrevista->candidatos;

            	$entrevista->save();

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

        	}

    	}


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

        	'model' => $model,

        	'entrevista' => $entrevista,

        	

    	));

	}



No view/candidatos/entrevistas.php




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



View/candidatos/admin.ph




<?php

	$this->widget('bootstrap.widgets.TbGridView', array(

    	'id' => 'candidatos-grid',

    	'dataProvider' => $model->search(),

    	'filter' => $model,

    	.................................

    	'columns' => array(

        	array(

            	'header' => 'Opções',

            	'htmlOptions' => array('nowrap' => 'nowrap'),

            	'class' => 'bootstrap.widgets.TbButtonColumn',

            	'htmlOptions' => array('style' => 'width: 10px'),

            	'template' => '{entrevistas}',

            	'buttons' => array(

                	'entrevistas' => array(

                    	'label' => 'Entrevistas',

                    	'imageUrl' => Yii::app()->baseUrl . '/css/' . 'rss.png',

                    	'url' => 'Yii::app()->createUrl("/candidatos/entrevistas", array("id" => $data->idcandidatos))',

                   	// 'visible' => 'Yii::app()->user->isAdmin()',

                	),

            	),

        	),

   	),

	));

?>



E no form que dei o nome de _entrevista.php ficou assim:




                                    	<div class="<?php echo $form->fieldClass($entrevista, 'dateone'); ?>">

                                        	<?php echo $form->labelEx($entrevista, 'Data ' . '<span class="required">*</span>'); ?>

                                        	<div class="controls">

                                            	<?php

                                            	$this->widget('CMaskedTextField', array(

                                                	'model' => $entrevista,

                                                	'attribute' => 'dateone',

                                                	'mask' => '99/99/9999',

                                                	'htmlOptions' => array(

                                                    	'class' => 'input-small',

                                                    	'title' => 'Data da 1ª Entrevista'))

                                            	);

                                            	?>

                                            	<?php echo $form->error($entrevista, 'dateone'); ?>

                                        	</div>

                                    	</div>

                                    	<div class="<?php echo $form->fieldClass($entrevista, 'responsavelone'); ?>">

                                        	<?php echo $form->labelEx($entrevista, 'Respons&aacute;vel ' . '<span class="required">*</span>'); ?>

                                            	<div class="controls">

                                            	<?php echo $form->textField($entrevista, 'responsavelone', array('class' => 'span4', 'title' => 'Quem fez a 1ª Entrevista')); ?>

                                            	<?php echo $form->error($entrevista, 'responsavelone'); ?>

                                        	</div>

                                    	</div>



Com isso se eu clicar em inserir e todos os campos estiverem nulos, a validação é feita perfeitamente, mas se colocar alguma informação o sistema nada salva e apaga todos os dados que digitei, ficando na mesma página e com todos os campos em branco.

O que será que fiz de errado. :unsure:

Agradeço a todos.