PHPackages                             mannikj/laravel-sti - 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. mannikj/laravel-sti

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

mannikj/laravel-sti
===================

A single table inheritance trait for you eloquent models

v5.0.3(1y ago)66.6k11MITPHPPHP ^8.0CI failing

Since Jun 3Pushed 1y ago1 watchersCompare

[ Source](https://github.com/MannikJ/laravel-sti)[ Packagist](https://packagist.org/packages/mannikj/laravel-sti)[ Docs](https://github.com/mannikj/laravel-sti)[ RSS](/packages/mannikj-laravel-sti/feed)WikiDiscussions master Synced 3w ago

READMEChangelog (10)Dependencies (4)Versions (35)Used By (1)

A single table inheritance trait for Eloquent
=============================================

[](#a-single-table-inheritance-trait-for-eloquent)

[![Latest Version on Packagist](https://camo.githubusercontent.com/81e56f00489666c27386a9c567f40e25c9f7648a765615ab1d3a235481b5d72c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d616e6e696b6a2f6c61726176656c2d7374692e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/mannikj/laravel-sti)[![Build Status](https://camo.githubusercontent.com/b90d1dfa1d65532fad39011f71db053894e9b0b2806e1e40e95eeb4c0605cdf1/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f6d616e6e696b6a2f6c61726176656c2d7374692f6d61737465722e7376673f7374796c653d666c61742d737175617265)](https://travis-ci.org/mannikj/laravel-sti)[![Total Downloads](https://camo.githubusercontent.com/2670980bb206ce8bcdb19eb5ff961b163ed89c430a0bcd7208811aefd57a9cd3/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6d616e6e696b6a2f6c61726176656c2d7374692e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/mannikj/laravel-sti)

This package provides a trait that makes your eloquent models capable of single table inheritance. If configured properly, queries will automatically return instances of the correct model subclasses according to the type column.

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

[](#installation)

You can install the package via composer:

```
composer require mannikj/laravel-sti
```

Basic Usage
-----------

[](#basic-usage)

### Migration

[](#migration)

The table you want to apply single table inheritance to must incorporate a type column.

The package's service provider adds a macro to the Blueprint class to create the type column.

```
Schema::table('table', function (Blueprint $table) {
    $table->sti()->nullable();
});
```

### Using the Trait

[](#using-the-trait)

You need to add the `SingleTableInheritance` trait to your root model class. The sub models need to extend the root class.

```
use MannikJ\Laravel\SingleTableInheritance\Traits\SingleTableInheritance;

class Root extends Model {
    use SingleTableInheritance;
}

class Sub1 extends Root {}

class Sub2 extends Root {}
```

For the default usage no other configuration is needed. The trait will use the class name of the subclasses as the type, scope the queries accordingly and return the correct instances of subclasses automatically.

#### Nested

[](#nested)

If you have multiple levels of subclasses and you want the automatic scoping to include all sub types, you need to define the direct subclasses for each model by setting the `stiSubClasses` array property:

```
use MannikJ\Laravel\SingleTableInheritance\Traits\SingleTableInheritance;

class Root extends Model {
    use SingleTableInheritance;

    protected $stiSubClasses = [
        Sub1::class, Sub2::class
    ]
}

class Sub1 extends Root {
    protected $stiSubClasses = [
        Sub3::class
    ]
}

class Sub2 extends Root {}

class Sub3 extends Sub1 {}
```

### Advanced Usage

[](#advanced-usage)

#### Types without fully-qualified classnames

[](#types-without-fully-qualified-classnames)

Without any tweaking, the trait assumes that there is a type column storing the fully qualified names of the subclasses. However, if you want to use some other string not directly referencing a class as the type identifier, you can do so by overwriting two functions of the trait:

```
    public static function resolveTypeViaClass()
    {
        $type = (new \ReflectionClass(static::class))->getShortName();
        $type = str_replace('Component', '', $type);
        $type = strtolower($type);

        return static::isSubclass()
            ? $type
            : null;
    }

    public function resolveModelClassViaAttributes($attributes = [])
    {
        $type = $this->resolveTypeViaAttributes($attributes);

        // Map class to type
        $mapping = [
            'motif' => MotifComponent::class,
            'text' => TextComponent::class,
        ];

        return $type
            ? data_get($mapping, $type)
            : static::class;
    }
```

#### Resolving the type based on a related model

[](#resolving-the-type-based-on-a-related-model)

You can also tweak the behavior even further so that the type will be determined based on a related model:

```
class Animal extends Model
{
    use SingleTableInheritance;

    protected $fillable = ['name'];

    public function resolveTypeViaAttributes($attributes = [])
    {
        if ($category = Category::find(Arr::get($attributes, 'category_id'))) {
            return $category->config_class;
        };
    }

    public function applyTypeCharacteristics($type)
    {
        $this->category_id = Category::where('config_class', $type)->first()?->id;
    }

    public function scopeSti(Builder $builder)
    {
        $builder->whereHas('category', function ($query) use ($builder) {
            $query->where('categories.config_class', static::class);
        });
    }

    public function category()
    {
        return $this->belongsTo(Category::class, 'category_id')->withDefault([
            'config_class' => static::class
        ]);
    }
}
```

### Testing

[](#testing)

```
composer test
```

### Changelog

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information about what has changed recently.

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

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

### Security

[](#security)

If you discover any security related issues, please email  instead of using the issue tracker.

Credits
-------

[](#credits)

- [Jannik Malken](https://github.com/mannikj)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

Laravel Package Boilerplate
---------------------------

[](#laravel-package-boilerplate)

This package was generated using the [Laravel Package Boilerplate](https://laravelpackageboilerplate.com).

###  Health Score

45

—

FairBetter than 91% of packages

Maintenance46

Moderate activity, may be stable

Popularity29

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity76

Established project with proven stability

 Bus Factor1

Top contributor holds 95.7% 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 ~70 days

Recently: every ~239 days

Total

32

Last Release

408d ago

Major Versions

v1.7.0 → v2.0.02020-04-06

v2.1.0 → v3.0.02021-06-02

v3.0.3 → v4.0.02022-02-03

v4.2.1 → v5.0.02023-01-31

PHP version history (4 changes)v1.0.0PHP ^7.2

v2.1.0PHP ^7.2.5

v3.0.1PHP ^7.2.5|^8.0

v4.2.0PHP ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/0395cab7b59845b773eac21ecdb506c06642c60ab1e10c27d0331a9d7ca249b4?d=identicon)[MannikJ](/maintainers/MannikJ)

---

Top Contributors

[![MannikJ](https://avatars.githubusercontent.com/u/1841856?v=4)](https://github.com/MannikJ "MannikJ (45 commits)")[![Tankonyako](https://avatars.githubusercontent.com/u/48120579?v=4)](https://github.com/Tankonyako "Tankonyako (2 commits)")

---

Tags

laravelmodeleloquenttraitmannikjsingle-table-inheritancestilaravel-sti

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/mannikj-laravel-sti/health.svg)

```
[![Health](https://phpackages.com/badges/mannikj-laravel-sti/health.svg)](https://phpackages.com/packages/mannikj-laravel-sti)
```

###  Alternatives

[esensi/model

The base model traits of Esensi

20067.0k1](/packages/esensi-model)[greabock/tentacles

Da epic tentacles for Eloquent

3634.5k](/packages/greabock-tentacles)

PHPackages © 2026

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