Symfony / Doctrine - несколько типов пользователей

Я создаю веб-сайт, на котором должно быть как минимум два типа пользователей, компания и клиент, два из них имеют одинаковую форму входа и разные формы регистрации, и они могут отправлять сообщения друг другу ...

Нормально (не думая о Doctrine) я думаю, что база данных должна выглядеть примерно так:
Пользователь (идентификатор, адрес электронной почты, пароль, facebook_id, роли)
Компания (id, user_id, name, city, ...)
Клиент (id, user_id, name, sex ...)
Сообщения (идентификатор, sender_id (user_id), Receiver_id (user_id), message, ...)
...

Итак, теперь я хочу узнать лучший и самый простой способ реализовать эти требования с помощью Доктрина и Symfony 4. Как могут выглядеть сущности?

(Примечание: я не использую FOSUserBundle)

Документация по доктрине содержит раздел по управлению различными типами наследования, который должен помочь вам начать работу. Если вы столкнетесь с какими-либо конкретными проблемами, не стесняйтесь открывать конкретный вопрос, но я боюсь, что сейчас вопрос слишком широкий, чтобы на него можно было дать осмысленный ответ.

dbrumann 13.11.2018 18:44

Да, я нахожу раздел документации доктрины «Сопоставление наследования», надеюсь, я смогу понять содержание, потому что я новичок в мире Symfony / Doctrine ..

Az.Youness 13.11.2018 18:56

Нет проблем, испытайте удачу, и если у вас возникнут проблемы, не стесняйтесь обращаться за помощью сюда. Ответить на вопросы с помощью существующих фрагментов кода и сообщений об ошибках всегда проще, чем отвечать на открытые вопросы. Это просто означает много работы, и в худшем случае это все равно будет не так полезно для вас, как документация и немного поиграться с ней. :)

dbrumann 13.11.2018 19:01
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
3
3
1 347
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Реализация этого домена:

  • Пользователь
  • Компания
  • Клиент

вы можете рассмотреть два разных подхода:

Первый подход

Этот подход использует ассоциацию. Если вы выберете этот вариант, вам следует вручную связать подходящего (компанию или клиента) с текущим пользователем в зависимости от некоторой логики. Каждый User, вероятно, должен иметь только одно из этих полей в любой момент времени. Компания или Клиент, но не то и другое одновременно.

Пользователь

/** @Entity */
class User
{
    /**
     * @ORM\column(type = "string")
     */
    protected password;

    /**
     * @ORM\column(type = "array")
     */ 
    protected roles;

    /**
     * @ORM\OneToOne(targetEntity = "Company", mappedBy = "user")
     */
    protected Company;

    /**
     * @ORM\OneToOne(targetEntity = "Client", mappedBy = "user")
     */ 
    protected Client;
}

Компания

/** @Entity */
class Company
{
    /**
     * @ORM\column(type = "string")
     */
    protected city;

    /**
     * @ORM\OneToOne(targetEntity = "User", inversedBy = "company")
     */ 
    protected user;
}

Клиент

/** @Entity */
class Client
{
    /**
     * @ORM\column(type = "string")
     */
    protected sex;

    /**
     * @ORM\OneToOne(targetEntity = "User", inversedBy = "client")
     */ 
    protected user;
}

Второй подход

Этот подход использует наследование и кажется более гибким, но имеет свои недостатки.

Пользователь

/** @MappedSuperclass */
class User
{
    /**
     * @ORM\column(type = "string")
     */
    protected password;

    /**
     * @ORM\column(type = "array")
     */ 
    protected roles;
}

Компания

/** @Entity */
class Company extends User
{
    /**
     * @Id @Column(type = "integer")
     */
    protected $id;

    /**
     * @ORM\column(type = "string")
     */
    protected city;
}

Клиент

/** @Entity */
class Client extends User
{
    /**
     * @Id @Column(type = "integer")
     */
    protected $id;

    /**
     * @ORM\column(type = "string")
     */
    protected sex;
}

У вас также есть отношение Один ко многим между Пользователь и Сообщение:

  • ОдинПользователь может иметь МногиеСообщения
  • ОдинСообщение принадлежит только ОдинПользователь

Использование Первый подход, описанного выше, нормально, но использование Второй подход приводит к проблемам как Доктрина говорит:

persistent relationships defined by a mapped superclass must be unidirectional (with an owning side only). This means that One-To-Many associations are not possible on a mapped superclass at all.

Спасибо, я выбираю первый подход (композиция), похоже, что это лучший способ реализовать мои требования, другая проблема, которую я обнаружил с подходом наследования, например, на некоторых этапах в моем приложении (регистрация должна быть разделена на два этапа .. ) Мне нужно будет обновить / изменить столбец дискриминатора пользователя, и сделать это с наследованием Doctrine невозможно / плохая практика .. проблема описана Здесь

Az.Youness 14.11.2018 23:31

это нормально на данный момент. не стесняйтесь задавать любые другие вопросы по Symfony. пожалуйста, примите && проголосуйте, если было полезно

Pmpr 14.11.2018 23:33

Другие вопросы по теме