Site

Queries de Relação

v4

Filtre 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_has em vez de where_raw quando possível