Yii Framework Forum: 1 Form 2 Models [Resolvido] - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 Form 2 Models [Resolvido] Utilizar um formulário de cadastro único, para 2 tabelas do banco Rate Topic: -----

#1 User is offline   begnini 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 13
  • Joined: 13-September 12
  • Location:cascavel

Posted 13 September 2012 - 01:58 PM

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.
0

#2 User is offline   Newerton 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 824
  • Joined: 27-April 10
  • Location:Campo Grande/MS - Cambé/PR, Brasil

Posted 13 September 2012 - 07:25 PM

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.
Newerton Vargas de Araújo
1

#3 User is offline   begnini 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 13
  • Joined: 13-September 12
  • Location:cascavel

Posted 14 September 2012 - 12:08 PM

Valeu Newerton, deu certo.
Unica coisa que estava faltando aqui era alterar o renderPartial().
0

#4 User is offline   Cálcio 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 84
  • Joined: 18-January 11
  • Location:Niterói - RJ - Brazil

Posted 13 October 2012 - 01:56 PM

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.
0

#5 User is offline   Newerton 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 824
  • Joined: 27-April 10
  • Location:Campo Grande/MS - Cambé/PR, Brasil

Posted 14 October 2012 - 08:19 AM

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();
  }

}

Newerton Vargas de Araújo
0

#6 User is offline   Cálcio 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 84
  • Joined: 18-January 11
  • Location:Niterói - RJ - Brazil

Posted 14 October 2012 - 10:00 AM

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,
		));
	}

0

#7 User is offline   Newerton 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 824
  • Joined: 27-April 10
  • Location:Campo Grande/MS - Cambé/PR, Brasil

Posted 14 October 2012 - 06:37 PM

Cálcio,

Se fizer desta forma aqui, funciona?

foreach($_POST['CollaboratosHasTypeCollaborators']['idCollaboratorType'] as $key => $value)
{
	$modelCollaboratosHasTypeCollaborators->idCollaboratorType = $value;
	$modelCollaboratosHasTypeCollaborators->save(false);
}

Newerton Vargas de Araújo
0

#8 User is offline   Cálcio 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 84
  • Joined: 18-January 11
  • Location:Niterói - RJ - Brazil

Posted 15 October 2012 - 09:24 PM

View PostNewerton, on 14 October 2012 - 06:37 PM, said:

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.
0

#9 User is offline   Adrian Lucas 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 232
  • Joined: 13-October 11
  • Location:João Pessoa - Paraíba

Posted 17 October 2012 - 12:15 PM

View PostCálcio, on 15 October 2012 - 09:24 PM, said:

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.
Adrian Lucas
A fé em Deus nos faz crer no incrível,
ver o invisível e realizar o impossível.

0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users