我有一个名为Post
的类:
class Post < ActiveRecord::Base
end
字符串
我有一个名为Question
的类,它继承自Post
:
class Question < Post
end
型
我有一个名为Answer
的类,它也继承自'Post':
class Answer < Post
end
型
在Post
中,我有一个名为post_type_id
的列,它的类型是Integer
。
如何使用STI和特定列名&类型从Post继承?0
表示Question
,1
表示Answer
。(0 & 1是posts表中post_type_id
的值)
5条答案
按热度按时间xu3bshqb1#
你可以像这样改变单表继承列的名称:
字符串
然而,没有办法让Rails使用整数而不是将实际类型存储为字符串,这让我觉得这可能不是单目标继承的好用例。也许作用域更适合你:
型
fivyi3re2#
实际上有一种方法,就像所有的事情一样。你可以重写find_sti_class方法来基于整数查找你的类型。
eqoofvh93#
这可能就是你要找的
http://lorefnon.me/2014/07/27/optimizing-sti-columns.html
编辑:更新的URL(感谢@ Subhashmartran)
monwx1rj4#
您需要使用self.inheritance_column设置列类型然后您必须为以下方法提供您自己的行为:“sti_class_for(type_name)”,该方法位于此文件“activerecord/lib/active_record/inheritance.rb”中
所以你将不得不对上面的文件进行修补。
这不是推荐的方法,您必须进行迁移并更改所有值以匹配您的类名。
hxzsmxv25#
ENUM方式:
这不需要任何重写,因为传递给
sti_class_for
方法的值是枚举值,如果设置正确,则不需要任何进一步的干预。字符串
CONSTANT方法:
这需要重写,这在某些情况下不是优选的。
型
其他案例:
我想补充一些澄清,这是从我发现这篇文章和当时的答案失踪。
self.inheritance_column
是你需要的大部分内容。然而,根据该列数据的格式,你可能需要将其格式化为ActiveRecord所期望的格式,或者你可能会得到类似于以下错误的东西:型
在我的例子中,数据是在snake_case而不是CamelCase中。sti_class_for方法的简单重写为我解决了这个问题。
型
这个问题也可以通过将数据以预期的格式存储在DB中来解决,然后在用于其他目的时转换为替代格式。您的需求可能非常,所以在决定走哪条路时请记住这一点。
注意事项:在我的例子中我没有选择enum的原因是为了避免使用和enum更改DB值的任何不可预见的副作用,因为虽然它是可能的并且有效,但它破坏了enum是a mapping for database integers to other values的意图。
Declare枚举属性,其中的值Map到数据库中的整数,但可以按名称查询
有一个blog post实际上提出了一个论点,要求对你的枚举进行严格的限制,这在documentation中提到,并对性能提出了警告:
最后,也可以使用字符串列来持久化枚举值。请注意,这可能会导致数据库查询速度变慢:
型
所以再一次,你的需求可能非常,所以相应地选择.