2014-02-19 10 views
5

ich mit ein paar Probleme versuchen, STI und polymorphe Assoziationen mit der folgenden Struktur renne zu kombinieren:Kombinieren STI und polymorphe mit Schienen 4

class User < ActiveRecord::Base 
end 

class Runner < User 
    has_many :subscriptions, as: :subscriber, :dependent => :destroy 
    has_many :areas, through: :subscriptions 
end 

class Trainer < Runner 
end 

class Subscription < ActiveRecord::Base 
    belongs_to :subscriber, polymorphic: true 
    belongs_to :area 
end 

class Area 
end 

Wenn ich versuche, in der Konsole:

Runner.find (2101) .areas

SELECT "areas".* FROM "areas" INNER JOIN "subscriptions" ON "areas"."id" = 
"subscriptions"."area_id" WHERE "subscriptions"."subscriber_id" = $1 AND 
"subscriptions"."subscriber_type" = $2 [["subscriber_id", 2101], ["subscriber_type", 
"User"]] 
=> #<ActiveRecord::Associations::CollectionProxy []> 

Allerdings gibt es einen Datensatz mit diesem Läufer:

#<Subscription id: 3, area_id: 2, subscriber_id: 2101, subscriber_type: "Runner", primary_area: true> 

Aber ich verstehe nicht, warum Active Record nach einem Benutzer und nicht nach einem Runner sucht.

Irgendeine Idee warum? oder besseres Design?

+1

Hier ist eine sehr ähnliche Frage mit mehr Antworten ist: http://stackoverflow.com/questions/9628610/why-polymorphic-association-doesnt-work- For-Sti-If-Typ-Spalte der Polymorphie – amoebe

Antwort

8

Von Schienen Dokumentation

polymorphe Assoziationen in Kombination Verwendung mit einzelner Tabelle ist Vererbung (STI) ein wenig schwierig. Damit die Zuordnungen zu wie erwartet funktionieren, stellen Sie sicher, dass Sie das Basismodell für die Modelle STI in der Typspalte der polymorphen Assoziation speichern. Um fortzufahren mit dem Asset-Beispiel oben, nehmen wir an, es gibt Gast Beiträge und Mitglied Beiträge, die die Posts-Tabelle für STI verwenden. In diesem Fall muss die Spalte in der Tabelle posts enthalten sein.

Ihr Abonnement Klasse ändern wie diese

class Subscription < ActiveRecord::Base 
    belongs_to :subscriber, polymorphic: true 
    belongs_to :area 

    def subscriber_type=(sType) 
    super(sType.to_s.classify.constantize.base_class.to_s) 
    end 
end