原则继承:区分实体属性而不是表列?

时间:2018-09-13 23:06:11

标签: php symfony doctrine-orm orm

使用Doctrine2继承,我要稍加改动,以便区分器不是基于列(来自映射表),而是基于实体的属性。代码如下:

(请注意,我知道Doctrine中没有像 @DiscriminatorAttribute 那样的东西,我只是在问最终实现它的方法)

const checkboxes = [1, 2, 3];

<Form>
   checkboxes.map(id =>
    <Checkbox key={id} id={id}/>
</Form>

1 个答案:

答案 0 :(得分:1)

鉴于shopType是一个相当静态的属性(在某种意义上说,对于一个类的所有实例而言,它始终是相同的),您可以简单地将shopType定义为该属性的默认值,并使用现有列作为区分列:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="shopType", type="string")
 * @ORM\DiscriminatorMap({"local" = "LocalShop", "foreign" = "ForeignShop"})
 */
class Shop
{
    protected const TYPE_LOCAL = 'local';
    protected const TYPE_FOREIGN = 'foreign';

    // ...
}

/**
 * @Entity
 */
class LocalShop extends Shop
{
    protected $shopType = Shop::TYPE_LOCAL;
    // ...
}

/**
 * @Entity
 */
class ForeignShop extends Shop
{
    protected $shopType = Shop::TYPE_FOREIGN;
    // ...
}

Doctrine的水化器将采用您的类的新实例,并使用所有默认值实例化该实例,然后将所有从数据库中提取的信息写入映射的属性。

由于您的属性具有默认值的期望值且未映射,因此即使从数据库中获取,其正确的默认值也不会被水化过程更改并且具有期望值。

在此过程中,未调用构造函数(实体是克隆的,或者是反射的newInstanceWithoutConstructor生成的),这就是原始代码无法正常工作的原因。