Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

AndreLC90

relacionamento N:N (terceira tabela)

Recommended Posts

Boa noite,

 

Tenho uma dúvida na questão de relacionamento de muitos para muitos.

 

Tenho a tabela imóveis com a informação relativa ao imóvel e tenho a tabela divisao com a informação relativa às divisões que poderá existir para um imóvel.

 

Pela lógica criei a tabela imovel_divisoes que possui ambos os ids das tabelas imoveis e divisao juntamente com a descricao e metros quadrados, pois necessito desta informação também.

CREATE TABLE IF NOT EXISTS `imoveis` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `estado` varchar(50) DEFAULT NULL,
 `area_util` varchar(255) DEFAULT NULL,
 `area_bruta` varchar(255) DEFAULT NULL,
 `area_terreno` varchar(255) DEFAULT NULL,
 `montante` varchar(255) DEFAULT NULL,
 `morada` varchar(255) DEFAULT NULL,
 `codpostal` varchar(4) DEFAULT NULL,
 `codpostal_ind` varchar(3) DEFAULT NULL,
 `localidade` varchar(255) DEFAULT NULL,
 `id_distrito` int(11) DEFAULT NULL,
 `id_concelho` int(11) DEFAULT NULL,
 `freguesia` varchar(50) DEFAULT NULL,
 `mini_descricao` varchar(255) DEFAULT NULL,
 `descricao` varchar(800) DEFAULT NULL,
 `Imagem1` varchar(255) DEFAULT NULL,
 `Imagem2` varchar(255) DEFAULT NULL,
 `Imagem3` varchar(255) DEFAULT NULL,
 `Imagem4` varchar(255) DEFAULT NULL,
 `Imagem5` varchar(255) DEFAULT NULL,
 `estado` tinyint(1) NOT NULL DEFAULT '2',
 `data_insercao` date NOT NULL,
 PRIMARY KEY (`id`),
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;

INSERT INTO `imoveis` (`id`, `id_estado`, `area_util`, `area_bruta`, `area_terreno`, `montante`, `morada`, `codpostal`, `codpostal_ind`, `localidade`, `id_distrito`, `id_concelho`, `freguesia`, `mini_descricao`, `descricao`, `Imagem1`, `Imagem2`, `Imagem3`, `Imagem4`, `Imagem5`, `estado`, `data_insercao`) VALUES
(1, 'Novo', 'n/a', 'n/a', 'n/a', '144.000', 'Rua D. Afonso henriques', '5454', '565', 'Castelo Branco', 5, 149, 'Castelo Branco', 'Garagem, com acesso a casa pelo exterior. Piscina interior.', 'Moradia composta por R/C, 1º Andar e Sotão. R/C - Sala 20m², acesso ao terraço, cozinha 14m², móveis em carvalho e bancada em granito, acesso ao terraço e WC. 1º Andar - Quarto 14m², varanda, quarto 15m², roupeiro e varanda, suite 16m², 2 roupeiros. Garagem e piscina.', 'Imagem0001.jpg', 'Imagem002.jpg', 'Imagem03.jpg', 'Imagem004.jpg', 'Imagem005.jpg', 1, '2012-02-02'),

CREATE TABLE IF NOT EXISTS `divisao` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `nome` varchar(255) NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=32 ;

INSERT INTO `divisao` (`id`, `nome`) VALUES
(1, 'Arrecadação'),
(2, 'Alpendre'),
(3, 'Biblioteca'),
(4, 'Casa de Banho'),
(5, 'Casa de Banho'),
(6, 'Casa de Banho'),
(7, 'Casa de Banho'),
(8, 'Casa de Banho'),
(9, 'Casa de Banho Partilhada'),
(10, 'Casa de Banho Privativa'),
(11, 'Closet'),
(12, 'Corredor'),
(13, 'Cozinha'),
(14, 'Cozinha Equipada'),
(15, 'Cozinha semi-equipada'),
(16, 'Despensa'),
(17, 'Escritório'),
(18, 'Hall'),
(19, 'Hall de Quartos'),
(20, 'Quarto'),
(21, 'Quarto'),
(22, 'Quarto'),
(23, 'Quarto'),
(24, 'Quarto'),
(25, 'Quarto Visitas'),
(26, 'Sala Comum'),
(27, 'Sala de Estar'),
(28, 'Sala de Jantar'),
(29, 'Sotão'),
(30, 'Suite'),
(31, 'Suite');

