问题描述
我参考了一些资料来弄清楚如何在 Ruby On Rails 中实现单表继承。我使用的具体示例仅涉及两种类型的用户:RegularUser
和 Admin
,它们继承自 User
模型,该模型具有一些类似 username
的字段。
User
模型中的字段之一是用户的类型,它只是一个字符串字段。我的问题是:当我简单地在名为“type”的字符串字段中指定它时,Rails 如何连接要使用的子类上的点,该字段可能只是一个与子类无关的字符串字段?如果 type
字段符合我的想法,是否意味着它是一个专门为 RoR 中的 STI 保留的关键字?
任何指针将不胜感激。
这是我的用户迁移文件(没什么特别的):
class createusers < ActiveRecord::Migration[6.1]
def change
create_table :users do |t|
t.string :username
t.string :email
t.string :type
t.timestamps
end
end
end
解决方法
Rails 有根据类型名infer the corresponding class 的方法
所以如果在你的数据库中你有一个记录
User,id: 5,type: 'user_admin'
然后你User.find(5)
Rails 将查看类型值 'user_admin' 并通过基本上执行 ActiveSupport::Dependencies.constantize("user_admin")
为您常量化正确的实例
这是一个花哨的名字,表示给我对应于这个字符串的 ruby 类。
在 Rails 中,除了促进 STI 之外,您不应该使用“type”作为列名,因此它确实是一种保留字,如果您的数据库包含不是 AR 类名的任何内容,您将导致代码崩溃在那里。如果您想为列使用名称“类型”,则需要按照说明更改继承列here
,我认为要回答您的问题是这样的。
当一个表有一个名为 type
的列时,活动记录将启用 STI,无论这是否是您的意图。这就是点如何连接起来的。如果表中的列名为 type
,如果不是有意使用 STI,则可能会破坏事情。
执行 type
时不必填写 create
字段的值,活动记录将使用类名填充它。从基类(或任何继承的类)执行 find
将返回 type
列中指定的类的实例。
所有这一切都是通过名为 type
的列的存在而实现的。