РЕЙЛЫ Пользовательские иерархии;классы, ассоциации.Полиморфный? - PullRequest
3 голосов
/ 25 января 2012

Я поражен тем, как трудно все еще найти однозначный ответ на этот вопрос: это кажется настолько распространенным, что я, должно быть, смотрю на все это неправильно.

У нас есть пользователи, чьи роли авторизации выполняют что-тонапример, ROLES =% w [администратор-модератор-ученик забанен]

Обычно рекомендуется использовать поле ROLES и наследование одной таблицы для (как здесь )

class User < ActiveRecord::Base
end

class Student < User
end

class Teacher < User
end

Но это помещает все данные в одну таблицу.Что если у нас будет достаточно данных, уникальных для каждого типа пользователя?

student
  year:integer
  request_id:integer
  portfolio_id:integer
  status:string
  ...

teachers
  user_id:integer
  district:string
  school:string
  subject1:string
  subject2:string
  specialty:string
  bio:text
  ...

STI дает такие вещи, как student.specialty и teacher.portfolio_id, которые мы не хотим и должны были бы заблокировать.

Ruby Way предлагает класс абстрактной базовой модели для обработки отдельных таблиц:

class User < ActiveRecord::Base
  self.abstract = true
end

class Student < User
end

class Teacher < User
end

, что позволит использовать уникальные таблицы как для ученика, так и для учителя.Однако он предупреждает, что User.find (: all) не будет работать.Плюс, есть общие атрибуты, которые мы хотели, и в этом вся суть модели User:

User
  username:string
  email:string
  password:string
  role:string

Поскольку нет таблицы User, нет общих атрибутов?

Различные другие ответы намекают наиспользуя :polymorphic => true, :class_name => 'User' или as:, но все объясняется больше как добавление комментариев к сообщению и изображению.Что не кажется хорошей параллелью.

Кажется, я помню по крайней мере один язык (и, возможно, пару OODB), который просто использовал отношение IS-A для наследования атрибутов.

Какой путь у РЕЙЛОВ?

1 Ответ

0 голосов
/ 25 января 2012

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

Я бы предпочел использовать универсальную модель пользователя, в которой общие элементы, такие как электронная почта, имя и для каждого типа пользователя, имеют отдельную модель (и стол).Таким образом, учителя и ученики могут ссылаться на пользователей, но имеют свои собственные поля.

Роли также должны быть в отдельной таблице отдельно от пользователей.

Ссылаться на запись пользователя следующим образом:

class Teacher < AR::Base
  belongs_to :user
end
class Student < AR::Base
  belongs_to :user
end
class User < AR::Base
  has_one :teacher
  has_one :student
end
...