Yii Framework Forum: CRUD de duas Tabelas - Yii Framework Forum

Jump to content

  • (2 Pages)
  • +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

CRUD de duas Tabelas Um formulário, Um controller, dois Models, p/ unir dados de 2 tabelas Rate Topic: -----

#1 User is offline   Breno Mayder 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 85
  • Joined: 15-September 10
  • Location:Belo Horizonte - Brasil

Posted 21 January 2011 - 02:17 PM

Olá pessoal, segue abaixo o exemplo de duas tabelas de meu banco de dados, (é apenas um exemplo):

CREATE TABLE IF NOT EXISTS `pessoa` (
`idpessoa` int(11) NOT NULL AUTO_INCREMENT,
`nome` varchar(45) NOT NULL,
`idtipopessoa` int(11) NOT NULL,
PRIMARY KEY (`idpessoa`)
)

CREATE TABLE IF NOT EXISTS `email` (
`idemail` int(11) NOT NULL AUTO_INCREMENT,
`idpessoa` int(11) NOT NULL,
`email` varchar(100) NOT NULL,
PRIMARY KEY (`idemail`),
KEY `idpessoa` (`idpessoa`)
)

ALTER TABLE `email`
ADD CONSTRAINT `email_ibfk_1` FOREIGN KEY (`idpessoa`) REFERENCES `pessoa` (`idpessoa`) ON DELETE NO ACTION ON UPDATE NO ACTION;

Preciso criar um CRUD para esta estrutura, mas preciso que os campos da tabela pessoa e e-mail estejam juntos no mesmo form. Ou seja, na tela de cadastro (insert ou update) o usuário precisa ver os seguintes campos no formulário: Nome, Tipo de pessoa (que pega de um dropdown de outra tabela, mas que já esta ok) e e-mail (que esta na tabela de nome 'email').

Alguém sabe como posso fazer isso e pode me ajudar? Obrigado.
Breno Mayder
Posted Image
0

#2 User is offline   Gustavo 

  • Master Member
  • Yii
  • Group: Moderators
  • Posts: 916
  • Joined: 27-July 10
  • Location:Curitiba - Brasil

Posted 21 January 2011 - 04:16 PM

//nas relations no seu segundo model 
return array(
			'pessoa'=>array(self::BELONG_TO, 'Pessoa', 'idpessoa'),
		);
//nas relations do primeiro model 
return  array(
			'email'=>array(self::HAS_ONE, 'Email', 'idpessoa'),
		);

ae pra usar faça algo como o seguinte:
$pessoal_model->email->email;
//ou
$email_model->pessoa->nome;

--
Extensions:
translate modue - module to handle translations
multiActiveRecord - db selection in models
redisCache - redis cache component
mpCpanel - interact with cpanel api
mUploadify - use uploadify uploader in your application

Gustavo Salomé Silva
0

#3 User is offline   Breno Mayder 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 85
  • Joined: 15-September 10
  • Location:Belo Horizonte - Brasil

Posted 21 January 2011 - 08:36 PM

View PostGustavo, on 21 January 2011 - 04:16 PM, said:

