Помощь со стратегией базы данных для предоставления ролей пользователям в конкретных экземплярах модели
У меня есть приложение ruby, запущенное с декларативной авторизацией, и я сделал роли:
admin (администратор приложения) org_admin (администратор организации) org_colab (коллаборатор организации) org_visitor (посетитель организации)
Пользователь может has_many Организации и может быть администратором или коллаборатором.
Я связываю их, используя таблицу Affiliation
Какова лучшая стратегия, чтобы решить это много-много ролей?
Чтобы добавить дополнительный атрибут в таблицу Affiliation? как: Affiliation (: user_id: integer,: organization_id: integer,: affiliation_type: integer)
и тип принадлежности может быть 0 для org_admin и 1 для org_colab и 2 для org_visitor?
Я предполагаю, что должен быть лучший способ назначить роли определенной организации...
2 ответа
Это классическая модель User-Group-Role. Это троичные отношения. User-Group - это многие ко многим; так же как и групповая роль. Вам понадобится пять таблиц, чтобы захватить все это.
Вы начнете с таблицы пользователей. У него будет первичный ключ (конечно). То же самое с группой и ролью.
У вас будет таблица UserGroup, расположенная между таблицами User и Group на вашей диаграмме E/R. UserGroup будет иметь два столбца: user_id и group_id. Первичным ключом будет комбинация (user_id, group_id). Столбец user_id будет иметь отношение внешнего ключа к первичному ключу таблицы User. То же самое для столбца group_id и таблицы Group.
Там будет аналогичная договоренность с группой и ролью. У каждого будет первичный ключ. Таблица GroupRole будет находиться между двумя в вашей диаграмме E/R. Повторите приведенное выше словосочетание, и вы получите его.
Я бы создал диаграмму E/R, чтобы показать вам, но я занят другими вещами. Я надеюсь, что этого достаточно для вас. Если нет, возможно, я добавлю это позже.
Таким образом, у пользователей нет ролей; Группы делают. Вы добавляете пользователя в группу, и этот пользователь получает все полномочия, которыми обладает группа. Таким образом, вы можете добавить определенную роль (например, права администратора для группы администраторов) для определенной группы. Тогда каждый, кто будет добавлен в эту группу, получит эти разрешения.
Я на самом деле реализовать что-то похожее на мой проект. Чтобы уточнить, правильно ли я вас понимаю, у вашего пользователя может быть роль во всем контексте приложения, а также определенная роль в контексте организации, которая может не зависеть друг от друга.
Прагматичным решением может быть реализация двух разных наборов ролей. Давайте подумаем о следующей конструкции: у вас есть модель пользователя (имеющая информацию для всего приложения), модель организации (которая определяет организацию и, возможно, может принадлежать пользователю) и модель сотрудничества, которая определяет отношения между пользователь и организация.
В этом случае было бы лучше хранить роли в пользовательской модели (которые выполняют всю работу приложения) и сохранять специфичные для организации роли в совместной модели.
Я использовал строковое хранилище ролей в моделях в сочетании с Райаном Бейтсом cancan-gem - его легко и быстро использовать и он размещает логику ролей в определенном месте.
Это может не сработать для тысяч различных ролей, групп и прочего, в этом случае вам следует внедрить хранилище ролей в дополнительную модель (с полиморфным отношением к пользователям и сотрудникам).
С наилучшими пожеланиями - Флориан
edit: чтобы сделать эту реализацию доступной для поиска ActiveRecord, вы можете использовать функцию 'serialize' для поля: role, как описано в ActiveRecord::Base.