Моделирование учетной записи пользователя со ссылкой на разные сущности

Я начинаю новый проект, который будет действовать как сервер авторизации / аутентификации и простое управление пользователями для определенного типа пользователей. Пользователь может быть HelpDeskResponsible, GroupManager, Employee, Customer и больше. Все члены этих групп смогут войти в систему с помощью одной формы в веб-интерфейсе. Каждая модель будет содержать различный набор данных, описывающих их.

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

Является ли моя концепция чрезмерной инженерией? Есть ли решения для такой проблемы? Может быть, мне не нужно несколько объектов для разных типов учетных записей?

Спасибо за любой совет.

РЕДАКТИРОВАТЬ: Различные уровни разрешений здесь не самая большая проблема — я хочу хранить различную информацию о пользователе в зависимости от роли, к которой он принадлежит. Customer будет иметь другой набор данных, чем Employee, Я уверен, что это разные модели, но я хочу сохранить возможность входа в систему с той же формой входа.

2

Решение

Я думаю, что основная проблема заключается в том, что ваша связь идет в обратном направлении: в вашем случае контекст управления пользователями должен знать о специфике других ограниченных контекстов (BC), тогда как это должно быть наоборот. В противном случае вам придется постоянно изменять свой контекст управления пользователями, так как все больше систем его используют.

Например, HelpDeskResponsible Скорее всего, роль играет в системе службы поддержки, которая живет в своем собственном БЦ (или наборе БК). Именно этот контекст должен отвечать за моделирование и сохранение специфики HelpDeskResponsible, Единственное, что должен содержать контекст управления пользователями, это то, находится ли пользователь в определенной роли и, возможно, некоторая информация, которая является общей для всех пользователей (например, имя, фамилия).

введите описание изображения здесь

Очевидно, что на приведенной выше диаграмме отсутствует антикоррупционный уровень (услуги), например. HelpDeskUserService), который живет в Help Desk BC и отвечает за абстрагирование связи с User Management BC и перевод User в HelpDeskResponsible,

1

Другие решения

Поскольку ваши дополнительные сущности расширяются User сущность с другими дополнительными данными, я бы, вероятно, использовал Наследование таблицы классов.

Наследование таблиц классов — это стратегия отображения наследования, в которой каждый
класс в иерархии отображается на несколько таблиц: свою собственную таблицу и
таблицы всех родительских классов. Таблица дочернего класса связана
к таблице родительского класса через ограничение внешнего ключа.
Доктрина 2 реализует эту стратегию с использованием дискриминатора
столбец в самой верхней таблице иерархии, потому что это
Самый простой способ добиться полиморфных запросов с помощью таблицы классов
Наследование.

Таким образом, у вас будет базовый стол User с базовыми данными (имя пользователя, пароль, адрес электронной почты и т. д.), а затем еще одна таблица для каждого дополнительного объекта, который расширяется User с дополнительными данными (например, столбец salary на столе Employee).


Определить родительский объект

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

/**
* @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
* @ORM\Table(name="user")
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="discr", type="string")
* @ORM\DiscriminatorMap({"user" = "User", "employee" = "Employee"})
*/
class User {
// your class..
}

Определить дочернюю сущность

/**
* @ORM\Entity(repositoryClass="AppBundle\Repository\EmployeeRepository")
* @ORM\Table(name="employee")
*/
class Employee extends User {

/**
* @ORM\Column(name="salary", type="float")
*/
private $salary;

public function setSalary($salary)
{
$this->salary = $salary;
return $this;
}

public function getSalary()
{
return $this->salary;
}

}

Конечно Employee класс может переопределять родительские методы (например, getRoles() если вы реализуете UserInterface в User).

Наконец (сделайте резервную копию вашей БД и) обновите вашу схему БД с помощью php bin/console doctrine:schema:update --force, Doctrine создаст новую таблицу с определенными данными и столбцом id которые относятся к относительному User,

Поэтому, когда обычный пользователь входит в систему, Symfony загрузит User сущность, а когда сотрудник входит в систему, он будет загружать Employee юридическое лицо.

0