简体   繁体   中英

Laravel eloquent and many polymorphic joins

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM