Hey everyone.
I've encountered an issue, and I can't get my head around it, so I am seeking some help.
First, a bit of info.
I have 3 tables: schedules, aircraft_types and aircraft.
Schedules and aircraft types are in a manyToMany relationship. Each schedule can have as many aircraft types, and each aircraft type can belong to as many schedules as required. Aircraft belong to an aircraft type - so, a many to one relationship.
Aircraft table contains aircraft_type_id
And there is a schedule_aircrafttypes table containing aircraft_type_id and schedule_id
Here is the relevant code:
...
//Schedule.php model
public function aircraftTypes() {
return $this->belongsToMany(AircraftType::class, 'schedule_aircrafttypes');
}
...
...
//AircraftType.php model
public function aircraft() {
return $this->hasMany(Aircraft::class);
}
public function schedules() {
return $this->belongsToMany(Schedule::class, 'schedule_aircrafttypes', 'aircraft_type_id');
}
}
...
//Aircraft.php model
public function type() {
return $this->belongsTo(AircraftType::class, 'aircraft_type_id');
}
In a way, a single aircraft can belong to as many schedules through its aircraft_type.
What I'm trying to achieve is to get all the schedules which have aircraft which satisfy a few conditions. Here is my current code, which works, but I'd like to improve on it, and actually get the correct result by a query/Eloquent instead of going through the "partially prepared" results and taking out the ones that do not meet the conditions.
Current code:
//Schedule.php model
public function getAvailableAircraft() {
$ids = [];
$pilotRankOrder = Auth::user()->rank->rank_order;
$types = $this->aircraftTypes()->whereHas('minrank', function ($query) use ($pilotRankOrder) {
$query->where('rank_order', '<=', $pilotRankOrder);
})->get();
foreach($types as $type) {
$ids[] = $type->id;
}
$a = Aircraft::where('location_id', $this->departure_id)->where('booked', false)->whereIn('aircraft_type_id', $ids)->with('type')->get();
return $a;
}
and inside my view:
@foreach($schedules as $schedule)
<?php if ($schedule->getAvailableAircraft()->count() == 0) continue; ?>
$schedules is defined by $schedules = Schedule::getAllBasedOnSettings();
public static function getAllBasedOnSettings($paginate = false) {
$schedules = self::getBasedOnSettings()->with('departure', 'arrival','airline');
if($paginate)
return $schedules->paginate(50);
return $schedules->get();
}
public static function getBasedOnSettings() {
$schedules = self::select();
if(Setting::get('LIMIT_SCHEDULES_BY_DAYS')) {
$schedules = $schedules->where(date('l'), true);
}
if(Setting::get('LIMIT_SCHEDULES_BY_RANK')) {
$pilotRankOrder = Auth::user()->rank->rank_order;
$schedules = $schedules->whereHas('minrank', function ($query) use ($pilotRankOrder) {
$query->where('rank_order', '<=', $pilotRankOrder);
});
}
if(Setting::get('LIMIT_SCHEDULES_BY_LAST_LOCATION')) {
$schedules = $schedules->where('departure_id', '=', Auth::user()->location_id);
}
return $schedules;
}
Question ultimately is what is the best way to optimize the code, so I don't do n*numberOfSchedules queries extra in the view, but rather get the proper query result in the first place.
I've tried a few things but didn't get far.
Sorry if I'm too confusing. I'd be happy to clarify, as English is not my first language. :)
Thanks a bunch!