staudenmeir/belongs-to-through
| Install | |
|---|---|
composer require staudenmeir/belongs-to-through |
|
| Latest Version: | v2.18 |
| PHP: | ^8.3 |
| License: | MIT |
| Last Updated: | Feb 28, 2026 |
| Links: | GitHub · Packagist |
BelongsToThrough
This inverse version of HasManyThrough allows BelongsToThrough relationships with unlimited intermediate models.
Supports Laravel 5.0+.
Installation
composer require staudenmeir/belongs-to-through:"^2.5"
Use this command if you are in PowerShell on Windows (e.g. in VS Code):
composer require staudenmeir/belongs-to-through:"^^^^2.5"
Versions
| Laravel | Package |
|---|---|
| 13.x | 2.18 |
| 12.x | 2.17 |
| 11.x | 2.16 |
| 10.x | 2.13 |
| 9.x | 2.12 |
| 8.x | 2.11 |
| 7.x | 2.10 |
| 6.x | 2.6 |
| 5.x | 2.5 |
Usage
Consider this HasManyThrough relationship:
Country → has many → User → has many → Post
class Country extends Model
{
public function posts()
{
return $this->hasManyThrough(Post::class, User::class);
}
}
Use the BelongsToThrough trait in your model to define the inverse relationship:
Post → belongs to → User → belongs to → Country
class Post extends Model
{
use \Znck\Eloquent\Traits\BelongsToThrough;
public function country(): \Znck\Eloquent\Relations\BelongsToThrough
{
return $this->belongsToThrough(Country::class, User::class);
}
}
You can also define deeper relationships:
Comment → belongs to → Post → belongs to → User → belongs to → Country
Supply an array of intermediate models as the second argument, from the related (Country) to the parent model (Comment):
class Comment extends Model
{
use \Znck\Eloquent\Traits\BelongsToThrough;
public function country(): \Znck\Eloquent\Relations\BelongsToThrough
{
return $this->belongsToThrough(Country::class, [User::class, Post::class]);
}
}
Custom Foreign Keys
You can specify custom foreign keys as the fifth argument:
class Comment extends Model
{
use \Znck\Eloquent\Traits\BelongsToThrough;
public function country(): \Znck\Eloquent\Relations\BelongsToThrough
{
return $this->belongsToThrough(
Country::class,
[User::class, Post::class],
foreignKeyLookup: [User::class => 'custom_user_id']
);
}
}
Custom Local Keys
You can specify custom local keys for the relations:
VendorCustomerAddress → belongs to → VendorCustomer in VendorCustomerAddress.vendor_customer_id
VendorCustomerAddress → belongs to → CustomerAddress in VendorCustomerAddress.address_id
You can access VendorCustomer from CustomerAddress by the following
class CustomerAddress extends Model
{
use \Znck\Eloquent\Traits\BelongsToThrough;
public function vendorCustomer(): \Znck\Eloquent\Relations\BelongsToThrough
{
return $this->belongsToThrough(
VendorCustomer::class,
VendorCustomerAddress::class,
foreignKeyLookup: [VendorCustomerAddress::class => 'id'],
localKeyLookup: [VendorCustomerAddress::class => 'address_id'],
);
}
}
Table Aliases
If your relationship path contains the same model multiple times, you can specify a table alias (Laravel 6+):
class Comment extends Model
{
use \Znck\Eloquent\Traits\BelongsToThrough;
public function grandparent(): \Znck\Eloquent\Relations\BelongsToThrough
{
return $this->belongsToThrough(
Comment::class,
Comment::class . ' as alias',
foreignKeyLookup: [Comment::class => 'parent_id']
);
}
}
Use the HasTableAlias trait in the models you are aliasing:
class Comment extends Model
{
use \Znck\Eloquent\Traits\HasTableAlias;
}
Soft Deleting
By default, soft-deleted intermediate models will be excluded from the result. Use withTrashed() to include them:
class Comment extends Model
{
use \Znck\Eloquent\Traits\BelongsToThrough;
public function country(): \Znck\Eloquent\Relations\BelongsToThrough
{
return $this->belongsToThrough(Country::class, [User::class, Post::class])
->withTrashed('users.deleted_at');
}
}
class User extends Model
{
use SoftDeletes;
}
Contributing
Please see CONTRIBUTING and CODE OF CONDUCT for details.