Symfony — необязательное наследование с Doctrine

Мы столкнулись с проблемой наследования в Symfony 5.

Мы создали пакет UserBundle, который включает в себя простой объект User (идентификатор, адрес электронной почты, пароль): цель этого пакета — легко повторно импортировать его в наши различные проекты. .

В некоторых проектах мы хотим расширить этот объект, добавив некоторые определенные поля (телефон, адрес,...), но это не всегда так.

Вот код, который мы установили:

UserBundle › Класс пользователя:

<?php

namespace MyCompany\UserBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;

/**
* @ORM\MappedSuperclass()
*/
class User implements UserInterface
{
   /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    ...

Унаследован объект пользователя:

<?php

namespace App\Entity;

use MyCompany\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;

/**
* @ORM\Entity
* @UniqueEntity(fields={"email"})
*/
class User extends BaseUser
{
    /**
     * @ORM\Column(type="string", length=50)
     */
    private $phone;

    ...

Наследование работает нормально: проблема исходит от проектов, для которых нам достаточно User сущности бандла. =› Класс User пакета определен как Mapped superclass, чтобы иметь возможность его расширить, но Doctrine не может создать связанную таблицу, если нет класса, который наследуется от него...

Мы могли бы систематически создавать пустой класс User в src/, который наследуется от класса User пакета, но мне это не кажется супер чистым...

Я пошел на этот пост, но это, похоже, не работает: замена Doctrine Inheritance

Может ли кто-нибудь помочь нам в этой проблеме? Я полагаю, что решение должно существовать...

Заранее спасибо!


person Alexandre O    schedule 01.10.2020    source источник
comment
Требование, чтобы каждое приложение имело собственный класс User, вероятно, является лучшим подходом.   -  person Cerad    schedule 02.10.2020


Ответы (1)


Идея ниже не работает.

Как уже указывал @Cerad, лучший подход, вероятно, действительно состоит в том, чтобы определить конкретный User в каждом приложении. Это также то, что делает FOSUserBundle.


Я бы выбрал следующий подход: объявить отображаемый суперкласс абстрактным.

/**
* @ORM\MappedSuperclass()
*/
abstract class AbstractBaseUser implements UserInterface
{
   /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    ...

И реализуйте конкретный пустой дочерний класс User внутри вашего пакета.

/**
* @ORM\Entity
*/
class User extends AbstractBaseUser
{
}

Таким образом, каждое приложение может либо использовать User вашей библиотеки, либо наследовать от нее.

person simon.ro    schedule 01.10.2020
comment
Спасибо! Мы уже пытались, но когда мы делаем bin/console make:migration, Doctrine отказывается говорить, что the user table already exists, что имеет смысл, потому что у нас есть два класса User, определенные как сущности. Ответ может быть очевиден, но есть ли решение заставить Doctrine выбирать сущность или другую в соответствии с нашими проектами? - person Alexandre O; 02.10.2020
comment
@AlexandreO так верно. Конечно, я обновил свой ответ. Не углубляясь, можно было бы определить отображение формы в yaml вместо аннотаций. После этого потребитель пакета должен иметь возможность переопределить конфигурацию. - person simon.ro; 02.10.2020