CREATE TABLE IF NOT EXISTS `imovel_divisoes` (
 `imovel_id` int(11) NOT NULL,
 `divisao_id` int(11) NOT NULL,
 `descricao` varchar(255) NOT NULL,
 `metros_quadrados` int(11) NOT NULL,
 PRIMARY KEY (`imovel_id`,`divisao_id`),
 KEY `imovel_id` (`imovel_id`),
 KEY `divisao_id` (`divisao_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

 

Acrescentei as divisões com checkboxes utilizando:

   <?php

	$q = mysql_query("SELECT * from divisao");
	while($nomes = mysql_fetch_array($q)){
   ?>
   	<input type="checkbox" name="divisoes[]" id="<?php echo $nomes["id"]; ?>" value="<?php echo $nomes["nome"]; ?>" onClick="chckd()"><?php echo $nomes["nome"]; ?>
    <div id="div_<?php echo $nomes["id"]; ?>" style="display: none;">
       	<input name="desc_<?php echo $nomes["nome"]; ?>" type="text" id="desc_<?php echo $nomes["nome"]; ?>" size="61" value="Digite aqui a descrição" onfocus="if (this.value == 'Digite aqui a descrição') {this.value = '';}" onblur="if (this.value == '') {this.value = 'Digite aqui a descrição';}" class="form_pesquisa" />
      		<input name="area_<?php echo $nomes["id"]; ?>" type="text" id="area_<?php echo $nomes["id"]; ?>" size="2" /> <label>m²</label></div>

   <?php
  	    };
   ?>

 

E conforme a imagem:

 

img01ui.jpg

 

À medida que clico na checkbox surge a caixa de texto para introdução da descrição e dos metros quadrados.

 

 

A minha dúvida é que eu estava a fazer um simples INSERT INTO para a tabela imóveis, mas agora como tenho a terceira tabela, tenho que fazer outro INSERT INTO para esta terceira tabela (imovel_divisões), ficando com 2 INSERT INTO ou há outra maneira mais eficiente de fazer?

 

Desculpem a pergunta, mas ainda não tinha necessidade de efectuar a gestão de registos com relacionamento N:N.

Obrigado pela ajuda.

 

Cumprimentos,

AndreLC90

Compartilhar este post


Link para o post
Compartilhar em outros sites

Está certo. Será um insert para a tabela imoveis, e vários inserts para a tabela imovel_divisões, de acordo com a quantidade de divisões marcadas.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Caramba a modelagem do seu banco está um tanto bagunçada.Com esse tanto de campos (tuplas)é possível criar outras diversas tabelas e outros relacionamentos.Sugiro dar uma estudada sobre MER(ou DER).

Abraço.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Está certo. Será um insert para a tabela imoveis, e vários inserts para a tabela imovel_divisões, de acordo com a quantidade de divisões marcadas.

 

Exacto mas como faço a insert para a tabela imovel_divisoes de maneira correcta? Como tenho aquela parte da checkbox dinamicamente estou um pouco confuso.

 

Obrigado pela ajuda.

 

Caramba a modelagem do seu banco está um tanto bagunçada.Com esse tanto de campos (tuplas)é possível criar outras diversas tabelas e outros relacionamentos.Sugiro dar uma estudada sobre MER(ou DER).

Abraço.

 

Eu tenho outras tabelas e relacionamente entre elas, apenas coloquei o que é necessário para a minha dúvida, obrigado pelo reparo.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não tem muito a ver com PHP, vou mover para a área correta:

PHP :seta: MySQL

 

OK, discordo porque na teoria percebo os relacionamentos muitos-para-muitos, apenas não sei como fazer em php.

 

E estou confuso como tenha aquela parte das checkboxes dinâmicamente não sei como recupero a checkbox que clicquei e posteriormente gravar correctamente na terceira tabela.

 

Obrigado pela ajuda.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Os checkboxes clicados vão estar "setados".

Fazendo um IF(isset($post[nome_do_checkbox)) vai retornar verdadeiro para os marcados, e falso para os não marcados. Então se entrar no if, insere na tabela.

 

Pode fazer um if para cada nome do checkbox, ou usar a mesma estrutura que você usou para criá-los.

 

Não sei se é essa a dúvida, mas começa a escrever, e vai perguntando o que precisa, postando o código pra facilitar.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Os checkboxes clicados vão estar "setados".

Fazendo um IF(isset($post[nome_do_checkbox)) vai retornar verdadeiro para os marcados, e falso para os não marcados. Então se entrar no if, insere na tabela.

 

Pode fazer um if para cada nome do checkbox, ou usar a mesma estrutura que você usou para criá-los.

 

Não sei se é essa a dúvida, mas começa a escrever, e vai perguntando o que precisa, postando o código pra facilitar.

 

O meu problema é mesmo ser a questão de ser uma relação muitos para muitos, estou baralhado. Pois tenho que inserir na tabela de associação (imovel_divisoes) o id do imovel e o id da divisao e respectiva descrição e metros quadrados.

 

Por exemplo, conforme as checkboxes seleccionadas na imagem e imaginando que estou a registar o imóvel 20, iria ficar na tabela:

 

20, 1, descricao, metros

20, 3, descricao, metros

20, 6, descricao, metros

20, 7, descricao, metros

20, 12, descricao, metros

20, 13, descricao, metros

 

Seleccionando 6 checkboxes fico com 6 registos na tabela, se seleccionar todas vou ficar com muitas linhas, a tabela vai ficar muito pesada, será mesmo assim??? Estou a pensar de maneira certa???

 

Depois como recupero os resultados para o browser, com uma query com INNER JOIN?

 

Como o id do imóvel é auto increment como vou saber o id na hora de registar nesta tabela de associação? Ainda para mais se for o primeiro imóvel que vou inserir tem que ser o id com o n.º 1!!

 

Espero não ter sido confuso.

 

Valeu pela ajuda.

Obrigado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Como tenho aquela parte em ciclo a gerar as checkboxes e como o name está com array...

 

Como faço o ciclo correctamente para guardar os registos das checkboxes e da respectiva descricao e dos m2 na tabela de associação imovel_divisoes?

 

Estou a enviar os dados assim:

 

   <?php

               $q = mysql_query("SELECT * from divisao");
               while($nomes = mysql_fetch_array($q)){
   ?>
       <input type="checkbox" name="divisoes[]" id="<?php echo $nomes["id"]; ?>" value="<?php echo $nomes["nome"]; ?>" onClick="chckd()"><?php echo $nomes["nome"]; ?>
           <div id="div_<?php echo $nomes["id"]; ?>" style="display: none;">
               <input name="desc_<?php echo $nomes["nome"]; ?>" type="text" id="desc_<?php echo $nomes["nome"]; ?>" size="61" value="Digite aqui a descrição" onfocus="if (this.value == 'Digite aqui a descrição') {this.value = '';}" onblur="if (this.value == '') {this.value = 'Digite aqui a descrição';}" class="form_pesquisa" />
               <input name="area_<?php echo $nomes["id"]; ?>" type="text" id="area_<?php echo $nomes["id"]; ?>" size="2" /> <label>m²</label></div>

   <?php
           };
   ?>

 

Agora seria algo do género:

 

//Aqui não há problema
$query_imoveis = "INSERT INTO imoveis (...)";
mysql_query($query_imoveis);

$id_imovel = mysql_insert_id();

//Aqui as minhas dúvidas:
//Como as checks no outro lado estão em ciclo aqui também terei que colocar algum ciclo, mas como ficaria?

//if (isset($_POST['divisoes'])) ? Deve faltar mais que isto concerteza... Talvez um for, while, foreach... ?
//{
  $query_imoveldivisoes = "INSERT INTO imovel_divisoes (imovel_id, divisao_id, descricao, metros_quadrados) VALUES ('$id_imovel', '???', '???', '???')";
  mysql_query($query_imoveldivisoes);
//}

 

OU

 

// inserir imóvel
...
// obter a lista de divisões
$rs = mysql_query("SELECT * from divisao");
while (($divisoes = mysql_fetch_array($rs)) != null) {

 // verificar se a info/id do registo vem assinalada pelos checkboxes
 if (isset($_POST['divisoes'])){

       //foreach($_POST['divisoes'] as $divisao){ ????

               $query_imoveisdivisoes = "INSERT INTO imovel_divisoes (imovel_id, divisao_id, descricao, metros_quadrados) VALUES ('$id_imovel', '$divisao???', '???', '???')";
               mysql_query($query_imoveisdivisoes);

    //} //foreach
 } //if
} //while

 

??? Coloquei assim mas ainda não está lá. Como obtenho também o nome da caixa de texto da descrição assim: desc_<?php echo $nomes["nome"]; ?> e dos metros quadrados assim: area_<?php echo $nomes["id"]; ?> como trato isto?

 

Obrigado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Já insere na tabela de associação, mas agora há um pequeno problema...

 

Fazendo um echo à query, reparo que me retorna 31 (que é o número de checkboxes que tenho) INSERT INTO, contudo adiciona somente na tabela uma vez como se esperava, mas queria colocar isto correctamente.

 

A imagem do echo à query:

 

abclq.jpg

 

Sei que é por estar dentro do ciclo, mas se retirar dentro do ciclo, se eu seleccionar 3 checkboxes, por exemplo, apenas grava-me a informação da última checkbox na tabela.

 

Queria corrigir essa situação. Poderiam ver o que se passa?

 

Tenho assim:

 

//INSERT de Imoveis - Aqui tudo bem
$query_imoveis = "INSERT INTO imoveis (...) VALUES (...)";
mysql_query($query_imoveis);

$id_imovel = mysql_insert_id();

//INSERT de imovel_divisoes na tabela de associação (DÚVIDA)

// obter a lista de divisões
$rs = mysql_query("SELECT * from divisao");
while (($divisoes = mysql_fetch_array($rs)) != null) {
   // verificar se a info/id do registo vem assinalada pelos checkboxes
   if (isset($_POST['divisoes'])) {
       foreach ($_POST['divisoes'] as $key => $id_divisao) {
           $desc_divisao = $_POST['desc'][$id_divisao];
           $metros       = $_POST['area'][$id_divisao];

           $query_imoveisdivisoes = "INSERT INTO `imovel_divisoes` (imovel_id, divisao_id, descricao, metros_quadrados) VALUES ('$id_imovel', '$id_divisao', '$desc_divisao', '$metros')";
           mysql_query($query_imoveisdivisoes);
           //echo $query_imoveisdivisoes;
       } //foreach
   } //if
} //while

 

Obrigado pela ajuda.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Mas é assim mesmo, apenas através de um foreach é q você consegue varrer o array do checkbox, senao ele só traz o último valor.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Mas aqui está a varrer uma data de vezes! É mesmo assim então?

 

Agora tendo o adicionar como faço o atualizar e o deletar?

 

Pois, por exemplo, no atualizar se escolher mais outra checkbox terá que inserir um novo registro na terceira tabela, mas se quiser desmarcar uma checkbox que já tivesse inserido terá que deletar o registro na terceira tabela, então não vai ser bem um update não é verdade?

 

A ideia seria como este exemplo: http://examples.codecharge.com/ExamplePack/ManyToManyCheckbox/ManyToManyCheckbox.php

 

Valeu pela ajuda.

 

Mas é assim mesmo, apenas através de um foreach é q você consegue varrer o array do checkbox, senao ele só traz o último valor.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.