您目前所拥有的内容适用于将用户与教室相关联的情况,但也不适用于教师,因为目前关联这两个模型的表格只能表示一种关系。
注意:Rails 要求模型名称是单数且不带下划线,即在您的示例中使用 ClassroomUser 而不是 Classroom_Users。
要将教师与教室联系起来,一种方法是创建一个额外的连接模型:
user.rb:
class User < ActiveRecord::Base
has_many :classroom_teachers
has_many :classroom_students
has_many :teaching_classrooms, through: :classroom_teachers
has_many :attending_classrooms, through: :classroom_students
end
classroom.rb:
class Classroom < ActiveRecord::Base
has_many :classroom_teachers
has_many :classroom_students
has_many :teachers, through: :classroom_teachers
has_many :students, through: :classroom_students
end
classroom_student.rb:
class ClassroomStudent < ActiveRecord::Base
belongs_to :student, class_name: 'User', foreign_key: 'user_id'
belongs_to :attending_classroom, class_name: 'Classroom', foreign_key: 'classroom_id'
end
classroom_teacher.rb:
class ClassroomTeacher < ActiveRecord::Base
belongs_to :teacher, class_name: 'User', foreign_key: 'user_id'
belongs_to :teaching_classroom, class_name: 'Classroom', foreign_key: 'classroom_id'
end
Rails 通常会根据字段的名称计算出与字段相关的模型类型,例如users 字段将链接到 User 模型的集合。使用上述模式,Rails 无法从关联字段的名称推断模型的类型,因为它不知道 teacher 是 user 的别名。为了克服这个问题,class_name 属性定义了连接字段的模型类型。
出于同样的原因,Rails 需要一些指导来了解哪个数据库键与哪个字段相关,这就是 foreign_key 属性的用途。
最后是迁移:
class CreateClassroomUsers < ActiveRecord::Migration
def change
create_table :users do |t|
end
create_table :classrooms do |t|
end
create_table :classroom_students do |t|
t.belongs_to :user, index: true
t.belongs_to :classroom, index: true
end
create_table :classroom_teachers do |t|
t.belongs_to :user, index: true
t.belongs_to :classroom, index: true
end
end
end
编辑:
或者,您可以在原来拥有的ClassroomUser 模型中添加一个额外字段来描述用户的角色,而不是使用两个连接模型(例如,enum 可以是student 或@ 987654338@)。这将允许将来添加更多角色,并且可能比我之前的建议更容易查询。例如,要检查用户是学生还是教师,您只需要一个查询:
example_user.classroom_users
然后可以检查返回的ClassroomUser 记录上的角色字段。有关该方法的示例,请参阅 this question。