简体   繁体   中英

Eager loading nested relationships only if main relationship exists

I am trying to load a nested realtionship from a model that can have or not a "main" relationship.

I have 3 models: Building, Address and City.

I have a Building model that optionally can have an Address relationship.

If the Address relationship exists it always have a City relationship itself.

My "list buildings" controller function looks as follow:

$buildingList = Building::with(['address','type'])->get();

The problem is this way the City nested relationship isn't loaded, so I did try the following:

$buildingList = Building::with(['address.city','type'])->get();

This way I get an error for every Building that hasn't an Address related model.

Is there an elegant way to solve this?

You can get the city in the Building Model (don't forget to create the relation in the Address Model)

public function address()
{
    return $this->hasOne(Address:class)->with('city');
}

And then your first query should work and load the city.

$buildingList = Building::with(['address','type'])->get();

To display the city name:

{{ $building->address->city->name }}

More addressing the cause of the issue:

You are most likely using something like this:

{{ $building->address->city->name }}

This will cause the issue you describe. Php will error out because it cannot find the variable you are looking for.

Simplest solution would be:

{{ $building->address->city->name ?? 'No address data' }}

Now the value 'No address data' will be shown if the address is not found. You can also leave it an empty string if that floats your boat.

Now you can just load it with the code:

$buildingList = Building::with(['address.city','type'])->get();

You can read more about the?? also known as 'Null coalescing operator' here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM