2012-04-12 14 views
0

Bitte helfen Sie einem Neuling, den besten Weg zur Implementierung der Vererbung in RoR3 zu wählen. Ich habe:Modellvererbung in Ruby on Rails 3

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

Ich denke, dass Single Table Inheritance eine schlechte Lösung ist, weil es eine Menge von null Feldern in der Tabelle erstellt werden. Was ist der beste Weg, dies zu tun? Verwenden Sie polymorphe Assoziationen (mit has_one?)? Verwenden Sie "any_to/has_one" (aber wie zeigt man dann im Player die Felder der Person an?)? Vererbung nicht implementieren? Andere Lösungen?

Antwort

1

Während ich denke STI wahrscheinlich ist der Ansatz ich dafür verwenden würde, eine andere Möglichkeit, wenn Sie eine Menge von NULL Attribute vermeiden wollen, ist eine Spalte other_attributes zu Ihrer Person Modell hinzuzufügen, die eine Hash von Attributen gespeichert werden . Um dies zu tun, fügen Sie eine text Spalte auf die people Tabelle:

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

Dann stellen Sie sicher das Attribut im Modell serialisiert wird. Und möchten Sie vielleicht einen Wrapper schreiben sicherzustellen, dass es als eine leere Hash initialisiert wird, wenn Sie es verwenden:

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 

Dann können Sie das Attribut wie folgt:

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

Ein Nachteil bei diesem Ansatz ist, dass Sie Zeichenfolgen als Schlüssel beim Abrufen von Daten von other_attributes verwenden sollten, da die Schlüssel immer Zeichenfolgen sind, wenn die Hash aus der Datenbank abgerufen wird.