Sou novo no Eloquent Query Builder e tenho algumas perguntas:
Objetivo: Criar uma consulta que me retornará receitas que correspondam aos parâmetros especificados dos seletores :
- Categoria de Prato
- Subcategoria de Pratos
- Cozinha
- Menu
nuance importante: em seletores você não pode selecionar uma subcategoria sem primeiro selecionar uma categoria (lógica suspensa dependente usando livewire).
Após selecionar os parâmetros nos seletores, a URL fica assim:
http://127.0.0.1:8000/recipes?dish_category=2&dish_subcategory=37&cuisine=1&menu=1
Problema:
Notei que ainda posso remover o ID da categoria na URL e deixar apenas a subcategoria:
http://127.0.0.1:8000/recipes?dish_category=&dish_subcategory=37&cuisine=1&menu=1
Como obter um comportamento em que um usuário só pode inserir, por exemplo, "culinária" no seletor, e a consulta seleciona receitas que correspondem somente a esse parâmetro?
Código:
Atualmente, tenho este código, ele me mostra dados corretos, mas não tenho certeza se é uma maneira adequada de filtrar dados usando parâmetros de URL:
$recipes = Recipe::with('user', 'cuisine')
->where('dish_category_id', $request->query('dish_category'))
->orWhere('dish_subcategory_id', $request->query('dish_subcategory'))
->orWhere('cuisine_id', $request->query('cuisine'))
->orWhere('menu_id', $request->query('menu'))
->get();
dd($recipes);
e dd($recipes)
me mostra isso:
Illuminate\Database\Eloquent\Collection {#1085 ▼ // app\Http\Controllers\RecipeController.php:26
#items: array:2 [▼
0 =>
App\Models
\
Recipe {#1116 ▶}
1 =>
App\Models
\
Recipe {#1082 ▶}
]
#escapeWhenCastingToString: false
}
(2 receitas encontradas com os parâmetros especificados pelo usuário, também, se o usuário, por exemplo, inserir apenas o parâmetro Categoria: Caldo, então o mesmo resultado será obtido)
Conclusão:
O código atual funciona, mas preciso que ele não apenas funcione, mas também seja escrito corretamente. Também preciso levar em conta os problemas descritos acima.
Ficaria grato por conselhos e ajuda.
EDITAR 01:
Eu tentei a abordagem com when()
o método:
$recipes = DB::table('recipes')
->when($dish_category, function ($query, $dish_category){
$query->where('dish_category_id', $dish_category);
})
->when($dish_subcategory, function ($query, $dish_subcategory){
$query->where('dish_subcategory_id', $dish_subcategory);
})
->when($cuisine, function ($query, $cuisine){
$query->where('cuisine_id', $cuisine);
})
->when($menu, function ($query, $menu){
$query->where('menu_id', $menu);
})
->get();
funciona, mas ainda consigo colar dish_subcategory_id
a URL (não tenho certeza se é um bom comportamento quando não permito que o usuário selecione dish_subcategory
sem dish_category
seletores)
A maneira correta seria se você quiser permitir o uso
dish_subcategory_id
somente quandodish_category
estiver definido:Tenha em mente que isso não é o mesmo que a consulta inicial
orWhere
(mas pode ser exatamente o que você deseja alcançar).Editar: usado
use()
para adicionar a variável necessária ao escopo do método