2015-08-20 4 views
2

Скажут, у меня есть три модели:Laravel 5,1 отношений отношений

  • Worker
  • Департамента
  • Компания

Компания имеет много департаментов и Департамент имеет много Рабочие. Теперь, как я могу получить всех Рабочих от компании?

я могу получить все отделы с

Company::find(1)->departments() 

я могу получить все рабочие с

Department::find(1)->workers() 

Я попытался создать метод модели компании так:

public function workers() 
{ 
    return $this->departments->map(function($item, $key){ 
     return $item->workers; 
    }); 
} 

Проблема поднялась, когда я хотел назвать метод 'where()' в коллекции с тремя аргументы, и это дало мне пустую коллекцию.

Company::find(1)->workers()->where('salary', '>=', '100'); 

И это возвращает пустую коллекцию, что бы я ни делал. Я попробовал whereLoose, передал '100' как целое число. Следующие работает отлично:

Company::find(1)->workers()->where('salary', '100'); 

дает мне все рабочие, которые имеют зарплату в 100

Есть ли способ рода использовать Отношения, так что я могу получить от отношения Company->hasMany('Worker')?

ответ

1

Читайте о hasManyThrough (http://laravel.com/docs/5.1/eloquent-relationships#has-many-through). Добавить функцию в модель компании:

public function workers() 
{ 
    // hasMany Workers through Department 
    return $this->hasManyThrough('App\Models\Worker', 'App\Models\Department'); 
} 

так что теперь Вы в состоянии сделать:

$Company = Company::with('workers')->find(1); 
$Workers = $Company->workers; 



маленький бонус. получить данные через 2 модели, что-то вроде hasManyThrough + hasMany (не тестировался):

создать класс (файл в каталоге моделей):

приложение/модели/ExtendedModel.PHP

<?php 

namespace App\Models; 

use Illuminate\Database\Eloquent\Model; 

class ExtendedModel extends Model { 
    public function hasManyThrough2Models($model1, $model2, $model3, $model1Key, $model2KeyWith1, $model2Key, $model3KeyWith2) 
    { 
     $model1 = new $model1; 
     $model1Table = $model1->getTable(); 
     $model2 = new $model2; 
     $model2Table = $model2->getTable(); 
     $model3 = new $model3; 
     $model3Table = $model3->getTable(); 

     return $model1 
      ->join($model2Table, $model2Table . '.' . $model2KeyWith1, '=', $model1Table . '.' . $model1Key) 
      ->join($model3Table, $model3Table . '.' . $model3KeyWith2, '=', $model2Table . '.' . $model2Key) 
      ->select($model1Table . '.*'); 
    } 
} 

, а затем получить данные через 2 модели:

<?php namespace App\Models; 

class Company extends ExtendedModel { 

    public function worksheets() { 
     return $this->hasManyThrough2Models('App\Models\Worksheet', 'App\Models\Worker', 'App\Models\Department', 'worker_id', 'id', 'department_id', 'id'); 
    } 

теперь используют:

$Company = Company::with('worksheets')->find(1); 
$Worksheets = $Company->worksheets; 
+0

Это именно то, что я искал. Но есть ли способ пройти через 2 промежуточных модели? Предположим, у меня есть отношения Worker-> hasMany ('Worksheet') и я ищу Company-> worksheets(). –

+0

Я не уверен, что это можно сделать без необработанного SQL-запроса с объединениями. Или мы можем получить источник hasManyThrough и сделать наш собственный метод и назвать его hasManyThrough2Models. Подожди немного, я постараюсь это сделать. Я скоро отправлю отзыв. – num8er

+0

@MihkelAllorg, я обновил свой ответ, надеюсь, что это поможет. Предупреждение: не проверено, но вы можете попробовать – num8er

0

Вы можете попробовать:

$company = Company::with('departments.workers')->find(1); 

Таким образом, он будет возвращать все рабочий, кто принадлежит к этой компании под каждый отдел индивидуален. В этом случае, вы можете петли так:

@foreach($company->departments as $department) 

    {{ $department->name }} 

    @foreach($department->workers as $worker) 

     {{ $worker->name }} 

    @endforeach; 

@endforeach; 
Смежные вопросы