Conheça  A Ferramenta LowCode mais moderna e veloz para desenvolvimento PHP: Adianti Creator
onSearch na listagem com campos de tabelas diferentes Boa noite, pessoal. Tenho uma listagem de registros que dentro da grid possui um campo que não tem referência dentro da Active Record da listagem porque se trata de uma composição e a chave estrangeira está na outra tabela. Assim, a forma que consegui para listar o registro estrangeiro foi criando um método get dentro do Active Record referenciando a tabela estrangeira da composição. ...
AA
onSearch na listagem com campos de tabelas diferentes  
Boa noite, pessoal.

Tenho uma listagem de registros que dentro da grid possui um campo que não tem referência dentro da Active Record da listagem porque se trata de uma composição e a chave estrangeira está na outra tabela. Assim, a forma que consegui para listar o registro estrangeiro foi criando um método get dentro do Active Record referenciando a tabela estrangeira da composição.

 
  1. <?php
  2. public function get_autores()
  3. {
  4. if (empty($this->autores))
  5. {
  6. $processo = new Processo($this->id);
  7. $pessoas[] = array();
  8. foreach ( $processo->polo_processual as $polo )
  9. {
  10. if ($polo->polo_processual == 'POLO_ATIVO')
  11. {
  12. $pessoa = new Pessoa($polo->pessoa_id);
  13. $autores[$pessoa->id] = $pessoa->nome; // Forma um array com todos os autores, se houver mais de um.
  14. }
  15. }
  16. }
  17. $str = implode(', ', $autores); // Transforma o array em string separada por vírgula
  18. return $str;
  19. }
  20. ?>


Na listagem tá funcionando como esperado, mas na hora de pesquisar o registro estou recebendo a mensagem:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'autores' in 'where clause'


Tal erro ocorre porque realmente não existe o campo no Active Record Processo, responsável pela listagem, e sim em outra tabela (PoloProcessual) que é responsável pela formação da composição, por isso o código $this->addFilterField('autores', 'like', 'autores'); não funciona já que autores é apenas um método get dentro da Active Record e o seu campo nome está em outra tabela.

Alguém tem uma solução para filtrar a tabela por esse campo estrangeiro?

Grato pela atenção.

Curso Dominando o Adianti Framework

O material mais completo de treinamento do Framework.
Curso em vídeo aulas + Livro completo + Códigos fontes do projeto ERPHouse.
Conteúdo Atualizado!


Dominando o Adianti Framework Quero me inscrever agora!

Comentários (6)


AA

Ainda sem consegui fazer essa consulta por esse campo estrangeiro gerado dinamicamente em formato de array. Alguém tem uma solução?
NR

https://www.adianti.com.br/forum/pt/view_866?usando-funcoes-e-subselects-em-crit
AA

O problema é que continuo sem a referência na TRecord. Deixa eu explicar melhor.

Tenho uma tabela chamada processos que possuem diversos campos e tem uma relação de N:N com a tabela pessoas. Para esse implementação criei uma terceira tabela (polos_processuais) para guardar as chaves primárias de processo e pessoa e fazer a vinculação.
 
  1. <?php
  2. public function __construct($id = NULL, $callObjectLoad = TRUE)
  3. {
  4. parent::__construct($id, $callObjectLoad);
  5. parent::addAttribute('polo_processual'); // Autor, réu, terceiro...
  6. parent::addAttribute('tipo_parte'); // Tipo de parte processual
  7. parent::addAttribute('is_cliente'); // Campo para verificar se é cliente
  8. parent::addAttribute('processo_id'); // Atributo do relacionamento com o processo
  9. parent::addAttribute('pessoa_id'); // Atributo do relacionamento com a tabela pessoas
  10. parent::addAttribute('uniqid');
  11. }
  12. ?>


A classe ProcessoList</p> possui uma listagem com vários campos próprio da tabela processos e um campo reservado para as pessoas que participam desse processo, cujo atributo se encontra em outra tabela. Para gravar e buscar os dados das pessoas que participam do processo fiz uma composição da classe Processo com a classe PoloProcessual, conforme abaixo:
 
  1. <?php
  2. /**
  3. * Method addPoloProcessual
  4. * Add um Polo Processual ao Processo
  5. * @param $object Instance of Polo Processual
  6. */
  7. public function addPoloProcessual(PoloProcessual $object)
  8. {
  9. $this->polo_processual[] = $object;
  10. }
  11. /**
  12. * Method getPoloProcessual
  13. * Retorna as partes processuais de um processo
  14. * @return Collection of Polo Processual
  15. */
  16. public function getPoloProcessual()
  17. {
  18. return $this->polo_processual;
  19. }
  20. /**
  21. * Load the object and its aggregates
  22. * @param $id object ID
  23. */
  24. public function load($id)
  25. {
  26. $this->polo_processual = parent::loadComposite('PoloProcessual', 'processo_id', $id);
  27. // load the object itself
  28. return parent::load($id);
  29. }
  30. /**
  31. * Store the object and its aggregates
  32. */
  33. public function store()
  34. {
  35. // store the object itself
  36. parent::store();
  37. parent::saveComposite('PoloProcessual', 'processo_id', $this->id, $this->polo_processual);
  38. }
  39. ?>


Todo o processo de gravação de registro e edição está funcionamento beleza, mas o problema é na listagem da grid. Como não tenho qualquer campo na TRecord processo que referencie a tabela polos_processuais eu fiz um método para buscar os dados e retornar um array separado por vírgulas.
 
  1. <?php
  2. public function get_autores()
  3. {
  4. if (empty($this->autores))
  5. {
  6. $processo = new Processo($this->id);
  7. $pessoas[] = array();
  8. foreach ( $processo->polo_processual as $polo )
  9. {
  10. if ($polo->polo_processual == 'POLO_ATIVO')
  11. {
  12. $pessoa = new Pessoa($polo->pessoa_id);
  13. $autores[$pessoa->id] = $pessoa->nome; // Forma um array com todos os autores, se houver mais de um.
  14. }
  15. }
  16. }
  17. $str = implode(', ', $autores); // Transforma o array em string separada por vírgula
  18. return $str;
  19. }
  20. ?>

Dessa forma, no preenchimento da grid bastou eu chamar esse método get_autores() que os dados foram apresentados. Contudo, esse mesmo método não funciona na busca onSearch. Sempre que eu coloco a chamada do método no TFilter dá o erro:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'autores' in 'where clause'

De igual forma eu não tenho como fazer uma subquery como você postou no link porque não tenho nenhum campo na tabela processo que referencie diretamente a tabela polos_processuais

Entendeu o problema? Alguma solução?

Desde já, agradeço.
AA

Acho que a solução seria por meio de join no SQL.

Tentei esse aqui:
 
  1. <?php $this->addFilterField('(SELECT p.nome FROM processos proc join polos_processuais pp on proc.id = pp.processo_id join pessoas p on pp.pessoa_id = p.id)', 'like', 'autores' ); ?>


Mas estou sofrendo o seguinte erro:
SQLSTATE[21000]: Cardinality violation: 1241 Operand should contain 1 column(s)
NR

A referência na TRecord que você precisa é o id:
 
  1. <?php
  2. parent::addFilterField('id', 'in', 'autores',function($filtro){
  3. return "(SELECT pp.processo_id FROM polos_processuais pp join pessoas p on pp.pessoa_id = p.id AND p.nome like '%{$filtro}%' )";
  4. });
  5. ?>
AA

Puts! Já tinha desistido, :D.

Deu certinho, Nataniel. Comportamento conforme esperado.

Muito obrigado por mais essa.