Certainly! In Eloquent, you can define relationships across multiple levels by chaining the relationship methods together. However, to directly access a country from a city, you can define an accessor on the City model that retrieves the country through the state. Here's how you can set it up:
First, define the relationships in your models:
// City model
class City extends Model
{
public function state()
{
return $this->belongsTo(State::class);
}
// Define an accessor to get the country directly
public function getCountryAttribute()
{
return $this->state->country;
}
}
// State model
class State extends Model
{
public function country()
{
return $this->belongsTo(Country::class);
}
public function cities()
{
return $this->hasMany(City::class);
}
}
// Country model
class Country extends Model
{
public function states()
{
return $this->hasMany(State::class);
}
}
With these relationships set up, you can now access the country of a city directly by using the country accessor:
$city = City::with('state.country')->find($cityId);
$country = $city->country; // This will use the accessor we defined
By using the with('state.country') method, you're eager loading the state and country relationships, which is more efficient than lazy loading them later.
Remember that the getCountryAttribute method is an accessor, and by default, Laravel will make it available as a property ($city->country) rather than a method. If you want to use it as a method, you can simply call it like so:
$country = $city->getCountryAttribute();
This approach allows you to efficiently retrieve the country associated with a city without having to write a custom query builder logic each time you need it.