Recebi n+1 consulta enquanto trabalhava com meus modelos e pivô
Receita.php:
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function ingredients(): BelongsToMany
{
return $this->belongsToMany(Ingredient::class)
->using(IngredientRecipe::class)
->withTimestamps()
->withPivot(['quantity', 'unit_id']);
}
IngredientRecipe.php (Pivot):
public function unit(): BelongsTo
{
return $this->belongsTo(Unit::class);
}
Ingrediente.php:
public function recipes(): BelongsToMany
{
return $this->belongsToMany(Recipe::class);
}
Unidade.php:
public function ingredient_recipes(): HasMany
{
return $this->hasMany(IngredientRecipe::class);
}
O que estou tentando fazer:
Na minha página de perfil de usuário, quero mostrar uma lista de receitas para o proprietário (usuário). Cada receita tem ingredients()
uma tabela dinâmica com colunas adicionais quantity
eunit_id
Código:
No meu ProfileController.php
estou usando este código:
public function show_profile(User $user)
{
$userRecipes = $user->recipes()->with('ingredients', 'guideSteps')->get();
return view('user.user-profile', compact('user', 'userRecipes'));
}
Problema:
O Laravel não sabe que isso pivot->unit_id
está relacionado ao Unit
modelo, então toda vez que acesso pivot->unit
, ele faz uma consulta separada na units
tabela.
Na barra de depuração estou recebendo 15 consultas duplicadas :
selecione * de users
onde users
. id
= 1 limite 1
selecione * de units
onde units
. id
= 3 limite 1
selecione * de units
onde units
. id
= 3 limite 1
... mais 12
E um problema está neste lugar:
@foreach($userRecipes as $recipe)
<x-recipe-card :recipe="$recipe"/>
@endforeach
---------------inside component recipe-card:------------------------
@foreach($recipe->ingredients as $ingredient)
<div>
<span>{{ $ingredient->name }}</span>
<div></div>
<span>{{ $ingredient->pivot->quantity . ' '. $ingredient->pivot->unit->name}}</span>
</div>
@endforeach
O Laravel não carregará automaticamente relacionamentos definidos dentro de modelos de pivô.
Tente algo assim (não testado)
EDITAR 02