I have a model Device and I need to return a property target_firmware that is eager loaded. The value of the property is determined through two related models DeviceFirmwareTarget and Asset. Device has one or none DeviceFirmwareTarget which has two columns asset_id and target_branch. Either asset_id will have a value or target_branch, but not both. Asset has a column called version.
The property target_firmware should be determined as follows. If a related DeviceFirmwareTarget exists, the value is Asset->version if DeviceFirmareTarget->asset_id is not null, otherwise it is DeviceFirmwareTarget->target_branch if its value is not null, otherwise the default value is published.
The code below will give me the correct value, but the property is not eager loaded, so the query runs for every device returned. Is there a way to eager load the property?
Models/Device.php
public function targetFirmware()
{
return $this->hasOne(DeviceFirmwareTarget::class, 'device_id');
}
public function getTargetFirmwareAttribute()
{
$targetFirmware = $this->targetFirmware()->leftJoin('binary_assets', 'device_firmware_targets.asset_id', '=', 'binary_assets.id')
->select(\DB::raw('COALESCE(binary_assets.version, device_firmware_targets.target_branch) AS target_firmware'))
->value('target_firmware');
return $targetFirmware ?? 'published';
}
DeviceController.php@index
// php debug bar shows a query for each device returned to populate the 'target_firmware" property
return Device::all();