srlabs / eloquent-sti

在Eloquent ORM中实现单表继承

v6.0.0 2022-02-09 04:46 UTC

This package is auto-updated.

Last update: 2024-09-09 10:20:44 UTC


README

本包提供了一种扩展Eloquent模型对象以支持单表继承的简单方法。灵感来源于Pallav Kaushish撰写的文章

安装

应通过composer安装此包

$ composer require srlabs/eloquent-sti

用法

在你的模型中添加 SingleTableInheritanceTrait 特性,然后指定以下配置值

  • table: 分配给基模型的数据库表名称
  • morphClass: 基Eloquent对象的完整类名
  • discriminatorColumn: 用于区分STI实体类型的数据库表中的列
  • inheritanceMap: 将鉴别列值映射到相应实体类的数组

以下是一个假设的Widget模型示例

// app/Epiphyte/Widget.php
class Widget extends Illuminate\Database\Eloquent\Model {

    /*****************************************************************************
     *  Eloquent Configuration
     *****************************************************************************/

    protected $guarded = ['id'];
    protected $fillable = ['name', 'description', 'status'];

    /*****************************************************************************
     * Single Table Inheritance Configuration
     *****************************************************************************/

    use SingleTableInheritanceTrait;
    protected $table = 'widgets';
    protected $morphClass = 'Epiphyte\Widget';
    protected $discriminatorColumn = 'status';
    protected $inheritanceMap = [
        'new' => 'Epiphyte\Entities\Widgets\NewWidget',
        'processed' => 'Epiphyte\Entities\Widgets\ProcessedWidget'
        'complete' => 'Epiphyte\Entities\Widgets\CompleteWidget'
    ];

    // ...
}

接下来,你需要创建每个子实体类。我通常将它们保存在一个Entities文件夹中,但任何命名空间位置都适用。

以下是一个假设的示例

// app/Epiphyte/Entities/Widgets/NewWidget.php
class NewWidget extends Epiphyte\Widget {

    /**
     * Limit the query scope if we define a query against the base table using this class.
     *
     * @param bool $excludeDeleted
     *
     * @return $this
     */
    public function newQuery($excludeDeleted = true)
    {
        return parent::newQuery($excludeDeleted)->where('status', '=', 'new');
    }

    // Remaining child entity methods go here...
}

每当Eloquent想要返回基模型的实例时,它将使用鉴别列的值来确定适当的实体类型,并返回该类的实例。这对于所有Eloquent操作都成立,但不会直接在数据库(即DB::table())调用中工作。

在子类中提供 newQuery() 方法允许你将实体用作传统的Eloquent访问器,它只返回其自身的实体。在这种情况下,NewWidget::all();将返回数据库中标记为'new'的所有Widget。

有关此包的任何问题都应发布在包网站上。