Ir para conteúdo

Arquivado

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

rockrgo

Artigo com mais de uma categoria

Recommended Posts

Boa tarde pessoal,

 

estou criando um site de noticias onde tenho categorias dinâmicas que podem ser criadas a qualquer momento, preciso relacionar uma notícia a mais de uma categoria, mas não sei como buscar os dados depois.

 

já fiz algo deste tipo com categorias fixas, pois eram 4 categorias somente, então inclui 4 campos a mais no registro da noticia.

 

pensei em usar json para salvar o id das categorias....mas depois não sei se da para buscar um único id na minha query.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá colega, minha idéia é você mostrar um checkbox em formato de array para o usuário marcar as categorias da notícia na hora de publicar. O value será o id da catgegoria.

 

Ai você usa um foreach, junta os valores, separa por vírgula e insere no banco em uma coluna da tabela notícias chamada categorias.

 

Na página das categorias, você faz uma busca na tabela notícias, na coluna categorias usando o LIKE com o id da categoria.

 

Ou seja, se o id da categoria for 5, ele vai trazer todas as notícias que tenham na coluna categorias o id 5.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ai você usa um foreach, junta os valores, separa por vírgula e insere no banco [...]

Fazendo dessa forma, você perde toda a integridade que um SGBD pode fornecer.

 

O correto é utilizar uma tabela N:N, também conhecido como many-to-many (muitos para muitos).

 

Nada mais é que uma tabela intermediária, entre categoria e artigo, que servirá como link entre um artigo e uma categoria.

 

Tal como na imagem abaixo:

many-to-many.png

 

Onde a tabela category_has_product cria um link entre category e product.

 

Também parte da normalização de dados.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Valeu Gabriel ...... como este problema só apareceu depois do projeto já em andamento nem havia me dado conta que poderia usar este tipo de relacionamento na tabela, mas clareou as idéias aqui.....vou redesenhar a estrutura das minhas tabelas!

 

Obrigado a todos!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Analisando bem, não sei se o modo N:N seria a melhor opção para mim. Pois eu tenho a categoria já criada mas o artigo eu estarei criando....

 

Aí quando fosse inserir a nova noticia, eu teria que inserir na tabela noticias primeiro para gerar a chave primária da notícia, depois teria que selecionar a ultima noticia criada na tabela para pegar o id da mesma e só aí fazer um loop para inserir cada relacionamento na tabela categorias_noticias.

 

Ou existe uma forma mais simples de se fazer isto?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Essa é a teoria e a prática:

- Cria-se a categoria;

- Cria-se a notícia;

- Vinculam-se ambas.

 

Entretanto, a criação da notícia e o vínculo da categoria pode ser feito de forma transparente ao usuário.

 

Formulário simples (bem simplificado) com título e seleção de uma, ou mais, categorias:

<form action="#" method="post" >
   <label for="titulo">Título</label>
   <input type="text" name="titulo" id="titulo" />

   <fieldset>
      <legend>Categorias</legend>

      <label for="categoria-1">Categoria 1</label>
      <input type="checkbox" name="categoria[]" id="categoria-1" value="1" />

      <label for="categoria-2">Categoria 2</label>
      <input type="checkbox" name="categoria[]" id="categoria-2" value="2" />

      <label for="categoria-3">Categoria 3</label>
      <input type="checkbox" name="categoria[]" id="categoria-3" value="3" />
   </fieldset>

    <button type="submit">Enviar</button>
</form>

 

Insert, utilizarei PDO para facilitar as coisas:

$pdo = new PDO('mysql:dbname=teste;host=localhost' , 'usuario' , 'senha');
$pdo->setAttribute(PDO::ATTR_ERRMODE , PDO::ERRMODE_EXCEPTION);

try {
    $statement = $pdo->prepare('INSERT INTO noticia (titulo) VALUES (:titulo)');
    $statement->bindValue(':titulo' , $_POST['titulo']);
    $statement->execute();
    
    $noticiaId = $pdo->lastInsertId();
    
    $statement->closeCursor();//Sempre importante fechar o cursor de um statement

    //é necessária a verificação, 
    //pois se não selecionar nenhuma categoria vai dar erro
    if(isset($_POST['categoria'])) {
       foreach($_POST['categoria'] AS $categoriaId) {
          $statement = $pdo->prepare('INSERT INTO categoria_has_noticia (categoriaid , noticiaid) VALUES (:categoriaid , :noticiaid)');
          $statement->bindValue(':categoriaid' , $categoriaId);
          $statement->bindValue(':noticiaid' , $noticiaId);
          $statement->execute();
          $statement->closeCursor();
       }       
    }
} catch (PDOException $exception) {
    echo $exception-getMessage();
}

Apesar da ordem de exigência, o cadastro foi feito de uma única vez com um único formulário de forma transparente ao usuário.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Entendi...mas e na hora de fazer um update na noticia caso não queira que faça mais parte de uma categoria....eu teria que buscar todos os registros de categoria_has_noticia e fazer uma comparação entre o resultado da busca e o array recebido via post, o que não estiver contido no outro eu faço um delete na tabela categoria_has_noticia.

 

Meu raciocínio está correto?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sim, está correto e também há outros modos, mas não são relevantes no momento.

 

Algo que esqueci de adicionar no script, foi o tratamento de transações.

 

Tente implementar a atualização (update) da forma que pensou e também tente implementar as transações (beginTransaction, commit e rollBack). Qualquer problema, poste-o aqui.

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.