//nas relations no seu segundo model 
return array(
			'pessoa'=>array(self::BELONG_TO, 'Pessoa, 'idpessoa'),
		);
//nas relations do primeiro model 
return  array(
			'email'=>array(self::HAS_ONE, 'Email', 'idpessoa'),
		);

ae pra usar faça algo como o seguinte:
$pessoal_model->email->email;
//ou
$email_model->pessoa->nome;



E ao gerar o crud pelo Gii ou Console o form vai aparecer com todos os campos? Não terei que fazer nada na View e nem no Controller?
Breno Mayder
Posted Image
0

#4 User is offline   Gustavo 

  • Master Member
  • Yii
  • Group: Moderators
  • Posts: 916
  • Joined: 27-July 10
  • Location:Curitiba - Brasil

Posted 21 January 2011 - 09:45 PM

Você aind aprecisa especificar os campos que deseja mostrar na view, e no formulario na hora de salvar deve ajustar o codigo
O codigo que passei estabelece relação estre as duas tabelas, assim na hora que você usar as variaveis definidas em relations(), essa variavel vai conter os dados gerados pelo relacionamento que passei no codigo acima
De uma olhada no manual de relacionamentos para maiores explicações
--
Extensions:
translate modue - module to handle translations
multiActiveRecord - db selection in models
redisCache - redis cache component
mpCpanel - interact with cpanel api
mUploadify - use uploadify uploader in your application

Gustavo Salomé Silva
0

#5 User is offline   Breno Mayder 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 85
  • Joined: 15-September 10
  • Location:Belo Horizonte - Brasil

Posted 23 January 2011 - 08:08 AM

Na verdade meu problema é o mesmo deste Topico,

http://www.yiiframew...7093#entry77093

com ajuda dele consegui resolver com relação ao Insert, mas já com relação ao Update não tive sucesso ainda.

Alguém pode me dar uma dica?

Acredito que o problema esteja no controller, vejam como penso em fazer
public function actionUpdate($id)
{
        $model=$this->loadModel($id);
        $usuario = new Usuario;
        $email = new Email;
        $telefone = new Telefone;

        //$usuario = Usuario::model()->find(array('idpessoa'=>$id));
        //$email = Email::model()->find(array('idpessoa'=>$id));
        //$telefone = Telefone::model()->find(array('idpessoa'=>$id));

        // Uncomment the following line if AJAX validation is needed
        $this->performAjaxValidation(array($model,$usuario,$email,$telefone));

        if(isset($_POST['Pessoa']))
        {
            $model->attributes=$_POST['Pessoa'];
            $model->save();
        }

        if (isset($_POST['Usuario']))
        {
            $usuario->attributes=$_POST['Usuario'];
            $usuario->save();
        }

        if (isset($_POST['Email']))
        {
            $email->attributes=$_POST['Email'];
            $email->save();
        }

        if (isset($_POST['Telefone']))
        {
            $telefone->attributes=$_POST['Telefone'];
            $telefone->save();
        }

        if( isset($_POST['Pessoa']) || isset($_POST['Usuario']) || isset($_POST['Email']) || isset($_POST['Telefone']))
        {
            $this->redirect(array('view','id'=>$model->idpessoa));
        }

        $this->render('update',array(
                'model'=>$model,
                'usuario'=>$usuario,
                'email'=>$email,
                'telefone'=>$telefone,
        ));
}


Acredito que tenha que popular o objeto de cada tabela conforme tentei fazer lá no inicio do código, mas acredito que daquela forma esta errado.

Para a tabela principal ele utiliza a linha abaixo para popular o model principal.

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


Nas linhas comentadas tentei popular os outros models, mas não sei se esta certo.

Alguém pode me ajudar?
Breno Mayder
Posted Image
0

#6 User is offline   Gustavo 

  • Master Member
  • Yii
  • Group: Moderators
  • Posts: 916
  • Joined: 27-July 10
  • Location:Curitiba - Brasil

Posted 23 January 2011 - 08:16 AM

se entende um pouco de ingles este topico vai ajudar
--
Extensions:
translate modue - module to handle translations
multiActiveRecord - db selection in models
redisCache - redis cache component
mpCpanel - interact with cpanel api
mUploadify - use uploadify uploader in your application

Gustavo Salomé Silva
0

#7 User is offline   Breno Mayder 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 85
  • Joined: 15-September 10
  • Location:Belo Horizonte - Brasil

Posted 23 January 2011 - 08:31 AM

Olá Gustavo, na verdade não ajuda não, esta parte do 'actionCreate' eu consegui fazer da seguinte forma:

public function actionCreate()
{
        $model = new Pessoa;
        $usuario = new Usuario;
        $email = new Email;
        $telefone = new Telefone;

        // Uncomment the following line if AJAX validation is needed
        $this->performAjaxValidation(array($model,$usuario,$email,$telefone));

        if( isset($_POST['Pessoa']) && isset($_POST['Usuario']) && isset($_POST['Email']) && isset($_POST['Telefone']))
        {
                $model->attributes=$_POST['Pessoa'];
                $usuario->attributes=$_POST['Usuario'];
                $email->attributes=$_POST['Email'];
                $telefone->attributes=$_POST['Telefone'];

                if ($model->validate())
                {
                    $model->save();
                }
                if ($usuario->validate())
                {
                    $usuario->idpessoa = $model->idpessoa;
                    $usuario->senha = md5($usuario->senha);
                    //$usuario->status = '1';
                    $usuario->save();
                }
                if ($email->validate())
                {
                    $email->idpessoa = $model->idpessoa;
                    $email->save();
                }
                if ($telefone->validate())
                {
                    $telefone->idpessoa = $model->idpessoa;
                    $telefone->save();
                }

                if ($model->validate() && $usuario->validate() && $email->validate() && $telefone->validate())
                {
                    $this->redirect(array('view','id'=>$model->idpessoa));
                }
        }

        $this->render('create',array(
                'model'=>$model,
                'usuario'=>$usuario,
                'email'=>$email,
                'telefone'=>$telefone,
        ));
}


Esta parte esta funcionando perfeitamente, estou com dificuldade para fazer é o Update, se alguém tiver algum artigo que me ajude ou souber de algum topico que faça algo parecido vai ajudar demais.

O meu 'actionUpdate' esta assim:

public function actionUpdate($id)
{
        $model=$this->loadModel($id);
        $usuario = new Usuario;
        $email = new Email;
        $telefone = new Telefone;

        //$usuario = Usuario::model()->find(array('idpessoa'=>$id));
        //$email = Email::model()->find(array('idpessoa'=>$id));
        //$telefone = Telefone::model()->find(array('idpessoa'=>$id));

        // Uncomment the following line if AJAX validation is needed
        $this->performAjaxValidation(array($model,$usuario,$email,$telefone));

        if(isset($_POST['Pessoa']))
        {
            $model->attributes=$_POST['Pessoa'];
            $model->save();
        }

        if (isset($_POST['Usuario']))
        {
            $usuario->attributes=$_POST['Usuario'];
            $usuario->save();
        }

        if (isset($_POST['Email']))
        {
            $email->attributes=$_POST['Email'];
            $email->save();
        }

        if (isset($_POST['Telefone']))
        {
            $telefone->attributes=$_POST['Telefone'];
            $telefone->save();
        }

        if( isset($_POST['Pessoa']) || isset($_POST['Usuario']) || isset($_POST['Email']) || isset($_POST['Telefone']))
        {
            $this->redirect(array('view','id'=>$model->idpessoa));
        }

        $this->render('update',array(
                'model'=>$model,
                'usuario'=>$usuario,
                'email'=>$email,
                'telefone'=>$telefone,
        ));
}


O meu problema acredito estar neste trecho:

public function actionUpdate($id)
{
        $model=$this->loadModel($id);
        $usuario = new Usuario;
        $email = new Email;
        $telefone = new Telefone;

        //$usuario = Usuario::model()->find(array('idpessoa'=>$id));
        //$email = Email::model()->find(array('idpessoa'=>$id));
        //$telefone = Telefone::model()->find(array('idpessoa'=>$id));


Preciso carregar o $usuario,$email e $telefone da mesma forma que foi carregado o $model na linha:

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

Breno Mayder
Posted Image
0

#8 User is offline   Gustavo 

  • Master Member
  • Yii
  • Group: Moderators
  • Posts: 916
  • Joined: 27-July 10
  • Location:Curitiba - Brasil

Posted 23 January 2011 - 08:43 AM

Ja testou o que vem na var $id ? talvez nao esteja vindo correto
Tambem me mostra a função loadModel

tambem seria uma boa fazer uma validação antes de redirecionar, algo como :
$valid=true;

em cada if algo como
$valid = $model->save() && $valid;

dae no final se valid for true é pq deu tudo certo, se for false deu algum erro no caminho
--
Extensions:
translate modue - module to handle translations
multiActiveRecord - db selection in models
redisCache - redis cache component
mpCpanel - interact with cpanel api
mUploadify - use uploadify uploader in your application

Gustavo Salomé Silva
0

#9 User is offline   Breno Mayder 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 85
  • Joined: 15-September 10
  • Location:Belo Horizonte - Brasil

Posted 23 January 2011 - 11:52 AM

View PostGustavo, on 23 January 2011 - 08:43 AM, said:

Ja testou o que vem na var $id ? talvez nao esteja vindo correto
Tambem me mostra a função loadModel

tambem seria uma boa fazer uma validação antes de redirecionar, algo como :
$valid=true;

em cada if algo como
$valid = $model->save() && $valid;

dae no final se valid for true é pq deu tudo certo, se for false deu algum erro no caminho


Bom, na verdade o $id esta retornando o valor correto sim, no formulário os unicos campos que são resgatados também são os relacionados ao $model, já os campos relacionados a $usuario,$email e $telefone vem em branco.

Ao editar todos os campos os unicos que alteram são os relacionados ao $model também.
Esta questão da validação realmente é importante, obrigado por ter lembrado, eu ia sem dúvidas me esquecer disso.

esta função loadModel foi criada pelo próprio Yii, acho que ela serve para carregar nos inputs os valores de cada campo a partir da busca do id, mas não tenho certeza, vou procurar sobre ela e colocar aqui.
Breno Mayder
Posted Image
0

#10 User is offline   Breno Mayder 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 85
  • Joined: 15-September 10
  • Location:Belo Horizonte - Brasil

Posted 23 January 2011 - 12:40 PM

Consegui fazer com que os campos do formulário venham todos preenchidos no update, ficou assim:


public function actionUpdate($id)
	{
		$model=$this->loadModel($id);

                $email = new Email;
                $telefone = new Telefone;
                $usuario = new Usuario;
                
                $email = Email::model()->find(array('condition'=>'idpessoa=:idpessoa','params'=>array(':idpessoa'=>$id)));
                $telefone = Telefone::model()->find(array('condition'=>'idpessoa=:idpessoa','params'=>array(':idpessoa'=>$id)));
                $usuario = Usuario::model()->find(array('condition'=>'idpessoa=:idpessoa','params'=>array(':idpessoa'=>$id)));
               



Apenas um campo não esta preenchido conforme recuperação no banco, é o campo da Cidade, mas deve ser pq fiz um dropdown dinamico que muda as cidades de acordo com a escolha do estado. Como estado não tem valor do banco preciso achar uma forma de fazer o dropdown dinâmico funcionar de forma reversa.
Breno Mayder
Posted Image
0

#11 User is offline   Breno Mayder 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 85
  • Joined: 15-September 10
  • Location:Belo Horizonte - Brasil

Posted 23 January 2011 - 12:56 PM

Gustavo, valeu pela força, com relação ao Update eu resolvi o problema, era pq eu tinha alterado o nome do campo para exibição no label no _form, o correto era alterar no attributeLabels() dentro do model de cada tabela.

Depois que fiz isso resolveu o problema.

Agora o único problema é para fazer resgatar o campo da cidade no Dropdown que fiz dinâmico, você ou alguém pode me dar um caminho para fazer com que a cidade cadastrada no banco apareça no update?
Breno Mayder
Posted Image
0

#12 User is offline   Gustavo 

  • Master Member
  • Yii
  • Group: Moderators
  • Posts: 916
  • Joined: 27-July 10
  • Location:Curitiba - Brasil

Posted 23 January 2011 - 08:46 PM

Algo como o seguinte:
echo CHtml::dropDownList('estado_id','', CHtml::listData(Estados::model()->findAll()),
 array(
   'ajax' => array(
    'type'=>'POST', //request type
    'url'=>CController::createUrl('controller/getcidades'), //url de pegar cidades.
    'replace'=>'#cidade_id', //onde colocar o resultado
 	//poderia ser 'update' ao inves de replace, ae você só retornaria os options nao todo o select
  )
); 
 
echo CHtml::dropDownList('cidade_id','', array());


e então faça uma action, algo como :
public function actionGetcidades()
{
    $model=Cidades::model();
    $data=$model->findAll('estado_id=:estado_id',array(':estado_id'=>(int) $_POST['estado_id']));
 
    echo CHtml::activeDropDownList($model,'cidade_id',CHtml::listData($data,'cidade_id','cidade_name'));
}

acredito que esta tudo certo apesar de ter escrito aqui no editor mesmo
--
Extensions:
translate modue - module to handle translations
multiActiveRecord - db selection in models
redisCache - redis cache component
mpCpanel - interact with cpanel api
mUploadify - use uploadify uploader in your application

Gustavo Salomé Silva
0

#13 User is offline   Breno Mayder 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 85
  • Joined: 15-September 10
  • Location:Belo Horizonte - Brasil

Posted 24 January 2011 - 02:37 PM

També vou tentar fazer isso, já estou tentando, se eu conseguir eu mando aqui.
Breno Mayder
Posted Image
0

#14 User is offline   Breno Mayder 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 85
  • Joined: 15-September 10
  • Location:Belo Horizonte - Brasil

Posted 24 January 2011 - 08:09 PM

Olha só, meu código do dropdown esta funcionando e esta assim:

_form
<?php
$estado = Estado::model()->findAllEstado();
  echo CHtml::dropDownList('estado','', $estado,
  array(
  'empty' => 'Selecione um estado',
  'ajax' => array(
  'type'=>'POST',
  'url'=>CController::createUrl('pessoa/dynamiccities'),
  'update'=>'#idcidade', //Quando coloco replace ele mostra corretamente os campos só que saindo de dentro do dropdown.
)));

?>
    
<?php echo CHtml::dropDownList('idcidade','', array(), array('empty' => 'Selecione uma cidade')); ?>


action dentro do controller
public function actionDynamiccities()
{
    $idestado = $_POST['estado'];
    $data=Cidade::model()->findPorEstado($idestado);
    foreach($data as $value=>$name)
    {
        echo CHtml::tag('option',
                   array('value'=>$value),CHtml::encode($name),true);
    }

}


função findPorEstado que esta dentro do model Cidade
public function findPorEstado($idestado)
{
    //format models resulting using listData
    return $list = CHtml::listData($models = Cidade::model()->findAll(
            array(
                'condition'=>'idestado=:idestado',
                'params'=>array(':idestado'=>$idestado),
            )), 'idcidade', 'nom_cidade');
} //Fiz esta função só pq como vou ter que usar-la em varios lugares fica mais facil chamar-la.


Este é meu código do Dropdown, ele esta funcionando corretamente, mas sempre quando abro a tela de update ele aparece zerado, como se o usuário não tivesse informado nada, o que preciso é fazer com que os campos estado e cidade dos dropdowns já estejam preenchidos com o que o usuário salvou no banco, e o detalhe é que só sei o id da cidade, ou seja, só o id da cidade que esta no banco, mas na tabela de cidades eu tenho o campo idestado para saber de qual estado é cada cidade.

Penso que preciso recuberar este valor de idcidade, por ele achar o idestado da cidade que o usuário é, marcar no dropdown o estado que encontramos, e pegar também a cidade e marcar-la.
Breno Mayder
Posted Image
0

#15 User is offline   Gustavo 

  • Master Member
  • Yii
  • Group: Moderators
  • Posts: 916
  • Joined: 27-July 10
  • Location:Curitiba - Brasil

Posted 25 January 2011 - 12:00 PM

use relacionamento de tabela

//model
function relations(){
   return array(
   	'estado'=>array(self::BELONGS_TO,'Estado','estadoid');
   );
}
//pra usar
$cidade=Cidade::model()->findByPk(1);
$cidade->estado->nome;//nome do estado

--
Extensions:
translate modue - module to handle translations
multiActiveRecord - db selection in models
redisCache - redis cache component
mpCpanel - interact with cpanel api
mUploadify - use uploadify uploader in your application

Gustavo Salomé Silva
0

#16 User is offline   Breno Mayder 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 85
  • Joined: 15-September 10
  • Location:Belo Horizonte - Brasil

Posted 25 January 2011 - 08:10 PM

Não entendi, mas vou tentar pensar nisso que vc disse.
Breno Mayder
Posted Image
0

#17 User is offline   Gustavo 

  • Master Member
  • Yii
  • Group: Moderators
  • Posts: 916
  • Joined: 27-July 10
  • Location:Curitiba - Brasil

Posted 25 January 2011 - 08:40 PM

em seu UserIdentity
function getCidade(){
   return $this->_model->idcidade;
}

/e pra buscar 

Yii::app()->user->cidade
/ou
Yii::app()->user->getCidade();


depois use relações como falei acima pra buscar o estado
$cidadeId=Yii::app()->user->cidade;
$cidade=Cidades::model()->findByPk($cidadeId);
$estado=$cidade->estado->id;

--
Extensions:
translate modue - module to handle translations
multiActiveRecord - db selection in models
redisCache - redis cache component
mpCpanel - interact with cpanel api
mUploadify - use uploadify uploader in your application

Gustavo Salomé Silva
0

#18 User is offline   Breno Mayder 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 85
  • Joined: 15-September 10
  • Location:Belo Horizonte - Brasil

Posted 25 January 2011 - 09:02 PM

Agora entendi o que vc falou, é o seguinte, o ID do Estado e o ID da Cidade eu consegui recuperar, mas como faço para que o Dropdown fique com Selected no ID que eu recuperei?
Breno Mayder
Posted Image
0

#19 User is offline   Gustavo 

  • Master Member
  • Yii
  • Group: Moderators
  • Posts: 916
  • Joined: 27-July 10
  • Location:Curitiba - Brasil

Posted 26 January 2011 - 07:45 AM

nao tenho certeza, mas algo como

$form->dropDownList(
  $model,'cidade',$data,
  array(
       	array('options'=>array(
                     	Yii::app()->user->cidade=>array('selected'=>'selected')
      	)
   )
);


deve funcionar
--
Extensions:
translate modue - module to handle translations
multiActiveRecord - db selection in models
redisCache - redis cache component
mpCpanel - interact with cpanel api
mUploadify - use uploadify uploader in your application

Gustavo Salomé Silva
1

#20 User is offline   Breno Mayder 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 85
  • Joined: 15-September 10
  • Location:Belo Horizonte - Brasil

Posted 26 January 2011 - 01:22 PM

Não deu, talvez fiz algo de errado pq não entendi esta logica. Tem alguma forma de fazer pelo controller com que o dropdown já venha com selected em determinado valor?
Breno Mayder
Posted Image
0

Share this topic:


  • (2 Pages)
  • +
  • 1
  • 2
  • 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