PHPackages                             znck/belongs-to-through - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. znck/belongs-to-through

Abandoned → [staudenmeir/belongs-to-through](/?search=staudenmeir%2Fbelongs-to-through)Library[Database &amp; ORM](/categories/database)

znck/belongs-to-through
=======================

Laravel Eloquent BelongsToThrough relationships

v2.11.2(4y ago)1.3k226.8k—0%962MITPHPPHP ^7.3|^8.0CI passing

Since Jun 6Pushed 2mo ago18 watchersCompare

[ Source](https://github.com/znck/belongs-to-through)[ Packagist](https://packagist.org/packages/znck/belongs-to-through)[ Fund](https://paypal.me/JonasStaudenmeir)[ RSS](/packages/znck-belongs-to-through/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (3)Versions (30)Used By (2)

BelongsToThrough
================

[](#belongstothrough)

[![CI](https://github.com/staudenmeir/belongs-to-through/actions/workflows/ci.yml/badge.svg)](https://github.com/staudenmeir/belongs-to-through/actions/workflows/ci.yml?query=branch%3Amain)[![Code Coverage](https://camo.githubusercontent.com/97a504717b5c9b25e506e70d1851526b1df19b4da8b52fd8587b7f8d18f60c22/68747470733a2f2f636f6465636f762e696f2f67682f7374617564656e6d6569722f62656c6f6e67732d746f2d7468726f7567682f67726170682f62616467652e7376673f746f6b656e3d5a344b73635646574945)](https://codecov.io/gh/staudenmeir/belongs-to-through)[![PHPStan](https://camo.githubusercontent.com/2b1732baa25914ee5ccbeaf42980d671de29700b49e0639e1edc8e66181f6905/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6c6576656c25323031302d627269676874677265656e2e7376673f7374796c653d666c6174)](https://github.com/staudenmeir/belongs-to-through/actions/workflows/static-analysis.yml?query=branch%3Amain)[![Latest Stable Version](https://camo.githubusercontent.com/32821d56709029a38f120362073f84aaabb6767b67a53febd750700b7cfbbc25/68747470733a2f2f706f7365722e707567782e6f72672f7374617564656e6d6569722f62656c6f6e67732d746f2d7468726f7567682f762f737461626c65)](https://packagist.org/packages/staudenmeir/belongs-to-through)[![Total Downloads](https://camo.githubusercontent.com/eb354b75cce9173bf74f98c6f76a9cdb0351f2e879d0a87b39ed79134dff39c6/68747470733a2f2f706f7365722e707567782e6f72672f7374617564656e6d6569722f62656c6f6e67732d746f2d7468726f7567682f646f776e6c6f616473)](https://packagist.org/packages/staudenmeir/belongs-to-through/stats)[![License](https://camo.githubusercontent.com/4ac69109763879758117d403c239af0018390e5fb4f831421b77eab609a39f0e/68747470733a2f2f706f7365722e707567782e6f72672f7374617564656e6d6569722f62656c6f6e67732d746f2d7468726f7567682f6c6963656e7365)](https://github.com/staudenmeir/belongs-to-through/blob/main/LICENSE)

This inverse version of `HasManyThrough` allows `BelongsToThrough` relationships with unlimited intermediate models.

Supports Laravel 5.0+.

Installation
------------

[](#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
--------

[](#versions)

LaravelPackage13.x2.1812.x2.1711.x2.1610.x2.139.x2.128.x2.117.x2.106.x2.65.x2.5Usage
-----

[](#usage)

- [Custom Foreign Keys](#custom-foreign-keys)
- [Custom Local Keys](#custom-local-keys)
- [Table Aliases](#table-aliases)
- [Soft Deleting](#soft-deleting)

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

[](#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

[](#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

[](#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

[](#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
------------

[](#contributing)

Please see [CONTRIBUTING](.github/CONTRIBUTING.md) and [CODE OF CONDUCT](.github/CODE_OF_CONDUCT.md) for details.

Credits
-------

[](#credits)

- [Rahul Kadyan](https://github.com/znck)
- [Danny Weeks](https://github.com/dannyweeks)
- [All Contributors](../../contributors)

###  Health Score

59

—

FairBetter than 99% of packages

Maintenance56

Moderate activity, may be stable

Popularity56

Moderate usage in the ecosystem

Community31

Small or concentrated contributor base

Maturity79

Established project with proven stability

 Bus Factor1

Top contributor holds 63.8% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~81 days

Recently: every ~69 days

Total

29

Last Release

1733d ago

Major Versions

v1.0.1 → v2.0-alpha2015-10-23

PHP version history (7 changes)v2.4PHP &gt;=5.6

v2.6PHP ^7.2

v2.10PHP ^7.2.5

v2.11PHP ^7.3

v2.11.1PHP ^7.3|^8.0

2.10.x-devPHP ^7.2.5|^8.0

2.9.x-devPHP ^7.2|^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/79c0b664c035ee2af1f8988190a505d9fd559649b56711d31670f6717e3ec441?d=identicon)[znck](/maintainers/znck)

---

Top Contributors

[![staudenmeir](https://avatars.githubusercontent.com/u/1853169?v=4)](https://github.com/staudenmeir "staudenmeir (127 commits)")[![znck](https://avatars.githubusercontent.com/u/2596484?v=4)](https://github.com/znck "znck (51 commits)")[![dannyweeks](https://avatars.githubusercontent.com/u/4365775?v=4)](https://github.com/dannyweeks "dannyweeks (10 commits)")[![SanderMuller](https://avatars.githubusercontent.com/u/9074391?v=4)](https://github.com/SanderMuller "SanderMuller (2 commits)")[![dennislindsey](https://avatars.githubusercontent.com/u/7014018?v=4)](https://github.com/dennislindsey "dennislindsey (2 commits)")[![axlon](https://avatars.githubusercontent.com/u/3661474?v=4)](https://github.com/axlon "axlon (2 commits)")[![muhammedkamel](https://avatars.githubusercontent.com/u/13101778?v=4)](https://github.com/muhammedkamel "muhammedkamel (1 commits)")[![daniel-de-wit](https://avatars.githubusercontent.com/u/3015394?v=4)](https://github.com/daniel-de-wit "daniel-de-wit (1 commits)")[![andreshg112](https://avatars.githubusercontent.com/u/15859884?v=4)](https://github.com/andreshg112 "andreshg112 (1 commits)")[![szepeviktor](https://avatars.githubusercontent.com/u/952007?v=4)](https://github.com/szepeviktor "szepeviktor (1 commits)")[![wnateg](https://avatars.githubusercontent.com/u/7966535?v=4)](https://github.com/wnateg "wnateg (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/znck-belongs-to-through/health.svg)

```
[![Health](https://phpackages.com/badges/znck-belongs-to-through/health.svg)](https://phpackages.com/packages/znck-belongs-to-through)
```

###  Alternatives

[owen-it/laravel-auditing

Audit changes of your Eloquent models in Laravel

3.4k33.0M95](/packages/owen-it-laravel-auditing)[staudenmeir/eloquent-json-relations

Laravel Eloquent relationships with JSON keys

1.1k5.8M24](/packages/staudenmeir-eloquent-json-relations)[bavix/laravel-wallet

It's easy to work with a virtual wallet.

1.3k1.1M11](/packages/bavix-laravel-wallet)[dragon-code/migrate-db

Easy data transfer from one database to another

15717.4k](/packages/dragon-code-migrate-db)[gearbox-solutions/eloquent-filemaker

A package for getting FileMaker records as Eloquent models in Laravel

6454.8k2](/packages/gearbox-solutions-eloquent-filemaker)[cybercog/laravel-ownership

Laravel Ownership simplify management of Eloquent model's owner.

9126.6k3](/packages/cybercog-laravel-ownership)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
