** How can I make this code easy . i use this query() function for many section i want to get event by filter. my filter based on tags and category(both are in pivot table) **
public function index(Request $request)
{
$customQuery = Event::where('status', '1');
if ($request->vehical_type) { //vehical filter
$customQuery->where('vehical_type', '=', $request->vehical_type);
}
if ($request->tag) { //tag filter
$id = $request->tag;
$customQuery->whereHas('tags', function (Builder $query) use ($id) {
$query->where('tag_id', $id);
});
}
if ($request->category) { //category filter
$id = $request->category;
$customQuery->whereHas('categories', function (Builder $query) use ($id) {
$query->where('category_id', $id);
});
}
$events = $customQuery->get(); //get event according to filters
$tags = Tag::whereHas('events', function (Builder $query) { //get all tags of events
$query->where('event_id', '>', 0);
})->get();
$categories = Category::whereHas('events', function (Builder $query) { //get all categories of events
$query->where('event_id', '>', 0);
})->get();
return view('frontend.event.index', compact('events', 'tags', 'categories'));
}
You could use when
for conditionals in the query and short hand closures with fn
to put them in a single line.
whereRelation
instead of whereHas
could make those queries a bit shorter too.
public function index(Request $request)
{
$events = Event::query()
->where('status', '1')
->when(
$request->vehical_type,
fn($query) => $query->where('vehical_type', $request->vehical_type)
)
->when(
$request->tag,
fn($query) => $query->whereRelation('tags', 'tag_id', $request->tag)
// or fn($query) => $query->whereHas('tags', fn($tags) => $tags->where('tag_id', $request->tag))
)
->when(
$request->category,
fn($query) => $query->whereRelation('categories', 'category_id', $request->category)
// or fn($query) => $query->whereHas('categories', fn($category) => $category->where('category_id', $request->category))
)
->get();
$tags = Tag::query()
->whereRelation('events', 'event_id', '>', 0)
// or ->whereHas('events', fn($events) => $events->where('event_id', '>', 0))
->get();
$categories = Category::query()
->whereRelation('events', 'event_id', '>', 0)
// or ->whereHas('events', fn($events) => $events->where('event_id', '>', 0))
->get();
return view('frontend.event.index', compact('events', 'tags', 'categories'));
}
You could also maybe use a query scope to put the search in the Event
model.
# Event.php
public function scopeSearch(Builder $query, array $filter = [])
{
return $query
->when(
array_key_exists('vehicle_type', $filter),
fn($query) => $query->where('vehical_type', $filter['vehicle_type'])
)
->when(
array_key_exists('tag', $filter),
fn($query) => $query->whereRelation('tags', 'tag_id', $filter['tag'])
// or fn($query) => $query->whereHas('tags', fn($tags) => $tags->where('tag_id', $filter['tag']))
)
->when(
array_key_exists('category', $filter),
fn($query) => $query->whereRelation('categories', 'category_id', $filter['category'])
// or fn($query) => $query->whereHas('categories', fn($category) => $category->where('category_id', $filter['category']))
);
}
public function index(Request $request)
{
$filter = [
'vehicle_type' => $request->vehicle_type,
'tag' => $request->tag,
'category' => $request->category,
];
$events = Event::query()
->where('status', '1')
->search($filter)
->get();
$tags = Tag::query()
->whereHas('events', fn($events) => $events->where('event_id', '>', 0))
->get();
$categories = Category::query()
->whereHas('events', fn($events) => $events->where('event_id', '>', 0))
->get();
return view('frontend.event.index', compact('events', 'tags', 'categories'));
}