cvsouth / eloquent-inheritance
Laravel 的联合表继承
1.0.22
2022-02-07 23:51 UTC
Requires
- doctrine/dbal: ^2.10|^3.3
- illuminate/database: ^8.4|^9.0
- illuminate/support: ^7.0|^8.0|^9.0
README
安装
composer require cvsouth/eloquent-inheritance
php artisan migrate
用法
定义类
从 InheritableModel 继承模型而不是通常的 Model
class Animal extends InheritableModel { public $table = "animals"; protected $fillable = [ 'name', 'species', ]; public function speak() { print($this->name . ' makes a noise'); } }
class Bird extends Animal { public $table = "birds"; protected $fillable = [ 'flying', ]; public function speak() { print('AAA!'); } public function fly() { $this->flying = true; } public function land() { $this->flying = false; } public function isFlying() { return $this->flying; } }
创建迁移时添加 base_id
class CreateAnimalsTable extends Migration { public function up() { Schema::create('animals', function (Blueprint $table) { $table->bigIncrements('id'); $table->bigInteger('base_id')->unsigned(); $table->string('species', 250); $table->string('name', 250)->nullable(); }); } public function down() { Schema::drop('animals'); } }
class CreateBirdsTable extends Migration { public function up() { Schema::create('birds', function (Blueprint $table) { $table->bigIncrements('id'); $table->bigInteger('base_id')->unsigned(); $table->boolean('flying')->default(false); }); } public function down() { Schema::drop('birds'); } }
存储对象
然后您可以使用对象就像普通的 Eloquent 对象一样
$bird = new Bird ([ "species" => "Aratinga solstitialis", // Note: This attribute is inherited from Animal ]); $bird->fly(); echo "This " . strtolower($bird->species) . " is " . ($bird->isFlying() ? "" : "not ") . "flying" . '<br/>'; // This aratinga solstitialis is flying $bird->species = 'Sun Conure'; $bird->save(); $bird->land(); echo "This " . strtolower($bird->species) . " is " . ($bird->isFlying() ? "" : "not ") . "flying" . '<br/>'; // This sun conure is not flying
查询对象
同样,您可以像通常的 Eloquent 一样查询对象
$bird = Bird::where("species", "=", "Aratinga solstitialis")->first(); $bird->speak(); // AAA!
不同继承级别的主键
在继承的每个级别,对象都有一个 id。在上面的示例中,$bird 有一个动物 id 以及一个鸟 id。此外,每个模型都有一个称为 base_id 的公共 id,它在整个类层次结构中是一致的。
使用 id_as 方法获取特定继承级别的模型 id
// The model's animal id echo $bird->id_as(Animal::class); // The model's bird id echo $bird->id_as(Bird::class);
或使用 base_id 属性获取实体的基本 id
// The model's base id echo $bird->base_id
关系
关系与常规 eloquent 关系类似,但请注意,您可以引用特定的继承级别。例如
class Trainer extends InheritableModel { 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->bigIncrements('id'); $table->bigInteger('base_id')->unsigned(); $table->string('name', 250)->nullable(); $table->bigInteger('animal_id')->unsigned(); }); Schema::table('trainers', function ($table) { $table->foreign('animal_id')->references('id')->on('animals')->onDelete('cascade'); }); } public function down() { Schema::drop('trainers'); } }
$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 class_basename($trainer->animal); // Bird echo $trainer->animal->species; // Sun Conure