PHPackages                             elkadrey/eloquent-json-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. elkadrey/eloquent-json-relations

ActiveLibrary

elkadrey/eloquent-json-relations
================================

Laravel Eloquent relationships with JSON keys

1.8.0(1y ago)1416MITPHPPHP ^8.3|^8.2|^8.1

Since Oct 11Pushed 1y agoCompare

[ Source](https://github.com/elkadrey/eloquent-json-relations)[ Packagist](https://packagist.org/packages/elkadrey/eloquent-json-relations)[ Fund](https://paypal.me/JonasStaudenmeir)[ RSS](/packages/elkadrey-eloquent-json-relations/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (9)Dependencies (2)Versions (12)Used By (0)

[![CI](https://github.com/staudenmeir/eloquent-json-relations/workflows/CI/badge.svg)](https://github.com/staudenmeir/eloquent-json-relations/workflows/CI/badge.svg)[![Code Coverage](https://camo.githubusercontent.com/63055f2843dd31eaac65866bb41b524ca414d731115480b936134a69501a13aa/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f7374617564656e6d6569722f656c6f7175656e742d6a736f6e2d72656c6174696f6e732f6261646765732f636f7665726167652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/staudenmeir/eloquent-json-relations/?branch=master)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/affdb20145df375d07b0ced49f866e57ccd78fab664f3f8a483726cd38791262/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f7374617564656e6d6569722f656c6f7175656e742d6a736f6e2d72656c6174696f6e732f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/staudenmeir/eloquent-json-relations/?branch=master)[![Latest Stable Version](https://camo.githubusercontent.com/de6b1360c4b0ff505f3654bfeaf079ebe66bc969a0168897051b4a7317fa56f0/68747470733a2f2f706f7365722e707567782e6f72672f7374617564656e6d6569722f656c6f7175656e742d6a736f6e2d72656c6174696f6e732f762f737461626c65)](https://packagist.org/packages/staudenmeir/eloquent-json-relations)[![Total Downloads](https://camo.githubusercontent.com/9ca400f1055aae14587acc999452af1223a32511a3f8872e812268aa7d44ecde/68747470733a2f2f706f7365722e707567782e6f72672f7374617564656e6d6569722f656c6f7175656e742d6a736f6e2d72656c6174696f6e732f646f776e6c6f616473)](https://packagist.org/packages/staudenmeir/eloquent-json-relations)[![License](https://camo.githubusercontent.com/aee81f7c13a26f1c75183a6473141db6b850e1ecbcaf27f5de9f64262aee2271/68747470733a2f2f706f7365722e707567782e6f72672f7374617564656e6d6569722f656c6f7175656e742d6a736f6e2d72656c6174696f6e732f6c6963656e7365)](https://packagist.org/packages/staudenmeir/eloquent-json-relations)

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

[](#introduction)

This Laravel Eloquent extension adds support for JSON foreign keys to `BelongsTo`, `HasOne`, `HasMany`, `HasOneThrough`, `HasManyThrough`, `MorphTo`, `MorphOne` and `MorphMany` relationships.
It also provides [many-to-many](#many-to-many-relationships) relationships with JSON arrays.

Compatibility
-------------

[](#compatibility)

DatabaseLaravelMySQL 5.7+5.5.29+MariaDB 10.2+5.8+PostgreSQL 9.3+5.5.29+[SQLite 3.18+](https://www.sqlite.org/json1.html)5.6.35+SQL Server 2016+5.6.25+Installation
------------

[](#installation)

```
composer require "elkadrey/eloquent-json-relations:^1.1"

```

Use this command if you are in PowerShell on Windows (e.g. in VS Code):

```
composer require "elkadrey/eloquent-json-relations:^^^^1.1"

```

Usage
-----

[](#usage)

- [One-To-Many Relationships](#one-to-many-relationships)
    - [Referential Integrity](#referential-integrity)
- [Many-To-Many Relationships](#many-to-many-relationships)
    - [Array of IDs](#array-of-ids)
    - [Array of Objects](#array-of-objects)
    - [Query Performance](#query-performance)

### One-To-Many Relationships

[](#one-to-many-relationships)

In this example, `User` has a `BelongsTo` relationship with `Locale`. There is no dedicated column, but the foreign key (`locale_id`) is stored as a property in a JSON field (`users.options`):

```
class User extends Model
{
    use \Staudenmeir\EloquentJsonRelations\HasJsonRelationships;

    protected $casts = [
        'options' => 'json',
    ];

    public function locale()
    {
        return $this->belongsTo(Locale::class, 'options->locale_id');
    }
}

class Locale extends Model
{
    use \Staudenmeir\EloquentJsonRelations\HasJsonRelationships;

    public function users()
    {
        return $this->hasMany(User::class, 'options->locale_id');
    }
}
```

Remember to use the `HasJsonRelationships` trait in both the parent and the related model.

#### Referential Integrity

[](#referential-integrity)

On [MySQL](https://dev.mysql.com/doc/refman/en/create-table-foreign-keys.html), [MariaDB](https://mariadb.com/kb/en/library/foreign-keys/) and [SQL Server](https://docs.microsoft.com/en-us/sql/relational-databases/tables/specify-computed-columns-in-a-table) you can still ensure referential integrity with foreign keys on generated/computed columns.

Laravel migrations support this feature on MySQL/MariaDB:

```
Schema::create('users', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->json('options');
    $locale_id = DB::connection()->getQueryGrammar()->wrap('options->locale_id');
    $table->unsignedBigInteger('locale_id')->storedAs($locale_id);
    $table->foreign('locale_id')->references('id')->on('locales');
});
```

Laravel migrations (5.7.25+) also support this feature on SQL Server:

```
Schema::create('users', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->json('options');
    $locale_id = DB::connection()->getQueryGrammar()->wrap('options->locale_id');
    $locale_id = 'CAST('.$locale_id.' AS INT)';
    $table->computed('locale_id', $locale_id)->persisted();
    $table->foreign('locale_id')->references('id')->on('locales');
});
```

There is a [workaround](https://github.com/staudenmeir/eloquent-json-relations/tree/1.1#referential-integrity) for older versions of Laravel.

### Many-To-Many Relationships

[](#many-to-many-relationships)

The package also introduces two new relationship types: `BelongsToJson` and `HasManyJson`

On Laravel 5.6.25+, you can use them to implement many-to-many relationships with JSON arrays.

In this example, `User` has a `BelongsToMany` relationship with `Role`. There is no pivot table, but the foreign keys are stored as an array in a JSON field (`users.options`):

#### Array of IDs

[](#array-of-ids)

By default, the relationship stores pivot records as an array of IDs:

```
class User extends Model
{
    use \Staudenmeir\EloquentJsonRelations\HasJsonRelationships;

    protected $casts = [
       'options' => 'json',
    ];

    public function roles()
    {
        return $this->belongsToJson(Role::class, 'options->role_ids');
    }
}

class Role extends Model
{
    use \Staudenmeir\EloquentJsonRelations\HasJsonRelationships;

    public function users()
    {
       return $this->hasManyJson(User::class, 'options->role_ids');
    }
}
```

On the side of the `BelongsToJson` relationship, you can use `attach()`, `detach()`, `sync()` and `toggle()`:

```
$user = new User;
$user->roles()->attach([1, 2])->save(); // Now: [1, 2]

$user->roles()->detach([2])->save();    // Now: [1]

$user->roles()->sync([1, 3])->save();   // Now: [1, 3]

$user->roles()->toggle([2, 3])->save(); // Now: [1, 2]
```

#### Array of Objects

[](#array-of-objects)

You can also store pivot records as objects with additional attributes:

```
class User extends Model
{
    use \Staudenmeir\EloquentJsonRelations\HasJsonRelationships;

    protected $casts = [
       'options' => 'json',
    ];

    public function roles()
    {
        return $this->belongsToJson(Role::class, 'options->roles[]->role_id');
    }
}

class Role extends Model
{
    use \Staudenmeir\EloquentJsonRelations\HasJsonRelationships;

    public function users()
    {
       return $this->hasManyJson(User::class, 'options->roles[]->role_id');
    }
}
```

Here, `options->roles` is the path to the JSON array. `role_id` is the name of the foreign key property inside the record object:

```
$user = new User;
$user->roles()->attach([1 => ['active' => true], 2 => ['active' => false]])->save();
// Now: [{"role_id":1,"active":true},{"role_id":2,"active":false}]

$user->roles()->detach([2])->save();
// Now: [{"role_id":1,"active":true}]

$user->roles()->sync([1 => ['active' => false], 3 => ['active' => true]])->save();
// Now: [{"role_id":1,"active":false},{"role_id":3,"active":true}]

$user->roles()->toggle([2 => ['active' => true], 3])->save();
// Now: [{"role_id":1,"active":false},{"role_id":2,"active":true}]
```

**Limitations:** On SQLite and SQL Server, these relationships only work partially.

#### Query Performance

[](#query-performance)

On PostgreSQL, you can improve the query performance with `jsonb` columns and [`GIN` indexes](https://www.postgresql.org/docs/current/datatype-json.html#JSON-INDEXING).

Use this migration when the array of IDs/objects is the column itself (e.g. `users.role_ids`):

```
Schema::create('users', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->jsonb('role_ids');
    $table->index('role_ids')->algorithm('gin');
});
```

Use this migration when the array is nested inside an object (e.g. `users.options->role_ids`):

```
Schema::create('users', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->jsonb('options');
    $table->rawIndex('("options"->\'role_ids\')', 'users_options_index')->algorithm('gin'); // Laravel 7.10.3+
    //$table->index([DB::raw('("options"->\'role_ids\')')], 'users_options_index', 'gin');  // Laravel < 7.10.3
});
```

Contributing
------------

[](#contributing)

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

###  Health Score

39

—

LowBetter than 86% of packages

Maintenance46

Moderate activity, may be stable

Popularity16

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity68

Established project with proven stability

 Bus Factor1

Top contributor holds 82.3% 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 ~89 days

Recently: every ~105 days

Total

11

Last Release

415d ago

PHP version history (3 changes)1.6.4PHP ^8.1

1.5.5PHP ^7.3|^8.0

1.7.1PHP ^8.3|^8.2|^8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/60830f0fe22af89caefe0e8281a537ff84766dd939e7a8e7b436f12e85c2ffa3?d=identicon)[elkadrey](/maintainers/elkadrey)

---

Top Contributors

[![staudenmeir](https://avatars.githubusercontent.com/u/1853169?v=4)](https://github.com/staudenmeir "staudenmeir (79 commits)")[![elkadrey](https://avatars.githubusercontent.com/u/2741848?v=4)](https://github.com/elkadrey "elkadrey (11 commits)")[![mstaack](https://avatars.githubusercontent.com/u/10169509?v=4)](https://github.com/mstaack "mstaack (1 commits)")[![nikazooz](https://avatars.githubusercontent.com/u/13997617?v=4)](https://github.com/nikazooz "nikazooz (1 commits)")[![szepeviktor](https://avatars.githubusercontent.com/u/952007?v=4)](https://github.com/szepeviktor "szepeviktor (1 commits)")[![dsazup](https://avatars.githubusercontent.com/u/8631224?v=4)](https://github.com/dsazup "dsazup (1 commits)")[![ziadoz](https://avatars.githubusercontent.com/u/645637?v=4)](https://github.com/ziadoz "ziadoz (1 commits)")[![iksaku](https://avatars.githubusercontent.com/u/4632429?v=4)](https://github.com/iksaku "iksaku (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/elkadrey-eloquent-json-relations/health.svg)

```
[![Health](https://phpackages.com/badges/elkadrey-eloquent-json-relations/health.svg)](https://phpackages.com/packages/elkadrey-eloquent-json-relations)
```

###  Alternatives

[larastan/larastan

Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel

6.4k43.5M5.2k](/packages/larastan-larastan)[owen-it/laravel-auditing

Audit changes of your Eloquent models in Laravel

3.4k33.0M95](/packages/owen-it-laravel-auditing)[fumeapp/modeltyper

Generate TypeScript interfaces from Laravel Models

196277.9k](/packages/fumeapp-modeltyper)[casbin/laravel-authz

An authorization library that supports access control models like ACL, RBAC, ABAC in Laravel.

324339.9k4](/packages/casbin-laravel-authz)[pressbooks/pressbooks

Pressbooks is an open source book publishing tool built on a WordPress multisite platform. Pressbooks outputs books in multiple formats, including PDF, EPUB, web, and a variety of XML flavours, using a theming/templating system, driven by CSS.

44643.1k1](/packages/pressbooks-pressbooks)[illuminatech/balance

Provides support for Balance accounting system based on debit and credit principle

16137.4k](/packages/illuminatech-balance)

PHPackages © 2026

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