Laravel Красноречивое соединение трех таблиц — имеет много сквозных

#eloquent #laravel-5.2

#красноречивый #laravel-5

Вопрос:

Привет, у меня есть три таблицы

организация

  id | name
 1  | org1
 2  | org2
  

Сайт

 id | name  | organisation_id
1  | site1 | 1
2  | site2 | 1
3  | site3 | 2
  

Обслуживание

 id | name     | site_id
1  | service1 | 1
2  | service2 | 1
3  | service2 | 2
  

Здесь я хочу получить все услуги организации (скажем, 1).
Я могу получить все сайты организации, подобные этому, но как мне получить услуги:

 $sites = Site::whereHas('organisation', function ($query) {
    $query->where('id', 1);
})->get();
  

Модель

Организационная модель

 public function sites() {
    return $this->hasMany('AppSite');
}
  

siteModel

 public function organisation(){
    return $this->belongsTo('AppOrganisation');
}

public function services() {
     return $this->hasMany('AppService');
} 
  

ServiceModel

 public function site(){
     return $this->belongsTo('AppSite');
}
  

Ответ №1:

Вы можете получить подобные отношения с «имеет много сквозных»:

Организация модели:

 public function services()
{
    return $this->hasManyThrough(Service::class, Site::class, 'organisation_id', 'site_id', 'id');
}
  

Чтобы получить:

 $services = Organisation::find(1)->services;
  

Или вы можете получить все сервисы с вложенными whereHas:

 $services = Service::whereHas('site.organisation', function ($query) {
    $query->where('organisation.id', 1);
})->get();
  

Ответ №2:

Вы можете получить таким образом :

 Site::with('organisation')
          ->select('id', 'name')
          ->with(['services' => function ($q) {
                   return $q->select('id', 'name');
            }])
           ->where('organisation_id', 1)
           ->get();
  

Ответ №3:

Это может быть достигнуто без каких-либо проблем с вложенной загрузкой

 $organization=Organization::with('sites','sites.services')->where(['id'=>1])->first();
foreach($organization->sites as $site)
{
    foreach($site->services as $service)
    {
        print_r($service->name);
    }
}