2010-12-04 7 views
2

Ich bin neu bei Ruby on Rails, also weiß ich nicht so viel über Modellassoziation. Aber hier ist mein Problem:Ruby on Rails - has_many basiert auf "kind"

Ich habe eine Projektressource, die "has_many: items". Jeder Gegenstand hat einen Namen und eine Art (der Typ gibt den Typ des Gegenstandes an). Ich möchte verschiedene Assoziationen auf der Grundlage der „Art“ -Wertes ... wie folgt aus:

class Item < ActiveRecord::Base 
    belongs_to :project, :dependent => :destroy 

    has_many :sports, :class_name => 'NormalSport' # if kind = 'normal_sport' 
    has_many :sports, :class_name => 'SuperSport' # if kind = 'super_sport' 
    has_many :sheep # if kind = 'sheep' 
    has_many :drinks # if kind = 'drink' 
end 

So bedeutet dies ein Element sein kann, entweder eine „normal_sport“, „super_sport“, „Schaf“ oder " Getränk". Also, wenn das Element ein normal_sport ist, würde Ich mag die Lage sein, zu sagen (so etwas wie):

Project.first.items.first.sports.all 

Und dann dem „Sport“ geht an den „NormalSport“ -Klasse.

Aber vielleicht ist dies die falsche Art, dies zu tun. Ich schaute auf polymorphe Assoziationen ... aber es sieht nicht so aus, als wäre es diese Art von Assoziation. Welche Art von Assoziation ist das? Wo ist der "Gegenstand" nur eine Art "Mittelmann-Modell"?

Danke! (Und sorry für mein schlechtes Englisch)

Mit freundlichen Grüßen Alexander


Danke euch beiden für die Antwort. Aber es scheint, als ob es die Routen nicht mag. Wenn ich so etwas sagen wie (in dem Artikel-Teil, die alle Elemente für ein Projekt Schleifen):

<%= link_to 'Destroy', [@project, item], :confirm => 'Are you sure?', :method => :delete %> 

es nicht als Mangel verhält es. Wenn es ein „Supersport“ -item ist, verwendet es die URL:

/projects/1/super_sport/4 

Und wenn es ein „Schaf“ -item ist, geht es zu

/projects/1/sheep/5 

Wie kann ich sagen, dass sie ALLE sollten gehen zu:

/projects/:project_id/items/:item_id 

Sie alle verwenden den ItemsController. Es wäre schön, wenn alle diese Route nutzen könnten. Ich habe mit diesem Hack versucht:

class Item < ActiveRecord::Base 
    belongs_to :project 
    validates_uniqueness_of :type, :scope => :project_id 

    # Hack. 
    def self.model_name 
    name = 'item' 
    name.instance_eval do 
     def plural; pluralize; end 
     def singular; singularize; end 
    end 
    return name 
    end 
end 

Aber dann bricht die Validierung. Ich hoffe du verstehst mein Problem!

Antwort

0

Wenn polymorphe Assoziationen nicht Ihren Anforderungen entsprechen, können Sie auch in Single Table Vererbung (STI) suchen.

Ein anderer Ansatz wäre, Bereiche für die Auswahl von Kindmodellen zu definieren.

4

Es sieht so aus, als ob Sie STI wollen, also gibt es eine Basisklasse mit der gemeinsamen Funktionalität, aber verschiedene Arten von Modellen, die davon erben. STI ist einfach zu implementieren:

class Sport < ActiveRecord::Base 
    belongs_to :item 
end 

class NormalSport < Sport 
end 

class SuperSport < Sport 
end 

class Item < ActiveRecord::Base 
    has_many :sports 
    has_many :normal_sports 
    has_many :super_sports 
end 

Durch die richtige Klasse verwenden, Rails die sports Tisch für Sie automatisch filtern. Wenn die Verwendung unterschiedlicher Klassen mühsam ist, können Sie auch die Basis Sport Klasse verwenden und das Feld type manuell filtern.