PHPackages                             reedware/laravel-composite-relations - 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. reedware/laravel-composite-relations

ActiveLibrary[Database &amp; ORM](/categories/database)

reedware/laravel-composite-relations
====================================

Adds the ability define composite eloquent relations.

v5.0.0(11mo ago)17131.3k↑23.1%6[2 issues](https://github.com/tylernathanreed/laravel-composite-relations/issues)MITPHPPHP ^8.2CI passing

Since Aug 14Pushed 11mo ago1 watchersCompare

[ Source](https://github.com/tylernathanreed/laravel-composite-relations)[ Packagist](https://packagist.org/packages/reedware/laravel-composite-relations)[ RSS](/packages/reedware-laravel-composite-relations/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (10)Versions (12)Used By (0)

Laravel Composite Relations
===========================

[](#laravel-composite-relations)

[![Laravel Version](https://camo.githubusercontent.com/9e1643675487e14c111a75a4914b12e5d36bd1c42de0f642c2558906eba9b417/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d31312e7825324631322e782d626c7565)](https://laravel.com/)[![Tests](https://github.com/tylernathanreed/laravel-composite-relations/actions/workflows/tests.yml/badge.svg)](https://github.com/tylernathanreed/laravel-composite-relations/actions/workflows/tests.yml)[![Lint](https://github.com/tylernathanreed/laravel-composite-relations/actions/workflows/coding-standards.yml/badge.svg)](https://github.com/tylernathanreed/laravel-composite-relations/actions/workflows/coding-standards.yml)[![Static Analysis](https://github.com/tylernathanreed/laravel-composite-relations/actions/workflows/static-analysis.yml/badge.svg)](https://github.com/tylernathanreed/laravel-composite-relations/actions/workflows/static-analysis.yml)[![Total Downloads](https://camo.githubusercontent.com/f740b1faba94e495fc99ba7f19760ab6530a1883903c5318e2c34e98e8173ffc/68747470733a2f2f706f7365722e707567782e6f72672f72656564776172652f6c61726176656c2d636f6d706f736974652d72656c6174696f6e732f646f776e6c6f616473)](//packagist.org/packages/reedware/laravel-composite-relations)

This package adds the ability to have multiple foreign keys in a relation.

Introduction
------------

[](#introduction)

Eloquent does not natively support using composite keys in relationships. While single key relationships are typically preferred, there are times where they are unfortunately needed, and there's good way around it. This package offers a solution where you can use composite keys, and everything still feels like it's Eloquent.

This package will allow you to define the following composite relations:

- Belongs To
- Has One
- Has Many

All composite relations support eager loading and existence queries (e.g. "where has").

There currently is no intention to add support for additional relations, as these should be enough for the vast majority of use cases.

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

[](#installation)

#### Using Composer

[](#using-composer)

```
composer require reedware/laravel-composite-relations

```

#### Versioning

[](#versioning)

This package is maintained with the latest version of Laravel in mind, but support follows Laravel's [Support Policy](https://laravel.com/docs/master/releases#support-policy).

PackageLaravelPHP5.x11.x - 12.x8.2 - 8.4+4.x10.x - 11.x8.1 - 8.3+3.x8.x - 10.x7.2 - 8.0+2.x6.x - 8.x7.2 - 8.0+1.x5.5 - 5.87.1 - 7.3+#### Code Changes

[](#code-changes)

This package does not use a service provider or facade, but rather a trait. On your base model instance, you'll want to include the following:

```
use Illuminate\Database\Eloquent\Model as Eloquent;
use Reedware\LaravelCompositeRelations\HasCompositeRelations;

abstract class Model extends Eloquent
{
    use HasCompositeRelations;
}
```

Usage
-----

[](#usage)

### 1. Defining Relations

[](#1-defining-relations)

#### Composite Belongs To

[](#composite-belongs-to)

Imagine you were defining a *non-composite* belongs to relation:

```
public function myRelation()
{
    return $this->belongsTo(MyRelated::class, 'my_column_on_this_table', 'my_column_on_the_other_table');
}
```

Since composite relations use multiple keys, you'll simply define the keys as an array:

```
public function myCompositeRelation()
{
    return $this->compositeBelongsTo(MyRelated::class, ['my_first_key', 'my_second_key'], ['their_first_key', 'their_second_key']);
}
```

#### Composite Has One

[](#composite-has-one)

This follows the same structure as the composite belongs to relation:

```
public function myCompositeRelation()
{
    return $this->compositeHasOne(MyRelated::class, ['their_first_key', 'their_second_key'], ['my_first_key', 'my_second_key']);
}
```

#### Composite Has Many

[](#composite-has-many)

The pattern continues:

```
public function myCompositeRelation()
{
    return $this->compositeHasMany(MyRelated::class, ['foreign_1', 'foreign_2'], ['local_1', 'local_2']);
}
```

### 2. Omitting Foreign and Local Keys

[](#2-omitting-foreign-and-local-keys)

With non-composite relationships, you aren't actually required to provide the foreign and local key, assuming you follow a certain convention. This functionality is also available for composite relations, but must be defined differently. Here's how:

```
class Task extends Models
{
    /**
     * The primary keys for the model.
     *
     * @var array
     */
    protected $primaryKeys = ['vendor_id', 'vendor_name'];

    public function importSummary()
    {
        return $this->compositeHasOne(TaskImportSummary::class);
    }
}

class TaskImportSummary extends Models
{
    public function task()
    {
        return $this->compositeBelongsTo(TaskImportSummary::class);
    }
}
```

### 3. Joining through Composite Relations

[](#3-joining-through-composite-relations)

This package is compatible with [reedware/laravel-relation-joins](https://github.com/tylernathanreed/laravel-relation-joins), meaning you can join through composite relations just like anything else:

```
$task->joinRelation('importSummary', function($join) {
    $join->where('task_import_summaries.name', 'like', '%Relation joins are cool!%');
});
```

You must separately include [reedware/laravel-relation-joins](https://github.com/tylernathanreed/laravel-relation-joins) for this to work.

### 4. Using composite `and` glue

[](#4-using-composite-and-glue)

The default glue between composite keys is `'or'`. Meaning your query will be like:

```
where (("foreign_1" = ? or "foreign_2" = ?) or ("foreign_1" = ? or "foreign_2" = ?))
```

You can change that by passing `'and'` for the glue parameter:

```
public function myCompositeBelongsToRelation()
{
    return $this->compositeBelongsTo(MyRelated::class, ['local_1', 'local_2'], ['foreign_1', 'foreign_2'], null, 'and');
}

public function myCompositeHasOneRelation()
{
    return $this->compositeHasOne(MyRelated::class, ['foreign_1', 'foreign_2'], ['local_1', 'local_2'], 'and');
}

public function myCompositeHasManyRelation()
{
    return $this->compositeHasMany(MyRelated::class, ['foreign_1', 'foreign_2'], ['local_1', 'local_2'], 'and');
}
```

Giving this result :

```
where (("foreign_1" = ? and "foreign_2" = ?) or ("foreign_1" = ? and "foreign_2" = ?))
```

###  Health Score

49

—

FairBetter than 95% of packages

Maintenance50

Moderate activity, may be stable

Popularity43

Moderate usage in the ecosystem

Community12

Small or concentrated contributor base

Maturity74

Established project with proven stability

 Bus Factor1

Top contributor holds 98.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 ~177 days

Recently: every ~364 days

Total

11

Last Release

333d ago

Major Versions

v1.1.0 → v2.0.12020-08-31

v2.0.4 → v3.0.02023-04-01

v3.0.1 → v4.0.02024-03-22

v4.0.0 → v5.0.02025-06-19

PHP version history (5 changes)v1.0.0PHP ^7.1.3

v2.0.1PHP ^7.2

v2.0.4PHP ^7.2|^8.0

v4.0.0PHP ^8.1

v5.0.0PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/6bfd8171901449cf1e05fa5db261a2f424abca5e26818ce54b95442de0661754?d=identicon)[tylernathanreed](/maintainers/tylernathanreed)

---

Top Contributors

[![tylernathanreed](https://avatars.githubusercontent.com/u/6486381?v=4)](https://github.com/tylernathanreed "tylernathanreed (82 commits)")[![SwiTool](https://avatars.githubusercontent.com/u/8834915?v=4)](https://github.com/SwiTool "SwiTool (1 commits)")

---

Tags

eloquentlaravelphplaraveleloquentcompositerelation

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/reedware-laravel-composite-relations/health.svg)

```
[![Health](https://phpackages.com/badges/reedware-laravel-composite-relations/health.svg)](https://phpackages.com/packages/reedware-laravel-composite-relations)
```

###  Alternatives

[cviebrock/eloquent-sluggable

Easy creation of slugs for your Eloquent models in Laravel

4.0k13.6M253](/packages/cviebrock-eloquent-sluggable)[tucker-eric/eloquentfilter

An Eloquent way to filter Eloquent Models

1.8k4.8M26](/packages/tucker-eric-eloquentfilter)[watson/validating

Eloquent model validating trait.

9723.3M47](/packages/watson-validating)[reedware/laravel-relation-joins

Adds the ability to join on a relationship by name.

2121.2M13](/packages/reedware-laravel-relation-joins)[cybercog/laravel-love

Make Laravel Eloquent models reactable with any type of emotions in a minutes!

1.2k302.7k1](/packages/cybercog-laravel-love)[cviebrock/eloquent-taggable

Easy ability to tag your Eloquent models in Laravel.

567694.8k3](/packages/cviebrock-eloquent-taggable)

PHPackages © 2026

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