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 to the parent model, and add the subclass name field to its $fillable
array
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
php artisan vendor:publish --provider="JonnyPickett\EloquentSTI\ServiceProvider"
// app/config/eloquent-sti.php
<?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 $subclassNameField
property to your parent model
class Animal extends Model
{
protected $subclassFieldName = 'your_subclass_field_name_here'
}
The MIT License (MIT). Please see License File for more information.