简体   繁体   English

Ruby on Rails 3中的模型继承

[英]Model Inheritance in Ruby on Rails 3

Please help a newbie to choose the best way to implement inheritance in RoR3. 请帮助新手选择在RoR3中实现继承的最佳方法。 I have: 我有:

-Person (address fields, birthdate, etc.)
   -Player, inherits from Person (position, shoe_size, etc.)
      -Goalkeeper, inherits from Player (other specific fields related to this role)

I think that Single Table Inheritance is a bad solution, because there will be a lot of null fields in the table created. 我认为“单表继承”是一个不好的解决方案,因为在创建的表中将有很多空字段。 What is the best way to do this? 做这个的最好方式是什么? Use polymorphic associations (with has_one?)? 使用多态关联(与has_one吗?)? Use belongs_to/has_one (but then how to show in the Player views the fields of Person too?)? 使用belongs_to / has_one(但是又如何在“播放器”视图中显示“人”的字段?)? Don't implement inheritance? 不实现继承吗? Other solutions? 其他解决方案?

While I think STI is probably the approach I would use for this, one other possibility, if you want to avoid a lot of NULL attributes, is to add a column other_attributes to your Person model that will store a Hash of attributes. 尽管我认为STI可能是我要使用的方法,但如果要避免使用许多NULL属性,另一种可能的方法是在Person模型中添加一列other_attributes ,该列将存储属性的Hash值。 To do this, add a text column to the people table: 为此,将text列添加到people表:

def self.up
  add_column :people, :other_attributes, :text
end 

Then make sure the attribute is serialized in the model. 然后,确保该属性在模型中已序列化。 And you may want to write a wrapper to make sure it's initialized as an empty Hash when you use it: 而且,您可能想编写一个包装器,以确保在使用它时将其初始化为空的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

Then you can use the attribute as follows: 然后,您可以使用以下属性:

p = Person.new(...)
p.other_attributes                          #=> {}
pl = Player.new(...)
pl.other_attributes["position"] = "forward"
pl.other_attributes                         #=> {"position" => "forward"}

One caveat with this approach is that you should use strings as keys when retrieving data from other_attributes , as the keys will always be strings when the Hash is retrieved from the database. 使用此方法的一个注意事项是,从other_attributes检索数据时,应将字符串用作键,因为从数据库中检索Hash时,键始终是字符串。

I suggest STI. 我建议性传播感染。 An alternative solution is to use a document store like mongodb, or use the activerecord store http://api.rubyonrails.org/classes/ActiveRecord/Store.html . 另一种解决方案是使用诸如mongodb的文档存储,或使用activerecord存储http://api.rubyonrails.org/classes/ActiveRecord/Store.html If you have a postgress database look at his HStore column http://rubygems.org/gems/activerecord-postgres-hstore . 如果您有一个postgress数据库,请查看他的HStore列http://rubygems.org/gems/activerecord-postgres-hstore

Another option is PostgreSQL table inheritance. 另一个选择是PostgreSQL表继承。 http://www.postgresql.org/docs/8.1/static/ddl-inherit.html http://www.postgresql.org/docs/8.1/static/ddl-inherit.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM