Queries de Relação
v4Filtre models com base na existência de relacionamentos usandowhere_has() e where_doesnt_have(). O ORM gera subqueriesEXISTS — mais eficiente que JOIN em muitos cenários.
where_has()
Retorna apenas registros que possuem a relação. O primeiro argumento é o nome do método de relação no model (snake_case).
market_item::query()
->where_has('proto', function ($q) use ($search) {
$q->where('name', 'like', '%' . $search . '%');
})
->get();Exemplo real do módulo market: filtra itens do mercado que têm proto com nome correspondente.
where_doesnt_have()
Retorna registros que não possuem a relação (ou não satisfazem a condição).
shop_item::query()
->where_doesnt_have('offers', function ($q) use ($category) {
$q->where('category_id', $category);
})
->get();Exemplo real do módulo shop: itens sem ofertas em determinada categoria.
Com paginação
post::query()
->where('active', 1)
->where_has('category', function ($q) use ($slug) {
$q->where('slug', $slug);
})
->paginate(15);Na view
Para saber se um registro tem relação carregada, use with() no handler e verifique na view com PHP normal:
<?php if ($item->proto): ?>
<span><?= e($item->proto->name) ?></span>
<?php else: ?>
<span>Sem proto</span>
<?php endif; ?>Resumo
// Tem a relação
Model::where_has('relacao', fn ($q) => $q->where(...))->get();
// Não tem a relação
Model::where_doesnt_have('relacao')->get();Boas práticas
- Use
where_has()para filtrar por dados em tabelas relacionadas - Use
where_doesnt_have()para listar registros órfãos ou incompletos - Combine com
paginate()em listagens grandes - Mantenha índices nas colunas de FK usadas nas relações
- Prefira
where_hasem vez dewhere_rawquando possível