cvsouth/entities

此包已被废弃,不再维护。作者建议使用cvsouth/eloquent-inheritance包。

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

⚠️ 注意:此包已被https://github.com/cvsouth/eloquent-inheritance取代。

Laravel的模型继承

安装

composer require cvsouth/entities
php artisan migrate

使用

定义类

Entity扩展模型,而不是使用常规的Model

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

创建迁移时,包括entity_id并插入一个新的EntityType对象

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]);
    }
}

存储对象

然后您可以像使用常规Eloquent对象一样使用您的对象

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

echo $bird->species;
// Aratinga solstitialis

查询对象

再次,您可以像通常的Eloquent一样查询对象

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

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

继承不同层次的主键

在继承的每一级,对象都有一个ID。在上面的例子中,$bird有一个动物ID和一个鸟ID。此外,每个实体都有一个称为实体ID的共同ID,它在类层次结构中是一致的。

使用id_as方法获取特定继承级别的实体ID

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

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

或者使用entity_id属性获取实体的共同ID

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

关系

关系的工作方式与常规Eloquent关系相同,但请注意,您可以引用特定的继承级别。例如

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