Я создаю веб-сайт, на котором должно быть как минимум два типа пользователей, компания и клиент, два из них имеют одинаковую форму входа и разные формы регистрации, и они могут отправлять сообщения друг другу ...
Нормально (не думая о 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)
Да, я нахожу раздел документации доктрины «Сопоставление наследования», надеюсь, я смогу понять содержание, потому что я новичок в мире Symfony / Doctrine ..
Нет проблем, испытайте удачу, и если у вас возникнут проблемы, не стесняйтесь обращаться за помощью сюда. Ответить на вопросы с помощью существующих фрагментов кода и сообщений об ошибках всегда проще, чем отвечать на открытые вопросы. Это просто означает много работы, и в худшем случае это все равно будет не так полезно для вас, как документация и немного поиграться с ней. :)




Реализация этого домена:
вы можете рассмотреть два разных подхода:
Этот подход использует ассоциацию. Если вы выберете этот вариант, вам следует вручную связать подходящего (компанию или клиента) с текущим пользователем в зависимости от некоторой логики. Каждый 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 невозможно / плохая практика .. проблема описана Здесь
это нормально на данный момент. не стесняйтесь задавать любые другие вопросы по Symfony. пожалуйста, примите && проголосуйте, если было полезно
Документация по доктрине содержит раздел по управлению различными типами наследования, который должен помочь вам начать работу. Если вы столкнетесь с какими-либо конкретными проблемами, не стесняйтесь открывать конкретный вопрос, но я боюсь, что сейчас вопрос слишком широкий, чтобы на него можно было дать осмысленный ответ.