** 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'));
}
CodePudding user response:
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'));
}
CodePudding user response:
You can use whereRelation
for getting instead of using whereHas.
$customQuery->whereRelation('tags', 'tag_id', $id)
Using this structure you can shortan your code and optimize.
there is other relationship query method introduced in newer version check here
CodePudding user response:
// Get event according to filters
$events = Event::where('status', '1')
->when($request->get('vehicle_type'), function ($query, $vehicleType) {
$query->where('vehical_type', '=', $vehicleType);
})
->when($request->get('tag'), function ($query, $tagId) {
$query->whereHas('tags', function ($query) use ($tagId) {
$query->where('tag_id', $tagId);
});
})
->when($request->get('category'), function ($query, $categoryId) {
$query->whereHas('categories', function ($query) use ($categoryId) {
$query->where('category_id', $categoryId);
});
})
->get();
You can use the when
method for these types of conditions. You can view the documentation here.