Symfony - Optional inheritance with Doctrine

Viewed 119

We encounter an issue with inheritance on Symfony 5.

We created a UserBundle bundle which includes a simple User entity (id, email, password): the purpose of this bundle is to be able to easily reimport it into our various projects.

In some projets, we want to extend this entity to add some specific fields (phone, address, ...), but that's not always the case.

Here is the code we had set up:

UserBundle > User class:

<?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;

    ...

User entity inherited:

<?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;

    ...

The inheritance works fine: the problem comes from projects for which the User entity of the bundle is sufficient for us. => The User class of the bundle is defined as Mapped superclass in order to be able to extend it but Doctrine can't create an associated table if there is no class which inherits from it...

We could systematically create an empty User class in src/ which inherits from the User class of the bundle, but that doesn't seem super clean to me...

I went on this post but that doesn't seem to work: Doctrine Inheritance replacement

Could anyone help us on this problem? I imagine that a solution must exist...

Thank you in advance!

1 Answers

The idea below does not work.

As @Cerad already pointed out, the best approach probably really is to define the concrete User in each app. Thats also what FOSUserBundle does.


I'd go with the following approach: Declare the mapped superclass abstract.

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

    ...

And implement a concrete empty child class User inside your bundle.

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

That way each app can either use the User of your library or inherit from it.

Related