我对rails很新,我正在尝试创建一个用户可以拥有许多教室的应用程序,而教室可以拥有许多用户。但是,我不确定如何设置模型。
假设我有一位名叫乔的老师。乔有很多教室。 Joe的每个教室都可以有很多学生,所以在很多教室里,Joe也有很多学生。但我也希望乔能够成为学生的一员,我希望学生能够从同一个帐户创建自己的教室,作为教师。
教室也应该有一位以上的老师。
我还希望能够做类似user.classrooms.first.users的事情,其中用户是Joe,用户是他第一堂课的学生。
我应该创建哪些模型,以及如何设置关联?
我在想has_and_belongs_to_many
,但显然它不再受欢迎了,has_many :through
会更好。它看起来像我这样的东西:
class User
has_many :classroom_users
has_many :classrooms, :through => :classroom_users
end
class Classroom
has_many :classroom_users
has_many :users, :through => :classroom_users
end
class Classroom_User
belongs_to :classroom
belongs_to :user
end
这是对的吗?我从here拿走了它。 另外,我应该如何使用迁移在数据库中镜像这些模型?
答案 0 :(得分:2)
目前您所拥有的内容适用于将用户与教室相关联的情况,但也不适用于教师,因为目前关联两个模型的表只能表示一种类型的关系。
注意: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可以是this question {1}}或student
)。这将允许在将来添加更多角色,并且可能比我之前的建议更容易查询。例如,要检查用户是学生还是教师,您只需要一个查询:
teacher
然后可以检查返回的example_user.classroom_users
记录上的角色字段。有关该方法的示例,请参阅Typesafe ConductR。