Lançado Adianti Framework 7.6!
Clique aqui para saber mais
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.     
  18.         $str implode(', '$autores); // Transforma o array em string separada por vírgula
  19.         
  20.         return $str;
  21.     }
  22. ?>


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.

Pacotão Dominando o Adianti Framework 7
O material mais completo de treinamento do Framework.
Curso em vídeo aulas + Livro completo + Códigos fontes do projeto ERPHouse.
Conteúdo Atualizado! Versão 7.4


Dominando o Adianti 7 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.     /**
  13.      * Method getPoloProcessual
  14.      * Retorna as partes processuais de um processo
  15.      * @return Collection of Polo Processual
  16.      */
  17.     public function getPoloProcessual()
  18.     {
  19.         return $this->polo_processual;
  20.     }
  21. /**
  22.      * Load the object and its aggregates
  23.      * @param $id object ID
  24.      */
  25.     public function load($id)
  26.     {
  27.         $this->polo_processual    parent::loadComposite('PoloProcessual''processo_id'$id);
  28.     
  29.         // load the object itself
  30.         return parent::load($id);
  31.     }
  32.     
  33.     /**
  34.      * Store the object and its aggregates
  35.      */
  36.     public function store()
  37.     {
  38.         // store the object itself
  39.         parent::store();
  40.     
  41.         parent::saveComposite('PoloProcessual''processo_id'$this->id$this->polo_processual);
  42.     }    
  43. ?>


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.     
  18.         $str implode(', '$autores); // Transforma o array em string separada por vírgula
  19.         
  20.         return $str;
  21.     }
  22. ?>

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.