Одинарное наследование таблиц с отношениями - PullRequest
0 голосов
/ 06 февраля 2012

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

Идея состоит в том, чтобы создать таблицу пользователей, которая содержит все основные данные для данного человека.См. UML / ER ниже для примера атрибутов.

  • Пользователь может быть одновременно Помощник и Ученик одновременно.
  • Помощник и Ученик должен наследовать от Пользователь .

Идея заключалась в том, чтобы наследовать непосредственно от пользователя, как это.

class User < ActiveRecord::Base
  # ...
  def awesome?
    [true, false].sample
  end
  # ...
end

class Student < User
  has_one :student
  has_many :registered_courses, through: :students
end

Student.new.awesome?

Это делает отношения в модели студента очень странными.has_many :registered_courses, through: :students

В конце я хочу сделать что-то подобное.

student.full_name
student.pin_code
student.registered_courses

Одним из решений будет ручная реализация метода, например,

class Student < User 
  has_one :student 
  def pin_number
    student.pin_number
  end
end

Но выглядит действительно странно, если ссылаться на объект студента внутри модели студента.

Есть ли более ясный и лучший способ сделать это?

Вот пример UML / ER,Я пытался сохранить этот пример в чистоте, удаляя не соответствующие атрибуты.Вот почему в зарегистрированном объекте курса так мало атрибутов.

uml

Ответы [ 2 ]

0 голосов
/ 06 февраля 2012

Я чувствую, что Наследование - плохой ход. Если вы собираетесь иметь ИППП, как это, то ИМЕЕТ быть тем или иным.

Вместо этого бросьте всю свою логику в модель User, все ваши данные все равно будут там. Кроме того, поскольку Student & Assistant не являются взаимоисключающими, не должно быть никаких методов, которые будут перекрывать друг друга.

Почему не ИППП?

STI в основном предназначен для объектов, которые содержат одни и те же данные, но делают с ними разные вещи.

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

process_1:
  order_id: 1
  specification: foo
  type: build

process_2:
  order_id: 1
  specification: foo
  type: test

В этом примере единственное, что изменяется в данных, это тип, но поскольку тип меняется, я знаю, что process выполнить из спецификации.

0 голосов
/ 06 февраля 2012

ИППП не является хорошим выбором для того, как вы это сформулировали здесь, поскольку пользователи могут быть как учениками, так и помощниками.Когда вы используете STI, вы обычно добавляете столбец типа, чтобы указать, какому подклассу действительно принадлежит запись.Если и Студент, и Ассистент наследуют от Пользователя, тогда это действительно не вариант, так как вы будете вынуждены создавать дубликаты записей Пользователя для того, кто является Ассистентом и Студентом.

Я думаю, что вам было бы лучше просто иметь строки Student и Assistant, принадлежащие_ Student, а затем делегировать элементы, содержащиеся в User, обратно в объект User.

...