Depois de ter criado o post sobre o Behavior para melhorar o find, cá está ele! Ontem a noite criei o projeto e enviei o código que tenho para o GitHub, no projeto entitulado de super_find.
Tinha dito que o nome seria power find, mas depois de ver alguns projetos na internet como o SuperAuth, SuperValidatable, etc., resolvi manter o nome de SuperFind.
Bem, vamos ao que interessa, o que faz e como funciona… Basicamente, ele serve para fazer um find podendo colocar condições de relacionamentos hasMany e HABTM. No CakePHP puro isto não é possível, pois ele joga estas condições na query direto e acaba causando um erro de SQL. Aí você dizer, mas e o Containable?! Bem, ele até faz alguns filtros, mas o filtro que ele faz é em cima do valor retornado da consulta principal. Vamos a um exemplo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | $this->Usuario->find('all', array('contain' => array('Tarefa.nome = "Tarefa 1"))); /* Retorno: array( array( 'Usuario' => array('id' => 1, 'nome' => 'Usuario 1'), 'Tarefa' => array( array('id' => 1, 'nome' => 'Task 1', 'usuario_id' => 1) ) ), array( 'Usuario' => array('id' => 2, 'nome' => 'Usuario 2'), 'Tarefa' => array( ) ), array( 'Usuario' => array('id' => 3, 'nome' => 'Usuario 3'), 'Tarefa' => array( ) ), ) */ $this->Usuario->superFind('all', array('conditions' => array('Tarefa.nome' => 'Tarefa 1'))); /* Retorna: array( array( 'Usuario' => array('id' => 1, 'nome' => 'Usuario 1'), 'Tarefa' => array( array('id' => 1, 'nome' => 'Tarefa 1', 'usuario_id' => 1) ) ) ) */ |
Em resumo, no Containable ele listou todos os usuários e no relacionamento Tarefa veio apenas os que tinham a ‘Tarefa 1′. Já no SuperFind ele mostrou apenas os usuários que tinham a ‘Tarefa 1′.
O mesmo funciona com relacionamentos HABTM. Para os relacionamentos hasOne e belongsTo não são necessários, pois isto já funciona nativamente.
Por enquanto é possível fazer isto apenas com um nível de filtro, ou seja, você não poderá colocar nas condições algo como Tarefa.Projeto.nome.
Bem, por enquanto é isso. Alguém tem mais sugestões do que poderia entrar? O que sente falta no find?
Abraços e bom uso.
Já que você perguntou, hehe
eu sinto falta de algo que retorne somente os valores de itens que contenham registro em outro tabela, tipo o select abaixo:
select * from users where id in (select distinct user_id from posts)
Tentei usar seu superFind porém ele ainda retorna os users sem posts.
Eis meu código:
$conditions = array(‘Questao.curso_id’ => ‘Curso.id’);
$cursos = $this->Inscricao->Curso->superFind(‘all’, $conditions);
Se souber de alguma luz no fim do tunel fico agradecido.
obrigado.
Comentário por FelipeVR — 28 abril 2010 @ 11:04 am
Código reloaded:
$conditions = array(‘Post.user_id’ => ‘User.id’);
$posts = $this->Post->User->superFind(‘all’, $conditions);
Comentário por FelipeVR — 28 abril 2010 @ 11:06 am
Olá Felipe. Eu não tinha pensado nesta questão, mas você pode fazer algo como “$this->User->superFind(‘all’, array(‘conditions’ => ‘Post.id > 0′));”
Uma coisa do seu código: não esqueça de colocar a chave ‘conditions’ no superFind, senão ele não irá funcionar.
Comentário por Juan Basso — 28 abril 2010 @ 1:37 pm
Po esse super find eh uma mão na roda, po juan, vi q você tem um repositório no google de um ERP free, mas não tem nenhum commit, morreu a idéia?
Comentário por Leonardo — 29 abril 2010 @ 12:24 am
Opa, obrigado. O repositório de ERP foi uma idéia antiga que por falta de tempo meio que morreu sim.
Comentário por Juan Basso — 29 abril 2010 @ 8:15 am
Assim no Containable:
$this->Usuario->find(‘all’, array(‘contain’ => array(‘Tarefa’ => array(‘nome’ => “Tarefa 1″))));
Assim funcionava aqui (pelo que me lembro)… mas mesmo assim sempre tive problemas… principalmente com HABTM (quando queria salvar e associar ao mesmo tempo ou fazer finds)…
Muito bom o behavior… você poderia alterar para ter um superSave (que funfe o HABTM… se bem que nem seria necessario, um pouco de beforeSave no proprio behavior e foi ontem xD)
Comentário por Lucas — 5 maio 2010 @ 8:43 am
Mais um grande projeto.
Vai poupar bastante tempo de criar alguns joins =p
Obrigado.
Comentário por Léo Haddad — 1 junho 2010 @ 10:55 pm