Estou fazendo um aplicativo de planejamento de casamento onde os usuários podem adicionar seus convidados a determinadas mesas, grupos, etc...
Estou tentando listar todos os grupos e dentro de cada grupo mostrar todos os convidados desse grupo (na mesma página like e acordeão)
Parece fácil e funciona, mas ao usar o DebugBar, posso ver que ele está fazendo duas consultas exatamente iguais e não consigo descobrir o porquê.
Um Evento pode ter muitos grupos e cada grupo pode ter muitos convidados.
$event = Event::find($id_event);
$event->load('group');
$event->group->load([
"guest" => function ($q) {
return $q->paginate(10);
}
]);
Editar
Esqueci de mencionar que se eu adicionar outras relações a isso, elas também serão duplicadas.
$event->group->load([
'guest.plusone',
"guest" => function ($q) {
$q->paginate(10);
}
]);
Editar 2
Ao tentar fazer o que você sugeriu, descobri o que causa isso, mas ainda não sei por quê.
Quando tento fazer o que você sugeriu, obtenho o mesmo resultado
$event->load(['group', 'group.guest' => function ($query) {
$query->paginate(10);
}]);
Mas se eu remover o retorno de chamada da paginação, receberei apenas uma consulta. Isso é normal? Eu sei que a paginação faz uma consulta extra para obter os resultados totais, mas neste caso está fazendo 3 consultas e 2 delas são exatamente iguais
Primeiramente pelo que você está fazendo, o resultado de 2 consultas é muito esperado. Veja abaixo a explicação:
Explicação:
ao chamar paginate você está forçando a execução de uma consulta, a mesma consulta que foi construída pelas definições de relação até aquele ponto. O mesmo aconteceria ligando para
$with->get()
. Mas o fechamento não espera que você execute uma consulta, nem se importa com isso, apenas modifique a consulta fornecida. Portanto, após uma consulta ser executada viapaginate
, observe que seu resultado não é usado em lugar nenhum, o fechamento termina e o Laravel executa a consulta de carregamento ansioso de relacionamento como faria normalmente.Para Laravel 11:
para o que você deseja alcançar, limite os modelos de relação carregados a 10 por grupo, você precisa usar um limite. Limit não executa uma consulta, mas modifica o objeto de consulta para incluir um limite quando for executado.
Antes do Laravel 11:
embora você possa fazer o mesmo no Laravel 10, o resultado que você obterá não é o mesmo. O limite será aplicado a todos os convidados carregados, não por grupo. Então se você tem grupo A e B com 10 convidados cada. Os dados resultantes incluiriam os 10 convidados do grupo A, mas 0 convidados do grupo B. Isso ocorre porque apenas 10 convidados foram carregados no total, e não 10 para cada grupo.
Para obter a mesma funcionalidade, você precisa incluir https://github.com/staudenmeir/eloquent-eager-limit em seu projeto e seguir suas instruções. (No Laravel 11 este pacote foi mesclado)