I have the following Laravel controller that searches through two models - Manufacturer and SearchTerm (which contains models of manufacturers, synonyms of models as well as common misspellings) using four different conditions: the first two for exact matches and the last two for partial matches.
I don't have a lot of experience with programming logic like this, and while it does thankfully work, it also seems to run very slow on my local server (2-3 seconds returning results from tables that are currently less than a hundred rows).
Controller
class SearchController extends Controller
{
public function index(Manufacturer $manufacturer) {
if (request("search")) {
$exact_terms = SearchTerm::with("manufacturer")->where('term', request("search"))->get();
if($exact_terms->isNotEmpty()) {
echo "Exact search term match!";
$results = $exact_terms;
foreach ($results as $result) {
$slug = $result->manufacturer->slug;
}
return redirect()->action([ManufacturerController::class, 'index'], ["manufacturer" => $slug]);
}
$exact_make = Manufacturer::where('slug', request("search"))->get();
if($exact_make->isNotEmpty()) {
echo "Exact manufacturer match!";
$results = $exact_make;
foreach ($results as $result) {
$slug = $result->slug;
}
return redirect()->action([ManufacturerController::class, 'index'], ["manufacturer" => $slug]);
}
$search_terms = SearchTerm::with("manufacturer")->where('term', "like", '%' . request("search") . '%')->get()->unique("manufacturers");
if($search_terms->isNotEmpty()) {
echo "Search term match!";
foreach ($search_terms as $search_term) {
$search_term = $search_term->manufacturer;
}
$results = collect()->add($search_term); // Needed to always return a collection to the view, even if made up of one object
}
$search_make = Manufacturer::where('slug', 'like', '%' . request("search") . '%')->get();
if($search_make->isNotEmpty()) {
echo "Manufacturer match!";
$results = $search_make;
}
$results = isset($results) ? $results : collect();
}
return view("search", [
"manufacturer" => $manufacturer,
"results" => $results,
]);
}
}
View
@if(!$results->isEmpty())
<h1 class="my-5"> {{ $results->count() }} {{ $results->count() == 1 ? "result" : "results" }} found for <i>{{ request("search") }}</i></h1>
@foreach ($results as $result)
<img src="{{ asset("/images/badges/".$result->slug.".svg")}}" class="search-result-badge" alt="...">
<h2>{{$result->name}}</h2>
@endforeach
@else
<p><h1>Sorry! We couldn't find any results for <i>"{{ request("search") }}"</i>.</h1></p>
<br>
@endif
foreach ($results as $result) { $slug = $result->manufacturer->slug; }
...is the intention to keep overwriting the$slug
variable in a loop and only preserve the final value? This technique is repeated two more times in your code. Please explain. And$results
keeps getting overwritten. Lots of red flags on this question to be honest. I'm leaning toward "Not Working As Intended". \$\endgroup\$