celinederoland/eloquent-polymorphic-model

此包的最新版本(2.0.3)没有可用的许可信息。

扩展eloquent功能,将一个类层次结构的分支映射到数据库中的一个表

2.0.3 2018-10-20 14:14 UTC

This package is not auto-updated.

Last update: 2024-09-30 20:54:33 UTC


README

扩展eloquent功能,将一个类层次结构的分支映射到数据库中的一个表。

目的

如果您数据库中有一个表(比如说一个包含字段 person_idnamegenderPerson 表)并且您想将它与您的类层次结构(比如说一个父类 Person 和两个子类 Man extends PersonWoman extends Person)关联起来,那么您可以使用这个包来自动进行映射。

配置类映射

从父类检索实例

在父类中,像通常一样定义模型

class Person extends Model {

    protected $table      = 'Person';
    protected $primaryKey = 'person_id';
    
}

定义空的子类

class Man extends Person {}

class Woman extends Person {}

在父类中使用 EloquentPolymorphism\PolymorphicParent 辅助类。您必须定义数据库结果如何与您的类层次结构绑定(在我这个例子中取决于 gender 字段的值)

protected function instanceFactory($attributes) {

    if (!array_key_exists('gender', $attributes)) {
        return static::class;
    }

    switch ($attributes['gender']) {
        case self::TYPE_WOMAN:
            return Woman::class;
        case self::TYPE_MAN:
            return Man::class;
    }
    return static::class;
}

有了这个,您可以检索到男性集合和女性集合

$persons = Person::all(); //an eloquent collection, containing instances of `Man` and instances of `Woman`

从子类检索实例

现在我们必须在子类中定义约束(否则 Man::all() 也会检索到男性和女性的集合)。为此,在子类中,您必须使用 EloquentPolymorphism\PolymorphicChild 特性并定义 polymorphismScope 约束;

class Man extends Person {

    * This scope will be added to all requests to make sure not retrieving other child.
     *
     * @param Builder $query
     */
    protected function polymorphismScope(Builder $query) {
    
        $query->where('gender', 'm');
    }
}

现在,如果您编写 Man::all() 或对 Man 模型执行任何更复杂的查询,它将返回一个包含 Man 实例的集合,对应于表示男性的表条目。

可选地,您可以通过在父类或子类中添加以下代码覆盖您在 Man 类中定义的作用域的名称

protected function polymorphismScopeIdentifier() {

    return 'polymorphism_scope_identifier';
}

更新/创建模型

默认属性

强烈建议在子类中定义默认属性值。

在我们的例子中,这将非常方便地编写

$woman = new Woman(['name' => 'Sandra']); 
$woman->save();

而不必设置她的性别。

为此,您必须在子类中覆盖 setChildDefaultAttributes 方法

public function setChildDefaultAttributes() {
      
     $this->gender = 'f';
}

在保存方法调用时的验证

PolymorphicParent 特性防止对子类进行不自然的更新/创建,例如

$man = new Man();
$man->gender = 'f';
$man->save(); //returns false, entry is not saved

这是通过检查 instanceFactory 方法中定义的条件是否确实检索到 Man 的实例来完成的。您可以通过实现 checkHierarchyConstraintsBeforeSaving 方法来覆盖此行为

class Man extends Person {
  
  /**
   * @return bool
   */
  protected function checkHierarchyConstraintsBeforeSaving() {
  
      //Your logic : return true if it's correct to consider this instance as beeing a man, false otherwise
  }
}

复杂查询、关系等。

您可以使用 Eloquent 模型的所有其他功能,就像平常一样。特别是,您可以定义所需的关系和复杂查询。

贡献

在您的github账户中fork项目。初始化gitflow

git flow init
git flow feature start feature-name develop

Composer安装

sh composer.sh install

测试

docker-compose up testunit

代码

git push

从您的发布分支创建一个合并请求到develop