hi i wrote this code and it works just fine but i think its not the best way to do it!
i want to get all the jobs for 1 company.
each company can have many addresses and each address can have many jobs
here is my code:
$company = Company::find($id)->with('addresses.jobDetails.job')->first();
$jobs = [];
foreach ($company->addresses as $address) {
foreach ($address->jobDetails as $detail) {
array_push($jobs, [
'id' => $detail->job->id,
'title' => $detail->job->title,
'country' => $detail->job->country,
'city' => $detail->job->city,
'type' => $detail->job->type,
'work_types' => JobType::where('job_id',$detail->job->id)->pluck('title'),
'income' => $detail->income,
]);
}
}
return $jobs;
can anyone help me to change this to better code please
thank you in advance
You do the opposite and start with JobDetails
$jobDetails = JobDetail::whereHas('address.company', function($companyQuery) use($id) {
$companyQuery->where('id', $id);
})->whereHas('jobs', function($jobQuery) {
$jobQuery->where('is_active', 1);
})->with('jobs')->get();
foreach ($jobDetails as $detail) {
array_push($jobs, [
'id' => $detail->job->id,
'title' => $detail->job->title,
'country' => $detail->job->country,
'city' => $detail->job->city,
'type' => $detail->job->type,
'work_types' => JobType::where('job_id',$detail->job->id)->pluck('title'),
'income' => $detail->income,
]);
}
return $jobs;
EDIT:
In your query
Company::find($id)->with('addresses.jobDetails.job')->first();
You run 4 queries with eager loading. one for each model. You can check in the result that you got that all the data is present in the variable $company
.
The example I gave you it runs only two queries, the first one (job_details) will use joins to filter the Job results by the id
of the companies table (you can make it faster by using the field company_id
in the addresses table)
The second one is for the jobs relation using eager loading.