请帮助新手选择在 RoR3 中实现继承的最佳方式。我有:
-Person(地址字段、生日等) -Player,继承自 Person(位置、鞋码等) -Goalkeeper,继承自 Player(与此角色相关的其他特定字段)
我认为单表继承是一个不好的解决方案,因为创建的表中会有很多空字段。做这个的最好方式是什么?使用多态关联(使用 has_one?)?使用belongs_to/has_one(但是如何在Player视图中显示Person的字段呢?)?不实现继承?其他解决方案?
请帮助新手选择在 RoR3 中实现继承的最佳方式。我有:
-Person(地址字段、生日等) -Player,继承自 Person(位置、鞋码等) -Goalkeeper,继承自 Player(与此角色相关的其他特定字段)
我认为单表继承是一个不好的解决方案,因为创建的表中会有很多空字段。做这个的最好方式是什么?使用多态关联(使用 has_one?)?使用belongs_to/has_one(但是如何在Player视图中显示Person的字段呢?)?不实现继承?其他解决方案?
虽然我认为 STI 可能是我会使用的方法,但如果您想避免大量NULL
属性,另一种可能性是在您的 Person 模型中添加一个列other_attributes
来存储一个Hash
属性。为此,请text
向表中添加一列people
:
def self.up
add_column :people, :other_attributes, :text
end
然后确保该属性在模型中被序列化。您可能需要编写一个包装器以确保Hash
在使用它时将其初始化为空:
class Person < ActiveRecord::Base
serialize :other_attributes
...
def other_attributes
write_attribute(:other_attributes, {}) unless read_attribute(:other_attributes)
read_attribute(:other_attributes)
end
end
然后您可以按如下方式使用该属性:
p = Person.new(...)
p.other_attributes #=> {}
pl = Player.new(...)
pl.other_attributes["position"] = "forward"
pl.other_attributes #=> {"position" => "forward"}
这种方法的一个警告是,在从 中检索数据时,您应该使用字符串作为键,因为从数据库中检索other_attributes
时,键将始终是字符串。Hash
我建议性病。另一种解决方案是使用像 mongodb 这样的文档存储,或者使用 activerecord 存储http://api.rubyonrails.org/classes/ActiveRecord/Store.html。如果您有一个 postgress 数据库,请查看他的 HStore 专栏http://rubygems.org/gems/activerecord-postgres-hstore。
另一种选择是 PostgreSQL 表继承。http://www.postgresql.org/docs/8.1/static/ddl-inherit.html