Ich versuche zu verstehen, wie ActiveRecord Verbindungen behandelt, die komplexer sind als einfache has_many
, belongs_to
, und so weiter.Komplexe Assoziationen in ActiveRecord-Modellen
Betrachten Sie als Beispiel eine Anwendung zum Aufzeichnen von Musikauftritten. Jeder Gig hat eine Band mit einem Genre. Jeder Gig hat auch einen Veranstaltungsort, der eine Region hat.
In der rauen Notation von MS Access (die ich plötzlich das Gefühl ganz nostalgisch fange an) diese Beziehungen würde wie folgt dargestellt werden
1 ∞ 1 ∞ ∞ 1 ∞ 1
Genre ---- Band ---- Gig ---- Venue ---- Region
Ich mag wäre in der Lage sein, zu erfahren, zum Beispiel , alle Bands, die in einer Region gespielt haben, oder alle Orte, die ein bestimmtes Genre beherbergen.
Idealerweise meine Modelle enthalten würde diesen Code
class Genre
has_many :bands
has_many :gigs, :through => bands
has_many :venues, :through => :gigs, :uniq => true
has_many :regions, :through => :venues, :uniq => true
end
class Band
belongs_to :genre
has_many :gigs
has_many :venues, :through => :gigs, :uniq => true
has_many :regions, :through => :venues, :uniq => true
end
class Gig
belongs_to :genre, :through => :band
belongs_to :band
belongs_to :venue
belongs_to :region, :through => :venue
end
und so weiter für Venue
und Region
.
aber es scheint, ich habe etwas zu produzieren, wie dies stattdessen
class Genre
has_many :bands
has_many :gigs, :through => bands
has_many :venues, :finder_sql => "SELECT DISTINCT venues.* FROM venues " +
"INNER JOIN gigs ON venue.id = gig.venue_id " +
"INNER JOIN bands ON band.id = gig.band_id " +
"WHERE band.genre_id = #{id}"
# something even yuckier for regions
end
class Band
belongs_to :genre
has_many :gigs
has_many :venues, :through => :gigs, :uniq => true
# some more sql for regions
end
class Gig
delegate :genre, :to => :band
belongs_to :band
belongs_to :venue
delegate :region, :to => :venue
end
Ich habe zwei Fragen - eine allgemeine und eine besondere.
Die allgemeinen:
Ich hätte gedacht, dass das, was ich versuche, ziemlich oft zu tun würde kommen. Ist das wirklich der beste Weg, oder ist da etwas viel Einfacheres, das ich übersehe?
Das besondere:
Was ich oben haben eigentlich nicht ganz funktionieren! Die #{id}
im zweiten Genre-Modell tatsächlich die ID der Klasse zurückgeben. (Ich denke). Allerdings scheint dies zu funktionieren here und here
Ich realisiere, das ist eine ziemlich epische Frage, also danke, wenn Sie so weit gekommen sind. Jede Hilfe würde sehr geschätzt werden!