staudenmeir/belongs-to-through
Add BelongsToThrough relationships to Eloquent: the inverse of HasManyThrough. Define belongs-to chains across unlimited intermediate models, with support for custom keys, table aliases, and soft deletes. Works with Laravel 5+.
Start by installing the package via Composer (composer require staudenmeir/belongs-to-through:^2.17 for Laravel 12) and adding the BelongsToThrough trait to any model needing inverse deep relationships. The most common first use case is reversing a HasManyThrough chain like Country -> Users -> Posts to allow Post to access its ultimate Country via User. Define the relationship like so:
class Post extends Model
{
use \Znck\Eloquent\Traits\BelongsToThrough;
public function country()
{
return $this->belongsToThrough(Country::class, User::class);
}
}
Then access it naturally: $post->country->name. Eager load with with('country') as usual.
belongsToThrough(Grandparent::class, [Parent::class, Child::class]).hasManyThrough in parent models with belongsToThrough in leaf models for natural navigation both ways (e.g., User → Posts → Tags ↔ Tag → Posts → User).with('user.country')) and use whereBelongsToThrough() constraints where supported.->where('status', 'active') on the relationship; apply withTrashed() for soft-deletable intermediate models.BelongsToThrough fields directly in resource forms (v2.9+), leveraging the same chain definitions.foreignKeyLookup and localKeyLookup arrays when using non-standard keys (e.g., foreignKeyLookup: [Intermediate::class => 'custom_id']).HasTableAlias trait and pass 'ModelName as alias' as the intermediate class string.withTrashed() fails on intermediate models; explicitly pass column aliases like ->withTrashed('users.deleted_at') to include soft-deleted intermediates.laravel-ide-helper (v2.15+) and enable PHPStan level 9+ with the updated generics to get reliable autocompletion for chained belongsToThrough results.How can I help you explore Laravel packages today?