cvsouth / entities
Joined-table inheritance for Laravel
Requires
- illuminate/database: 5.6.*|5.7.*|5.8.*
- illuminate/support: 5.6.*|5.7.*|5.8.*
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