Auto Relacionamento de Categorias

Olá a todos,

To com uma ‘bucha’, que to quase careca de pensar.

Vamos aos fatos.

Tenho uma tabela ‘produto’, e ‘categoriaproduto’.

produto: codproduto, codprodutocategoria

categoriaproduto: codprodutocategoria, codpai

Como visto a tabela categoriaproduto, tem um auto-relacionamento.

Ai vem a questão:

Até o primeiro ‘produto p INNER JOIN categoriaproduto cp ON p.codprodutocategoria = cp.codprodutocategoria’.

Até ae tudo bem, o que complico e não traz a ‘query’ correta, e outro relacionamento de categoriaproduto para categoriaproduto novamente, mais pra que isso?

Por que eu preciso mostrar o produto, mais que a título da categoria seja ‘%adesivo%’, eu queria pegar pelo menos o segundo nível do relacionamento.

Fiz a seguinte relação no Model:




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(

            'produtocategoria' => array(self::MANY_MANY, 'Produtocategoria', 'produtocategoria(codprodutocategoria, codpai)',

                'alias'=>'pc',

                'together'=>true,

                'joinType'=>'INNER JOIN'

                ),

        );

    }



Query:




SELECT `p`.`codproduto` AS `t0_c0`, `p`.`codprodutocategoria`

AS `t0_c1`, `p`.`codigo` AS `t0_c2`, `p`.`titulo` AS `t0_c3`,

`p`.`datacriacao` AS `t0_c4`, `p`.`dataatualizacao` AS `t0_c5`,

`p`.`liberar` AS `t0_c6`, `p`.`lancamento` AS `t0_c7`,

`pc`.`codprodutocategoria` AS `t1_c0`, `pc`.`codpai` AS `t1_c1`,

`pc`.`titulo` AS `t1_c2`, `pc`.`datacriacao` AS `t1_c3`,

`pc`.`dataatualizacao` AS `t1_c4` FROM `produto` `p`  INNER JOIN

`produtocategoria` `produtocategoria_pc` ON

(`p`.`codproduto`=`produtocategoria_pc`.`codprodutocategoria`) INNER JOIN

`produtocategoria` `pc` ON

(`pc`.`codprodutocategoria`=`produtocategoria_pc`.`codpai`)  WHERE

(p.liberar = '1' AND produtocategoria_pc.titulo NOT LIKE '%adesivo%') ORDER

BY codproduto DESC LIMIT 16



Observa que no último relacionamento está invertido (pc.codprodutocategoria=produtocategoria_pc.codpai), e onde está dando o erro, eu precisava que o ‘codpai = codprodutocategoria’

To penando aqui, mais sem sucesso, se alguem puder me ajudar.

Segue abaixo o estanciamento do produto:




$produtos = Produto::model()->findAll(array(

                    'alias' => 'p',

                    'condition' => "p.liberar = '1' AND produtocategoria_pc.titulo NOT LIKE '%adesivo%' AND pc.titulo NOT LIKE '%adesivo%'",

                    'order' => 'codproduto DESC',

                    'limit' => '16',

                    'with' => array('produtocategoria')

                ));



Tem 2 NOT LIKE, seria no máximo 2 nível que queria.

Cara, esse SQL é o gerado pelo Yii????

Não tendi. Se ele é um MANY_MANY, qual a tabela que fica no meio da produtos e Produtocategoria?

Daniel,

Esse SQL é gerado pelo Yii, peguei do LOG.

Eu coloquei MANY_MANY, por que a Produtocategoria, se auto relaciona!

Vou citar um exemplo,

Um determinado Produto, está na categoria (Adesivos), e nessa categoria, tem uma Subcategoria (Colorido).

A pesquisa anterior, sem esse MANY_MANY, só com TO_BELONG(produto->produtocategoria), funciona, por que ele vai até a primeira categoria (Adesivos).

