因此,我设置了单表继承,这样我就可以为 User 表创建两个子类。在我当前的实现中,这两个子类将拥有完全相同的字段,因此我认为 STI 在这里是有意义的。
类 User < ApplicationRecord
结束
类 Student < 用户
结束
类 教师 < 用户
结束
类 约会 < 应用记录
结束
我想创建一个与学生有多对一关联、与教师也有多对一关联的预约模型。但是,由于学生和教师属于同一个用户表,我将如何创建数据迁移,以便与这些模型建立关联?
类 CreateAppointments < ActiveRecord::Migration[7.0]
def 更改
create_table :appointments do |t|
t.datetime :start_datetime
t.references :users, null: false, foreign_key: true
# t.references :users, null: false, foreign_key: true -->这个应该是为学生设置的
t.timestamps
结束
结束
结束
我继续使用 STI 是否有意义,还是应该为学生和教师创建单独的表格?目前对我来说没有太大意义,因为它们的字段完全相同。但这样一来,进行预约关联就会变得更加容易。
你目前的数据库架构设计为
单表继承(STI)
,对于
Student
和
Teacher
模型来说是一个不错的选择,因为它们都继承自
User
模型并拥有相同的属性。STI 的优势在于,它可以让你在一个表中存储不同类型的用户,从而简化某些查询。
然而,你遇到的问题在于,
Appointment
模型需要与
Student
和
Teacher
都建立关联,而他们都在同一个表中。
解决这个问题有两个主要方法:
1. 使用多态关联:
- 不需要更改你的数据库架构。
-
在
Appointment
模型中添加两个新的引用,一个用于student
,一个用于teacher
。 -
将这两个引用设置为多态的,这意味着它们可以指向不同类型的模型(在本例中是
Student
和Teacher
)。
以下是更新后的迁移文件:
ruby
class CreateAppointments < ActiveRecord::Migration[7.0]
def change
create_table :appointments do |t|
t.datetime :start_datetime
t.references :appointable, polymorphic: true, null: false
t.timestamps
end
end
end
你需要在你的模型中添加以下关联:
```ruby
class Appointment < ApplicationRecord
belongs_to :appointable, polymorphic: true
end
class Student < User has_many :appointments, as: :appointable end
class Teacher < User has_many :appointments, as: :appointable end ```
2. 使用独立的表进行关联:
-
创建两个新的表
student_appointments
和teacher_appointments
,用于存储与Student
和Teacher
的关联。 -
这些表将包含
appointment_id
、user_id
和type
(用于区分Student
或Teacher
)列。
以下是新的迁移文件: ```ruby class CreateStudentAppointments < ActiveRecord::Migration[7.0] def change create_table :student_appointments do |t| t.references :appointment, null: false, foreign_key: true t.references :student, null: false, foreign_key: { to_table: :users } t.timestamps end end end
class CreateTeacherAppointments < ActiveRecord::Migration[7.0]
def change
create_table :teacher_appointments do |t|
t.references :appointment, null: false, foreign_key: true
t.references :teacher, null: false, foreign_key: { to_table: :users }
t.timestamps
end
end
end
你需要在你的模型中添加以下关联:
ruby
class Appointment < ApplicationRecord
has_many :student_appointments
has_many :students, through: :student_appointments
has_many :teacher_appointments
has_many :teachers, through: :teacher_appointments
end
class Student < User has_many :student_appointments has_many :appointments, through: :student_appointments end
class Teacher < User has_many :teacher_appointments has_many :appointments, through: :teacher_appointments end ```
选择哪种方法取决于你的具体需求:
-
如果你预计将来会有更多类型的用户需要与
Appointment
关联,那么 多态关联 更灵活,因为它不需要你为每种新类型创建新表。 -
如果你需要在
Student
或Teacher
关联上添加特定属性,那么 独立的表 更合适,因为它允许你在关联表中添加自定义列。
总的来说, 对于你的情况,我建议使用多态关联,因为它更简洁,并且可以很好地满足你的需求。
标签:ruby-on-rails,ruby,model-view-controller,activerecord,single-table-inheritance From: 78577951