Reputation: 989
Let's say I have three models:
- Worker
- Department
- Company
A Company has many Departments and a Department has many Workers. Now how can I get all the Workers from the company?
I can get all the departments with
Company::find(1)->departments()
I can get all the Workers with
Department::find(1)->workers()
I tried creating a method to the model Company like that:
public function workers()
{
return $this->departments->map(function($item, $key){
return $item->workers;
});
}
The issue rose, when I wanted to call a the method 'where()'
on the collection with three arguments and it gave me an empty collection.
Company::find(1)->workers()->where('salary', '>=', '100');
And that returns an empty collection whatever I do. I tried whereLoose, passed '100' as an integer. The following works fine:
Company::find(1)->workers()->where('salary', '100');
Gives me all the workers, who have a salary of 100.
Is there a way to kind of use the Relationships so I can get the Relationship from Company->hasMany('Worker')
?
Upvotes: 2
Views: 1321
Reputation: 19372
Read about hasManyThrough (http://laravel.com/docs/5.1/eloquent-relationships#has-many-through). Add function to Your Company model:
public function workers()
{
// hasMany Workers through Department
return $this->hasManyThrough('App\Models\Worker', 'App\Models\Department');
}
so now You're able to do:
$Company = Company::with('workers')->find(1);
$Workers = $Company->workers;
a little bonus. to get data through 2 models, something like hasManyThrough+hasMany (not tested):
create class (file in models directory):
app/Models/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 . '.*');
}
}
and then get data through 2 models:
<?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');
}
now use:
$Company = Company::with('worksheets')->find(1);
$Worksheets = $Company->worksheets;
Upvotes: 1
Reputation: 146191
You may try:
$company = Company::with('departments.workers')->find(1);
So, it'll return all the workers who belongs to that company under each department individually. In this case, you may loop like this:
@foreach($company->departments as $department)
{{ $department->name }}
@foreach($department->workers as $worker)
{{ $worker->name }}
@endforeach;
@endforeach;
Upvotes: 0