[英]Model inheritance, the Factory pattern, and self-parsing in Ruby-on-Rails
[英]Model Inheritance in Ruby on Rails 3
请帮助新手选择在RoR3中实现继承的最佳方法。 我有:
-Person (address fields, birthdate, etc.) -Player, inherits from Person (position, shoe_size, etc.) -Goalkeeper, inherits from Player (other specific fields related to this role)
我认为“单表继承”是一个不好的解决方案,因为在创建的表中将有很多空字段。 做这个的最好方式是什么? 使用多态关联(与has_one吗?)? 使用belongs_to / has_one(但是又如何在“播放器”视图中显示“人”的字段?)? 不实现继承吗? 其他解决方案?
尽管我认为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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.