I have custom code where I check request params for existing and make query to database with model
public function search(Request $request)
{
$position = $request->get("position") ?? null;
$location = $request->get("location") ?? null;
$employment = $request->get("employment") ?? null;
$jobsBy = null;
$jobs = null;
if($position) {
$jobs = Job::where('title', 'LIKE', '%'.$position.'%');
if($location) {
$locations = [];
if(is_array($location)) {
foreach ($location as $name) {
$locations[] = $name;
}
} else $locations[] = $location;
$jobs = $jobs->whereMetaIn("location", $locations);
}
if($employment) {
$employments = [];
if(is_array($employment)) {
foreach ($employment as $name) {
$employments[] = $name;
}
} else $employments[] = $employment;
$jobs = $jobs->withAnyTag($employments);
}
if($jobs->get()->count()) $jobsBy = "position";
}
if($location && $jobsBy === null) {
$locations = [];
if(is_array($location)) {
foreach ($location as $name) {
$locations[] = $name;
}
} else $locations[] = $location;
$jobs = Job::whereMetaIn('location', $locations);
if($employment) {
$employments = [];
if(is_array($employment)) {
foreach ($employment as $name) {
$employments[] = $name;
}
} else $employments[] = $employment;
$jobs = $jobs->withAnyTag($employments);
}
if($jobs->get()->count()) $jobsBy = "location";
}
if($employment && $jobsBy === null) {
$employments = [];
if(is_array($employment)) {
foreach ($employment as $name) {
$employments[] = $name;
}
} else $employments[] = $employment;
$jobs = Job::withAnyTag($employments);
if($jobs->get()->count()) $jobsBy = "employment";
}
if($jobs == null || !$jobs->get()->count()) {
$jobs = Job::where("status", '<', 2);
$jobsBy = "latest";
}
if(isset($jobs) && $jobs instanceof \Illuminate\Database\Eloquent\Builder && $jobsBy != null) {
$IDS = $jobs->where('status', '<', 2)->pluck('id');
$partnerCompanyJobs = Job::with(['user' => function($user) {
$user->without('roles', 'companies')
->select('id', 'name');
}])->withCount('views')->where('type', 0)
->whereIn('id', $IDS)
->where('status', 1)
->orderBy('updated_at', 'DESC')
->get();
$companyJobs = Job::with(['user' => function($user) {
$user->without('roles', 'companies')
->select('id', 'name');
}])->withCount('views')->where('type', 1)
->where('status', 1)
->whereIn('id', $IDS)
->orderBy('updated_at', 'DESC')
->get();
$sampleJobs = Job::with(['user' => function($user) {
$user->without('roles', 'companies')
->select('id', 'name');
}])->withCount('views')->where('type', 2)
->where('status', 1)
->whereIn('id', $IDS)
->orderBy('updated_at', 'DESC')
->get();
$somonJobs = Job::withCount('views')->whereIn('type', [3,4])
->whereIn('id', $IDS)
->where('status', 1)
->orderBy('updated_at', 'DESC')
->get();
$jobs = $partnerCompanyJobs->merge($companyJobs)
->merge($sampleJobs)
->merge($somonJobs);
if(count($jobs)) {
$page = $request->page ?? 1;
$items = $jobs->forPage($page, 5);
return response()->json([
'data' => JobResource::collection($items),
'total' => count($jobs),
'jobsBy' => $jobsBy
]);
}
}
return response()->json([
'data' => [],
'total' => 0,
'jobsBy' => ""
]);
}
How can I avoid duplication of code here and create an optimal database query in my case? I have a problem processing request parameters. Because of this, much is duplicated in my code. How can I fix such a case?