Users/Classroom 协会
Users/Classroom Associations
我是 rails 的新手,我正在尝试创建一个应用程序,用户可以在其中拥有很多教室,而教室可以有很多用户。但是,我不确定如何设置模型。
假设我有一位老师叫乔。乔有很多教室。 Joe 的每个教室都可以有很多学生,所以从这么多教室 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 拿来的。
另外,我应该如何通过迁移在数据库中镜像这些模型?
你现在所得到的将适用于将用户与教室相关联的情况,但不适用于教师,因为目前将两种模型相关联的 table 只能表示一种类型关系。
注意: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
字段将 link 到 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
或 teacher
)。这将允许将来添加更多角色,并且可能比我之前的建议更容易查询。例如,要检查用户是学生还是老师,您只需要一个查询:
example_user.classroom_users
然后可以检查返回的 ClassroomUser
记录中的角色字段。有关该方法的示例,请参阅 this question。
我是 rails 的新手,我正在尝试创建一个应用程序,用户可以在其中拥有很多教室,而教室可以有很多用户。但是,我不确定如何设置模型。
假设我有一位老师叫乔。乔有很多教室。 Joe 的每个教室都可以有很多学生,所以从这么多教室 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 拿来的。 另外,我应该如何通过迁移在数据库中镜像这些模型?
你现在所得到的将适用于将用户与教室相关联的情况,但不适用于教师,因为目前将两种模型相关联的 table 只能表示一种类型关系。
注意: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
字段将 link 到 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
或 teacher
)。这将允许将来添加更多角色,并且可能比我之前的建议更容易查询。例如,要检查用户是学生还是老师,您只需要一个查询:
example_user.classroom_users
然后可以检查返回的 ClassroomUser
记录中的角色字段。有关该方法的示例,请参阅 this question。