Só que eu queria colocar mais 1 nível abaixo dessa categoria Adesivos, gostaria de mostrar os produtos da subcategoria (Colorido), por isso fiz esse auto-relaciomaneto com MANY_MANYY emcima da categoriaproduto.

O SQL gerado pelo Yii, está quase normal, o problema que o último JOIN está invertido a relação, ele está buscando (codprodutocategoria = codpai), o correto é pegar (codpai = codprodutocategoria).

Entendi a sua idéia, mas acho que não é a ordem do último não. Pq com inner join não faz diferença o lado que a sequência está. No mais, acho que, mesmo que o problema seja este, não sei se tem como modificar a ordem dos parâmetros gerados pelo Yii. Talvez seja necessário SQL direto neste caso.

Daniel,

Vou ter que usar outra solução, vou avisar para o cliente adicionar junto as subcategoria o titulo da Categoria Principal, por exemplo:

Adesivo

Colorido

Vermelho


Azul

Assim não funciona, solução!

Adesivo

Adesivo - Colorido

Adesivo - Vermelho


Adesivo - Azul

Se ficar muito poluido, vou usar SQL direto que nen tu cito.

O pior é que eu tava doido pra saber se vc ia conseguir fazer desta forma. Semana que vem vou fazer a categorização dos produtos daqui :(

Pois é, ontem de noite fiquei doido, fiz de todas as formas, usei todas as relação, percorri o forum todo, o google todo, e o máximo que consegui foi chega nessa query que o Yii gerou!

E que assim Daniel, raciocina comigo, as subcategorias que tenho, usei em uma CTreeView na Administração, na hora de adicionar o Produto, aparece a árvore normal, mais eu coloquei um <input radio> em cada item, ai o Produto só pertence a 1 Categoria ou Subcategoria, nunca em duas ou mais, agora pensando assim, se eu mudar pra <input checkbox> e criar outra tabela, para contêr o codproduto e codprodutocategoria, ai sim a relação MANY_MANY funciona perfeitamente.

Produto

[font="Courier New"]

±—±----------+

| id | titulo |

±—±----------+

| 1 | Produto 1 |

±—±----------+

| 2 | Produto 2 |

±—±----------+

Produto_categoria

±----------±--------------------+

|codproduto | codprodutocategoria |

±----------±--------------------+

| 1 | 1 |

±----------±--------------------+

| 1 | 3 |

±----------±--------------------+

| 2 | 1 |

±----------±--------------------+

| 2 | 4 |

±----------±--------------------+

Produtocategoria

±—±-------±-------+

| id | parent | titulo

±—±-------±-------+

| 1 | NULL | Categoria 1

±—±-------±-------+

| 2 | NULL | Categoria 2

±—±-------±-------+

| 3 | 1 | Subcategoria 1.1

±—±-------±-------+

| 4 | 2 | Subcategoria 2.1

±—±-------+

[/font]

Eu tenho quase certeza que dessa forma, tu consegue o que deseja, eu to usando só a Tabela Produto e CategoriaProduto, não tenho uma tabela intermediaria para administrar isso, por que cada Produto pertence a 1 categoria só.

Mais desenhando essa tabela pra você, to pensando em mudar, lógicamente é melhor para manipular vários niveis.

Bom falei de mais, tira sua conclusão, e veja se te atende, ou se fiz algo de errado.

Ahe, Brow nao sei se é isso que vc quer:




SELECT p.* 

FROM produtos p 

INNER JOIN categorias c ON c.id = p.categoria_id OR c.pai = p.categoria_id

WHERE c.id = 'coloco a id aqui' OR c.pai = 'coloco a id aqui'

GROUP BY p.id

Pode ser que te ajude!

Edson,

Eu fiz por SQL mesmo, sorte que todo produto que era Papel e/ou Adesivo, tinha no titulo do produto descrevendo o que era.

Mais como a Cliente estava dando nojo abandonaram o projeto!

Daquelas cliente nojenta demais, que pelo investimento não valia o re-trabalho.

Mais valeu.