I have some Laravel polymorphic models which include a User model that can have many booking calendar entries which can have many holiday entries. I can write the following SQL query to pull back the data I require but struggle with the eloquent version of the query. Perhaps it's my model relationships or my understanding of how things work in Laravel. I have some eloquent queries that do work, however, they are very inefficient, and when I investigate use many selects rather than just the one.
My SQL:
select hol.*
from booking_calendar bc
join holidays hol
on bc.booked_by_id = hol.id
where bc.model_type='App\Staff'
and bc.model_id=123
and bc.booked_by_type='App\Holiday'
The database tables:
Staff: (App\Staff)
id 123
...
booking_calendar: (App\BookingCalendar)
model_id 123
model_type App\Staff
...
booked_by_id 77
booked_by_type App\Holiday
holidays: (App\Holiday)
id 77
...
I guess the crux of my problem is that booking_calendar has 2 polymorphic relationships as it is also used for Asset bookings.
What I would like to do is $staff->holidays() or $staff->bookingCalendar->holidays.
I'd be grateful if someone could explain how to do this in a single eloquent select statement that is not raw SQL + hydrate.
I assumed the relationships according to your DB design.
Staff <=> BookingCalendar --> Polmorphic: One to many
Holiday <=> BookingCalendar --> Polmorphic: One to many
Staff Model
public function bookingCalendars(){
return $this->morphMany(App\BookingCalendar::class, 'model');
}
Holiday Model
public function bookingCalendars(){
return $this->morphMany(App\BookingCalendar::class, 'booked_by');
}
BookingCalendar Model
public function model(){
return $this->morphTo();
}
public function booked_by(){
return $this->morphTo();
}
filter
and pluck
are collection methods.
$staff = Staff::with('bookingCalendars.model')->find($id);
$filtered_bks = $staff->bookingCalendars->filter(function($bk){
return $bk->model_type == 'App\Holiday';
});
$holidays = $filtered_bks->pluck('model');
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.