假设我有User
模型及其属性(first_name,last_name等),我想创建两个新模型Teacher
和Student
。
他们将继承User
模型属性,并且他们将具有特定属性。例如,Student
模型将具有file
属性,Teacher
模型将具有subject
属性。
我正在阅读STI(单表继承)和多态关系。
我应该寻找什么来实现这一目标?你有什么例子可以展示吗?
答案 0 :(得分:1)
如果在users
表上创建名为“type”的属性,Rails将自动假设您要实现STI。然后,创建教师和学生模型就像扩展User类一样简单。子类的名称将自动插入到类型列中,并用于按预期过滤查询。
<强> user.rb 强>
class User < ApplicationRecord
end
<强> teacher.rb 强>
class Teacher < User
end
<强> student.rb 强>
class Student < User
end
使用STI,您可以放置模型将在同一个表中使用的所有列,并忽略(默认为null)那些在任何给定情况下不适用的列。
多态关系允许两个或多个表填充相同的关联。如果您想使用三个不同的表但确保用户具有教师或学生,则可以将其建模为多态belongs_to
。缺点是您需要返回用户模型才能访问共享信息,即teacher.user.first_name
。
答案 1 :(得分:-1)
我发现这个宝石看起来像我正在寻找的东西。我玩了一点,它对我有用。
https://github.com/krautcomputing/active_record-acts_as
所以,对于我的情况,我已添加到Gemfile:
gem 'active_record-acts_as'
然后:
$ bundle
这些是我的迁移:
# 20171202142824_create_users.rb
class CreateUsers < ActiveRecord::Migration[5.1]
def change
create_table :users do |t|
t.string :first_name
t.string :last_name
t.date :birth_date
t.string :dni
t.string :cuil
t.string :email
t.string :phone
t.string :address
t.string :postal_code
t.string :city
t.string :state
t.string :country
t.actable # This is important!
t.timestamps
end
end
end
# 20171202142833_create_students.rb
class CreateStudents < ActiveRecord::Migration[5.1]
def change
create_table :students do |t|
t.string :file
# Look, there is no timestamp.
# The gem ask for it to be removed as it uses the User's timestamp
end
end
end
# 20171202142842_create_teachers.rb
class CreateTeachers < ActiveRecord::Migration[5.1]
def change
create_table :teachers do |t|
# Look, there is no timestamp.
# The gem ask for it to be removed as it uses the User's timestamp
end
end
end
这些是我的模特:
# user.rb
class User < ApplicationRecord
actable
validates_presence_of :first_name, :last_name
def full_name
[last_name.upcase, first_name].join(', ')
end
end
# student.rb
class Student < ApplicationRecord
acts_as :user
validates_presence_of :file
end
# teacher.rb
class Teacher < ApplicationRecord
acts_as :user
end
现在,通过所有这些设置,您只需创建一个新学生和新教师:
Student.create!(first_name: 'John', last_name: 'Doe', file: 'A125')
=> #<Student id: 3, file: "A125">
Teacher.create!(first_name: 'Max', last_name: 'Power')
=> #<Teacher id: 1>
您可以访问用户的所有方法和属性。例如:
Teacher.last.full_name
=> "POWER, Max"