cvsouth/entities

This package is abandoned and no longer maintained. The author suggests using the cvsouth/eloquent-inheritance package instead.

Joined-table inheritance for Laravel

5.8.2 2019-08-01 18:10 UTC

This package is auto-updated.

Last update: 2019-11-18 09:35:05 UTC


README

⚠️ NOTICE: This package has been superceded by https://github.com/cvsouth/eloquent-inheritance.

Model Inheritance for Laravel

Installation

composer require cvsouth/entities
php artisan migrate

Usage

Defining classes

Extend your models from Entity instead of the usual Model:

class Animal extends Entity
{
    public $table = "animals";
    protected $fillable =
    [
        'name',
        'species',
    ];
}
class Bird extends Animal
{
    public $table = "birds";
    protected $fillable =
    [
        'flying',
    ];
}

When creating your migrations, include entity_id and insert a new EntityType object:

class CreateAnimalsTable extends Migration
{
    public function up()
    {
        Schema::create('animals', function (Blueprint $table)
        {
            $table->increments('id');
            $table->integer('entity_id')->unsigned();
            $table->string('species', 250);
            $table->string('name', 250)->nullable();
        });
        
        $entity_type = new EntityType(["entity_class" => Animal::class]); $entity_type->save();
    }

    public function down()
    {
        Schema::drop('animals');
                
        $entity_type = EntityType::where("entity_class", Animal::class)->first(); if($entity_type) EntityType::destroy([$entity_type->id]);
    }
}
class CreateBirdsTable extends Migration
{
    public function up()
    {
        Schema::create('birds', function (Blueprint $table)
        {
            $table->increments('id');
            $table->integer('entity_id')->unsigned();
            $table->boolean('flying');
        });
        
        $entity_type = new EntityType(["entity_class" => Bird::class]); $entity_type->save();
    }

    public function down()
    {
        Schema::drop('birds');
        
        $entity_type = EntityType::where("entity_class", Bird::class)->first(); if($entity_type) EntityType::destroy([$entity_type->id]);
    }
}

Storing objects

You can then use your objects just like normal Eloquent objects:

$bird = new Bird
([
   "species" => "Aratinga solstitialis", // Note: This attribute is inherited from Animal
   "flying" => true,
]);
$bird->save();

echo $bird->species;
// Aratinga solstitialis

Querying objects

Again, you can query the object just like usual for Eloquent:

$bird = Bird::where("species", "=", "Aratinga solstitialis")->first();

echo "This " . strtolower($bird->species) . " can " . ($bird->flying ? "" : "not ") . "fly";
// This aratinga solstitialis can fly 

Primary keys at different levels of inheritance

At each level of inheritance the object has an ID. In the example above, the $bird has an Animal ID as well as a Bird ID. In addition to this each entity has a common ID called Entity ID which is consistent throughout it's class hierarchy.

Use the id_as method to get the id for an entity at a specific level of inheritance:

// The entity's Animal ID
echo $bird->id_as(Animal::class);

// The entity's Bird ID
echo $bird->id_as(Bird::class);

Or use the entity_id property to get the entities common ID:

// The entity's common ID
echo $bird->entity_id

Relationships

Relationships work like regular eloquent relationships but bear in mind that you can reference specific levels of inheritance. For example:

class Trainer extends Entity
{
    public $table = "trainers";
    protected $fillable =
    [
        'name',
        'animal_id',
    ];
    
    public function animal()
    {
        return $this->belongsTo(Animal::class);
    }
}
class CreateTrainersTable extends Migration
{
    public function up()
    {
        Schema::create('trainers', function (Blueprint $table)
        {
            $table->increments('id');
            $table->integer('entity_id')->unsigned();
            $table->string('name', 250)->nullable();
            $table->integer('animal_id')->unsigned();
        });
        
        Schema::table('trainers', function ($table)
        {
            $table->foreign('animal_id')->references('id')->on('animals')->onDelete('cascade');
        });
        
        $entity_type = new EntityType(["entity_class" => Trainer::class]); $entity_type->save();
    }

    public function down()
    {
        Schema::drop('trainers');
                
        $entity_type = EntityType::where("entity_class", Trainer::class)->first(); if($entity_type) EntityType::destroy([$entity_type->id]);
    }
}
$bird = Bird::where("species", "=", "Aratinga solstitialis")->first();
$trainer = new Trainer
([
    "name" => "Trainer 1",
    "animal_id" => $bird->id_as(Animal::class), // Reference the bird's Animal ID
]);
$trainer->save();

echo gettype($trainer->animal); // Bird
echo $trainer->animal->species; // Aratinga solstitialis