I have the following structure:
'buildings' have many 'blocks' which have many 'units' which have many 'tenants'
I need to get a list of all tenants that live in a building.
Laravel provides hasMany and hasManyThrough commands that help you get collections of models which have direct relationship or are related through a single intermediate table but what if you want to get related elements of two, three, or any levels deep?
What is the proper way to achieve this using Laravel/Eloquent?
To find all the tenants in a given building, the easiest method would be to use JOIN
clauses.
I have assumed all of your relationships are hasMany
inversed by belongsTo
.
$tenants = Tenant::select('tenants.*')
->join('units', 'units.id', '=', 'tenant.unit_id')
->join('blocks', 'blocks.id', '=', 'units.block_id')
->join('buildings', 'buildings.id', '=', 'blocks.building_id')
->where('buildings.id', 123)
->get();
If this is something you'll use more than once, then I'd suggest creating a query scope on your Tenant
model.
class Tenant extends Eloquent
{
// ...
public function scopeInBuilding($query, $buildingId)
{
return $query->select('tenants.*')
->join('units', 'units.id', '=', 'tenant.unit_id')
->join('blocks', 'blocks.id', '=', 'units.block_id')
->join('buildings', 'buildings.id', '=', 'blocks.building_id')
->where('buildings.id', $buildingId);
}
// ...
}
And you can use it as follows:
$tenants = Tenant::inBuilding(123)->get();