Наследование доктрины: атрибут «Дискриминатор от сущности», а не столбец таблицы? - PullRequest
0 голосов
/ 14 сентября 2018

Используя наследование Doctrine2, я хочу внести небольшие изменения, чтобы дискриминатор основывался не на столбце (из сопоставленной таблицы), а на атрибуте сущности.Код будет выглядеть так:

(ps я знаю, что в Doctrine нет ничего похожего на @ DiscriminatorAttribute , я просто спрашиваю о возможном обходном пути для «реализации»)

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

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

    protected $shopType;
    // ...
}

/**
 * @Entity
 */
class LocalShop extends Shop
{
    public function __construct()
    {
        $this->shopType=Shop::TYPE_LOCAL;
    }
    // ...
}
/**
 * @Entity
 */
class ForeignShop extends Shop
{
    public function __construct()
    {
        $this->shopType=Shop::TYPE_FOREIGN;
    }
    // ...
}

1 Ответ

0 голосов
/ 16 сентября 2018

Учитывая тот факт, что 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 ) Reflection, поэтому исходный код не работал.

...