Как я могу иметь двух пользователей, которые используют одну и ту же таблицу? - PullRequest
0 голосов
/ 16 апреля 2020

У меня есть сущность Пользователь с множеством функций, созданных для него.

/**
 * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
 * @UniqueEntity("email", message="Email already in use")
 * @ORM\HasLifecycleCallbacks
 * @Table(name="users")
 */
class User implements UserInterface
{
/* variables + getter & setter */
}

Эта сущность хороша для большинства моих User. Тем не менее, некоторые из них будут иметь особую роль ROLE_TEACHER. С этой ролью мне нужно хранить множество новых переменных специально для них.

Если я создаю новую сущность Teacher, doctrine создает новую таблицу с данными каждого пользователя + данные учителя.

/**
 * @ORM\Entity(repositoryClass="App\Repository\TeacherRepository")
 * @Table(name="teachers")
 */
class Teacher extends User
{
    /**
     * @ORM\Column(type="string", length=64, nullable=true)
     */
    protected $test;

    public function __construct()
    {
        parent::__construct();
    }
}

Я хочу, чтобы Учитель и Пользователь совместно использовали таблицу users, а в таблице teachers сохранялись только дополнительные данные. Как мне этого добиться?

1 Ответ

1 голос
/ 17 апреля 2020

Это скорее проблема проектирования системы, чем проблема реализации. Как сказал @Gary, вы можете использовать Inheritance Mapping , которая может иметь Проблемы с производительностью , я бы скорее предложил переосмыслить вашу схему и использовать методы нормализации базы данных, чтобы разбить ваши данные в более управляемые сущности.

Вы можете иметь сущность пользователя:

/**
 * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
 * @UniqueEntity("email", message="Email already in use")
 * @ORM\HasLifecycleCallbacks
 * @Table(name="users")
 */
class User implements UserInterface
{
    /* variables + getter & setter */
    /**
    * One user has many attibute data. This is the inverse side.
    * @OneToMany(targetEntity="UserData", mappedBy="data")
    */
    private $data;
}

С другой сущностью UserData с отношением OneToMany:

/**
 * @ORM\Entity(repositoryClass="App\Repository\UserDataRepository")
 * @Table(name="user_data")
 */
class UserData
{
    /* variables + getter & setter */
    @ORM\Id()
    private $id;

    /**
    * Many features have one product. This is the owning side.
    * @ManyToOne(targetEntity="User", inversedBy="data")
    * @JoinColumn(name="user_id", referencedColumnName="id")
    */
    private $user;

    /** 
    * @ORM\Column(type="string") 
    */
    private $attribute;

    /*
    * @ORM\Column(name="value", type="object")
    */
    private $value;
}

Теперь вы можете иметь список пользователей атрибуты, не требующие указания c структуры для каждой роли. Он масштабируемый и произвольный.

Вы также можете определить ту же связь с объектами TeacherData, StudentData или UserProfile с внешними ключами и ветвить логи приложения c в соответствии с ролями. Ключ состоит в том, чтобы разбить данные на отдельные домены и хранить общие данные в одной таблице. Загружайте связанные данные, запрашивая связанные объекты, это повышает удобочитаемость и упрощает разбивку сложной структуры на управляемую кодовую базу.

...