Rails 提供了从父模型类继承模型类的能力。然后模型可以具有共享属性,但也可以具有唯一属性。在数据库中,所有这些模型对象都存储在所有类的同一个表中,因此这称为单表继承或 STI。 (记录在 here 但博客文章中有更好的文档。)
如果您使用这种方法,那么您可以在父类中搜索所有实例以找到匹配的对象/记录。
class AccessToken < ActiveRecord::Base
# has attribute access_token, and maybe others
end
class OneAccessibleKind < AccessToken
# may have other attributes
end
class AnotherAccessibleKind < AccessToken
# may have other attributes
end
您的迁移将如下所示:
create_table :access_token do |t|
t.string "access_token"
t.string "type"
# add any additional attributes of subclasses
t.timestamps
end
然后您可以查询父类。注意
all_models = AccessToken.where(access_token: 'a-token')
请注意,这些都将作为 AccessToken 对象(即父类)返回,但您可以检查 type 属性以查看它们的基类是什么。
但是,如果您的类主要是不同的字段,这可能不是最佳解决方案,因为您将有很多未使用的列。根据您的后备数据库(假设是面向行的 SQL)和对象的数量,这可能是一个性能问题。
另一种选择是使用一对一的关系,并为您的其他每个模型使用AccessToken 模型。在这里您可以使用 STI 关联。
class AccessToken < ActiveRecord::Base
belongs_to :owner, :polymorphic => true
end
class OneAccessibleKind < ActiveRecord::Base
has_one :access_token, :as => :owner
end
class AnotherAccessibleKind < ActiveRecord::Base
has_one :access_token, :as => :owner
end
使用类似这样的迁移:
create_table :access_token do |t|
t.string :access_token
t.integer :owner_id, null: false
t.string :owner_type, null: false
t.timestamps
end
create_table :one_accessible_kind do |t|
# any attributes for this type
t.timestamps
end
然后您可以找到一个访问令牌并访问每个owner 以获取对象。
AccessToken.where(access_token: 'a-token').map(&:owner)