Single Table Inheritance for Laravel's Eloquent ORM.
Via Composer
$ composer require jonnypickett/eloquent-sti
After updating composer, add the ServiceProvider to the providers array in config/app.php
JonnyPickett\EloquentSTI\ServiceProvider::class,
Use the SingleTableInheritance trait in any Eloquent model to take advantage of Single Table Inheritance in Laravel with the model's subclasses.
A table taking advantage of Single Table Inheritance needs to store subclass names. By default, this package uses a field named subclass_name
, so add this field, or the field name you choose (configuration is shown later), to your table.
Schema::table('animals', function(Blueprint $table)
{
$table->string('subclass_name');
}
Once this field is added to your database table, you will need to add the SingleTableInheritance
trait, make sure to specify the table property, and add the subclass name field to the $fillable
array all on the parent model definition
class Animal extends Model
{
use SingleTableInheritance;
protected $table = 'animals';
protected $fillable = [
'subclass_name',
...
];
protected $noise = '';
/**
* @return string
*/
public function speak()
{
return $this->noise;
}
}
Now just extend the parent model with any child models
class Dog extends Animal
{
protected $noise = 'ruff';
}
class Cat extends Animal
{
protected $noise = 'meow';
}
That's it. Now the entries in your table, animals
for our example, will always be returned as an instance of a specific subclass. When retrieving a collection, the collection will be a collection of various subclass instances.
By default, the subclass names will be stored in a field named subclass_name
. This can be changed project wide by updating your .env file
ELOQUENT_STI_SUBCLASS_FIELD=your_subclass_field_name_here
or publishing and updating the package configuration file in app/config/eloquent-sti.php
php artisan vendor:publish --provider="JonnyPickett\EloquentSTI\ServiceProvider"
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Subclass Field
|--------------------------------------------------------------------------
|
| Subclass class names will be stored and retrieved from this field.
| This can be overridden in specific classes by setting the
| protected property $subclassFiled to a different value
| in the class definition.
|
*/
'subclass_field' => env('ELOQUENT_STI_SUBCLASS_FIELD', 'your_subclass_field_name_here'),
];
or can be changed on a per model basis by adding a $subclassField
property to your parent model
class Animal extends Model
{
protected $subclassField = 'your_subclass_field_name_here'
}
Inspiration for this package came way back when I came across this Laravel.io forum post by Shawn McCool
The MIT License (MIT). Please see License File for more information.