1

I'm creating a web app which consists of schools, courses, students, and teachers.

A school can have many courses and a course has one teacher and many students.

The problem I am running into is that a single user could be a teacher of one course, but a student in another course (or even a student or teacher in a course in a different school). I don't want to create a model for teachers and a separate model for students because I would like to track all my users in one place. There is an enrollment table which lists which users are enrolled as students in a course.

I would like to do something like the following:

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

But if I have only a users table and not two separate students and teachers tables, this won't work.

Instead, I would have to do something like

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

How can I set up my model and associations to make this work?

Thanks.

Deonomo
  • 1,583
  • 3
  • 16
  • 25

3 Answers3

3

Use inheritance.

Teachers and students are inherited from the users model. You can consult http://api.rubyonrails.org/classes/ActiveRecord/Base.html for further information. Be sure to create a "type" column or equivalent in your User table.

class User < ActiveRecord::Base
end

class Student < User
end

class Teacher < User
end

Rails will treat them individually, but they will still exist in the User table.Let me know if you need further assistance

sohaibbbhatti
  • 2,672
  • 22
  • 21
  • Hmm, I'm not sure I want to create a type column in my user table because the same user can sometimes be a student and sometimes be a teacher. For instance, you can teach one course while being a student in a different course. – Deonomo Jan 07 '12 at 18:00
  • I think sohaib is right here. You can create a type column, and not have to worry about it at all. The object that you receive from Active Record will either be a Student or Teacher depending on the type. Its just another layer of abstraction. – Wahaj Ali Jan 07 '12 at 18:38
  • Will this allow the same user to be both a student and a teacher? – Deonomo Jan 07 '12 at 18:47
  • You could have two entries for a same individual, I.e. one as a student and one as a teacher. This also makes sense because, you'd most probably be having separate logic for the two. Most School/college portals treat the 2 differently as well. – sohaibbbhatti Jan 07 '12 at 20:41
0

I may have missed something, but it should work if you add the class_name to your relation with "User":

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
Baldrick
  • 23,882
  • 6
  • 74
  • 79
  • `class_name` is actually ignored on `:through` associations. Along with `primary_key` and `foreign_key` – Azolo Jan 07 '12 at 19:57
0

Add a teachers_id column to courses and use belongs_to instead of has_one. Then add a class_name option.

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
Azolo
  • 4,353
  • 1
  • 23
  • 31