Rails STI 和 "type" 字段

Rails STI and the "type" field

我通过一些资源了解如何在 Ruby On Rails 中实现单一 Table 继承。我使用的具体示例只涉及 2 种类型的用户:RegularUserAdmin 继承自 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 class 对应于这个字符串。

在 Rails 中,你不应该使用“type”作为列名,而不是为了促进 STI,所以它确实是一个保留字,如果你的数据库包含任何东西,你的代码就会崩溃里面没有 AR class 个名字。如果要为列使用名称“type”,则需要按照 here

中的说明更改 inheritance_column

关于你的问题,我认为要回答的是这个。

当 table 有一个名为 type 的列时,活动记录将启用 STI,无论这是否是您的意图。这就是点连接的方式。 table 和名为 type 的列如果不是预期的 STI 可能会破坏事情。

您在执行 create 时不必填写 type 字段的值,活动记录将使用 class 的名称填充它。从基础(或任何继承的 classes)执行 find 将 return type 列中指定的 class 的实例。

所有这些都是通过名为 type.

的列的存在而启用的