Normally when querying a given model with its relationships, Laravel allows you to use dot notation to reach nested ones.
Relationship definitions
For example imagine we have 3 models - Configuration
, EngineType
and CarBrand
. For the sake of simplicity the linkage goes as follows:
Configuration::class
belongs to anEngineType::class
EngineType::class
belongs to aCarBrand::class
Within Configuration.php
model:
public function engineType(): BelongsTo
{
return $this->belongsTo(EngineType::class, 'engine_type_id', 'id');
}
Within EngineType.php
model:
public function carBrand(): BelongsTo
{
return $this->belongsTo(CarBrand::class, 'car_brand_id', 'id');
}
Finally leave CarBrand.php
model with no relationship (even inverse ones).
Fetching and obtaining nested attribute
Now imagine you fetch all of the configurations and you want to know how many unique car brands were assigned to all of these configurations.
Define an array with relationship that represents the nested structure. Keep in mind that the structure of our database is fully normalised to avoid any unnecessary redundancy. In other words CarBrand
is not directly connected with Configuration
.
$relationships = [
'engineType.carBrand',
];
Pulling everything together can be done like:
$configurations = Configuration::with($relationships)->get();
Now lets use the pluck()
method to extract primary keys of all fetched car brands.
$carBrandIds = $configurations->pluck('engineType.carBrand.id')->unique();
This is it. We specify the column name under relationship we're interested in. In this particular case we want ID
of a CarBrand
. The pluck()
will return a collection. As multiple configurations can have the same CarBrand
(through EngineType
) we call unique()
to remove duplicated IDs
(it works as distinct
on the SQL query statement level).