Аутентификация нескольких моделей с помощью Authlogic - PullRequest
1 голос
/ 17 февраля 2010

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

Я склоняюсь к отдельным таблицам для учеников, администраторов школ и деловых контактов, но с помощью Authlogic у меня есть таблица Users с информацией для аутентификации (все должны войти в систему).

Вопрос в том, как лучше связать эту единственную таблицу аутентификации с отдельными профилями. Кажется, что для отношения один-к-одному требуется одна таблица (например, пользователи <-> студенты или пользователи <-> Business_contacts). Я хочу иметь что-то вроде отношения «один к одному из следующих» (Пользователи <-> Студенты или Business_contacts). Есть ли хороший способ сделать это с помощью таблицы соединений или другой конструкции?

В качестве альтернативы, я мог бы объединить общую информацию в таблице Users и создать столбец «profile» в XML для поддержки уникальной информации. Я думал, что хранение всего в чистых столбцах БД упростит выбор / вставку.

Мысли, идеи?

Ответы [ 2 ]

5 голосов
/ 17 февраля 2010

деловые контакты ссылаются на предприятия, школьные администраторы и ученики ссылаются на школы.

Это означает, что у вас разные роли пользователей, а не разные пользователи.

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

Это означает, что разные роли имеют разные данные и поведение, что приводит к разным классам OO .

Вопрос в том, как лучше связать эту единственную таблицу аутентификации с отдельными профилями. Я хочу иметь что-то вроде " один к одному из следующих " (Пользователи <-> Студенты или Business_contacts). Есть ли хороший способ сделать это с помощью таблицы соединений или другой конструкции?

Самая простая модель, которую я могу придумать , если следующее:

  • User (имя пользователя, электронная почта, пароль, имена и другие общие данные для каждого пользователя )
  • Participant, аннотация. (имеет отношение к одному пользователю - определяет роль участника, поведение и его общие данные). Должен предоставить интерфейс для участников.
  • Student (наследуется от Участника, добавляет свое поведение и данные)
  • SchoolAdministrator (наследуется от участника)
  • и т. Д.

В объектно-ориентированном мире (не в РСУБД) это имеет простое преимущество: полиморфизм . Имея пользователя, вам не нужно точно знать, кто он. Вы просто делаете такие вещи:

user.participant.can_manage_stuff?
user.participant.order_book(harry_potter)

И будут выполняться соответствующие действия, которые будут реализованы в Student, SchoolAdministrator или другом классе, унаследованном от Participant.
Другое дело, что очень легко добавлять новые роли для системы. Просто наследуйте от Participant и реализуйте его интерфейс.

Теперь, когда объектно-ориентированное проектирование завершено, давайте взглянем на хранилище данных . Я предполагаю, что вы используете RDBMS.

Так что теперь у вас есть 2 типа ссылок:

  1. Один к одному связь между User и Participant.
  2. Обобщение (наследование) между Participant и Student, SchoolAdministrator.

Реализация 1st так же проста, как наличие ассоциации has_one и / или belongs_to для следующей таблицы (через столбец participant_id):

Пользователи: id | имя пользователя | электронная почта | пароль | и т. д. | member_id (не ноль) FK_TO_participant table |

Так что вы можете легко реализовать это.

Теперь 2-я ссылка может быть реализована в СУБД в количестве различных значений .

Но, к счастью или к сожалению ActiveRecord поддерживает только одну опцию , чтобы сделать это. И это иерархия для таблицы стратегия отображения, которая использует дискриминатор столбец для различения типа (хранится в столбце type по соглашению).

Таким образом, у вас будет вторая таблица, которая выглядит следующим образом:

perticipants: id | тип | student_card_number (null) | administrator_number (null) | и т.д.

В этой таблице будут все столбцы для всех возможных участников. Это самая простая и легкая реализация иерархии в БД. Но не самый оптимальный с некоторых точек зрения. Как я уже говорил с ActiveRecords, в любом случае доступен только один вариант.

Таким образом, в результате этого проекта вы получите 2 таблицы базы данных (пользователи, участники) и как минимум 3 класса (Пользователь, Участник, Студент).

И, конечно, вы можете сильно отличаться от этого, но это должно помочь мне.

И да, пожалуйста, не используйте XML в базе данных, не тратьте нервы и драгоценное личное время.

Приветствие.

3 голосов
/ 17 февраля 2010

Если вам действительно нужны отдельные модели для каждой роли, которую вы используете, то я бы рекомендовал использовать полиморфную ассоциацию ( подробнее здесь ). Итак:

# User model
belongs_to :owner, :polymorphic => true

# Student model
has_one :user, :as => :owner

# Any other model
has_one :user, :as => :owner

А вам нужно добавить в таблицу пользователей:

 t.integer :owner_id
 t.string  :owner_type
...