In my Laravel app I have a search function, in said search function the user can search by a query string and a selection of tags.
An ordinary search query would produce a request like the following:
https://events-portal.test/api/events/search?q=search
where q is the query string.
I also have a series of tags that users can select many of, then the request looks like the following:
https://events-portal.test/api/events/search?q=search&tags[]=%7B%22slug%22:%22business-development%22%7D
However, this feels broken as when I paginate Laravel only brings the query string to the next page.
Should I really be passing the entire object to the query string?
Essentially, is there a better way to pass multiple of the same parameter to the query string instead of an object as an array?
Code
public function search(Request $request)
{
$search_term = $request->get('q');
$tags = $request->get('tags');
// Organise tags from request into usable array
$tags = collect($tags)->map(function ($item, $key) {
return [
json_decode($item)->slug,
];
})->flatten()->toArray();
// Build error message if no results are found
$error = ['error' => "No results found for '{$request->get('q')}'"];
$error['error'] = count($tags) > 0
? $error['error'] . ' with ' . count($tags) . ' tag(s) selected.'
: $error['error'];
// If there is a search term, search for events meeting search criteria
if (!empty($search_term)) {
$events = Event::search($search_term)->query(function ($query) use ($tags) {
return $query->listed()
->when(count($tags) > 0, function ($query) use ($tags) {
return $query->withTag($tags);
})
->select('id', 'title', 'header_image_url', 'location', 'start_datetime', 'finish_datetime');
})->paginate(6);
}
// If there is NO search term, load all listed events meeting tag criteria
else {
$events = Event::listed()
->withTag($tags)
->select('id', 'title', 'header_image_url', 'location', 'start_datetime', 'finish_datetime')
->orderBy('start_datetime')
->paginate(6);
}
return $events->count() ? $events : $error;
}