Ассоциации Rails - как я могу создать ассоциации для разных типов пользователей?

Я создаю веб-приложение, которое состоит из школ, курсов, студентов и учителей.

В школе может быть много курсов, а в курсе один учитель и много учеников.

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

Я бы хотел сделать что-то вроде следующего:

class School < ActiveRecord::Base
  has_many :courses
  has_many :students :through enrollments
  has_many :teachers :through courses
end

class Course < ActiveRecord::Base
  has_one :teacher
  belongs_to :school
  has_many :students :through enrollments
end

class User < ActiveRecord::Base
  has_many :courses
  has_many :schools
end

Но если у меня есть только таблица пользователей, а не две отдельные таблицы учеников и учителей, это не сработает.

Вместо этого мне пришлось бы сделать что-то вроде

class School < ActiveRecord::Base
  has_many :users [that are teachers]
  has_many :users :through enrollments [that are students]
end

Как я могу настроить свою модель и ассоциации, чтобы эта работа работала?

Спасибо.


person Deonomo    schedule 07.01.2012    source источник


Ответы (3)


Используйте наследование.

Учителя и ученики унаследованы от модели пользователей. Вы можете проконсультироваться с http://api.rubyonrails.org/classes/ActiveRecord/Base.html для получения дополнительной информации. Обязательно создайте столбец типа или эквивалент в таблице User.

class User < ActiveRecord::Base
end

class Student < User
end

class Teacher < User
end

Rails будет обрабатывать их индивидуально, но они все равно будут существовать в таблице User. Сообщите мне, если вам потребуется дополнительная помощь.

person sohaibbbhatti    schedule 07.01.2012
comment
Хм, я не уверен, что хочу создать столбец типа в своей таблице пользователей, потому что один и тот же пользователь иногда может быть учеником, а иногда и учителем. Например, вы можете вести один курс, будучи студентом другого курса. - person Deonomo; 07.01.2012
comment
Я думаю, что сохаиб прямо здесь. Вы можете создать типовой столбец и не беспокоиться об этом вообще. Объект, который вы получите от Active Record, будет либо учеником, либо учителем, в зависимости от типа. Это просто еще один уровень абстракции. - person Wahaj Ali; 07.01.2012
comment
Позволит ли это одному пользователю быть и учеником, и учителем? - person Deonomo; 07.01.2012
comment
У вас может быть две записи для одного и того же человека, т. Е. один как студент и один как учитель. Это также имеет смысл, потому что у вас, скорее всего, будет отдельная логика для двух. Большинство порталов школ / колледжей также относятся к этим двум по-разному. - person sohaibbbhatti; 08.01.2012

Возможно, я что-то пропустил, но это должно сработать, если вы добавите class_name в свою связь с «пользователем»:

class School < ActiveRecord::Base
  has_many :courses
  has_many :students :through enrollments, :class_name => "User"
  has_many :teachers :through courses, :class_name => "User"
end

class Course < ActiveRecord::Base
  has_one :teacher, :class_name => "User"
  belongs_to :school
  has_many :students :through enrollments, , :class_name => "User"
end

class User < ActiveRecord::Base
  has_many :courses
  has_many :schools
end
person Baldrick    schedule 07.01.2012
comment
Спасибо, это очень помогло. - person Deonomo; 07.01.2012
comment
class_name фактически игнорируется в :through ассоциациях. Вместе с primary_key и foreign_key - person Azolo; 07.01.2012

Добавьте столбец teachers_id в courses и используйте belongs_to вместо has_one. Затем добавьте параметр class_name.

class School < ActiveRecord::Base
  has_many :courses
  has_many :students :through enrollments
  has_many :teachers :through courses
end

class Course < ActiveRecord::Base
  belongs_to :teacher, :class_name => 'User'
  belongs_to :school
  has_many :students :through enrollments
end

class User < ActiveRecord::Base
  has_many :courses
  has_many :schools, :through enrollments
  has_many :teachers, :through :courses
end
person Azolo    schedule 07.01.2012