Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Jam0r's avatar
Level 8

Eloquent resource conditional relationship query

How can I solve/improve this issue.

I have 3 models - Service, Landlord, Tenancy.

All 3 have the following attributes - charge, letting_fee, re_letting_fee - with the them overwriting their respective parent value.

For example, if a charge on a service is set to 10%, when setting the charge to 5% on the tenancy I want it to overwrite what is set on it's related landlord and service.

This is setup and works fine.

I use the following method to get the service charge on the Tenancy model

public function getServiceCharge()
{
if ($this->charge) {
return $this->charge;
}

if ($this->landlord->charge) {
return $this->landlord->charge;
}

return $this->service->charge;
}

In my TenancyResource I have the above formatted as follows

[
'charge' => [
'percent' => $this->getServiceCharge()
]
]

So when returning a TenancyResource instance i'm automatically adding 2 new queries onto the initial Tenancy query and this isn't a problem for a single resource.

However if I use the TenancyResource for anything else it can be troublesome and add additional queries when i'm not even wanting to display these values.

I know you can do conditional relationships within a resource but this won't work.

The only page I that display this service charge information is on the Detail.vue page

Any ideas?

0 likes
2 replies
frankincredible's avatar

If you're only using this method on Detail.vue, and presumably this is only showing the details for a single Tenancy, your fear of loading the landlord() and service() relationship for more than one resource isn't really an issue...

But for the sake of argument, lets say you were listing out all Tenancy's, and with this list, you wanted to show service_charge for each one....

I think you'd probably want to do something like this:

return TenancyResource::collection(Tenancy::with(['landlord', 'service'])->get());

This would mean that landlord and service would be eager-loaded once (each), rather than for each individual $tenancy in the collection.

There's really no way of knowing, in that case, whether or not the relationships will be needed unless you knew for charge that every Tenancy in the collection had its own non-0, non-null charge field.

But at least this is only 2 extra queries, instead of 2 extra queries for every single item in the collection.

Please or to participate in this conversation.