I have a user model that I want to assign to be teacher or student( teacher and student are two separated model ) because if the user signup he would have different registration fields depending on if he is teacher or student. User can be a teacher or student, not both.
I have tried, but don't think that this is the best way to do it. Any help?
class User < AR
has_secure_password
has_one :teacher, class_name: "teacher", foreign_key: "teacher_id", conditions: { role: 'teacher' }
has_one :student, class_name: "student", foreign_key: "student_id", conditions: { role: 'student' }
enum role: [:teacher, :student]
end
class Teacher < AR
belongs_to :user, class_name: "user", foreign_key: "user_id"
end
class Student < AR
belongs_to :user, class_name: "user", foreign_key: "user_id"
end
This is how you can implement the STI for your case
class User < AR
has_secure_password
# Make all forms with User data send params with ':user' as a param key
# instead of ':user_teacher'/':user_student'
def self.model_name
ActiveModel::Name.new(self, nil, 'User')
end
end
class Teacher < User
# custom methods
end
class Student < User
# custom methods
end
This way, you can have your form with form_for @user do # ...
.
One caveat, it is all placed in the Single table in the DB (hence the name Single Table Inheritance), and that means a lot of NULL values for the unrelated fields (say Teacher
has a teacher_identification_number
, and a user has student_identification_number
which are different in size or they require different validation) for all the Students that attribute teacher_identification_number
would be NULL, and vice-versa.
If the fields are much different between the two models, then you can analyze your data and put it in the different table to which only the Teacher/Student would have access to, that is called a Database Normalization (say Teacher
has_many
ClassInfo
's or has_one
JobInfo
; or Teacher
has_one
TeacherProfile
, and Student
has_one
StudentProfile
or whatever).
It all really depends on how you model your DB.
References:
- Blog Post - Medium - STI
- Video Link - Drifting Ruby - STI
- Video Link - @ RailsCasts - STI
- Blog Post - StudyTonight - DB Normalization