Scheinbar redundante Active has_many Definition
-
29-09-2019 - |
Frage
Ich habe die Anwendung has and belongs to many
Stil Assoziationen zu einem Projekt, das ich gearbeitet habe, sondern weil ich in meinem beitreten Modell zusätzliche Informationen erfassen wollte, ich bin Einstellung implizit es über den aufwändigere belongs_to
/ has_many
Ansatz, statt von has_and_belongs_to_many
. Nachdem zunächst auf dem Stolpern, erfuhr ich, dass ich diese beiden Definitionen in meinem Modell Benutzer benötigt wird (und das gleiche im Show-Modell Gegenstück):
has_many :saved_shows
has_many :shows, :through :saved_shows
Alles funktioniert, und meine Frage ist, mehr über die Gestaltung der Rails-Syntax, weil ich sicherstellen möchten, ich bin nicht das größere Bild fehlt hier: warum ist das erste notwendig? Wenn wir Feststellung, dass ein Benutzer eine Liste von Shows über einen Zwischen mit einem Nicht-Standard-Namen saved_shows
zugreifen kann, warum auch has_many :saved_shows
etablieren?
Ich vermute, ich bin nicht der erste haben einen Haken auf diesen einen Hit, so dass ich neugierig bin, warum Rails diese scheinbar redundante Definition erfordert. Ist es nur eine schlecht gewählte Syntax oder gibt es eine tiefere Design dahinter?
Lösung
Rails verwendet die :through
Option einen anderen Verein zu verweisen, die Sie bereits definiert haben. Ich denke, es tut dies so, dass Sie sauber komplexe Assoziationen einrichten können zunächst, ohne sie zu definieren und Referenzierung sie in der gleichen Zeile.
Betrachten wir zum Beispiel diese (unnötig komplex) Beispiel:
has_many :users, :class_name => 'Person', :foreign_key => 'owner_id'
has_many :tasks, :through => :users, :class_name 'Job'
Es gibt keinen sauberen Weg, um all diese Informationen inline zum Ausdruck bringen.
Zusätzlich (nicht sicher, ob Sie dies in Ihrer Frage sind impliziert), können Sie explizit beiden Verbände direkt zugreifen. Also, wenn ein Benutzer has_many :tasks
und has_many :milestones, :through => :tasks
, können Sie und wird wollen beide @user.tasks
und @user.milestones
zugreifen zu können.
So ist es nicht nur nützlich für das Gehen durch das, was ist mehr oder weniger eine Join-Tabelle in Ihrem Beispiel (zwei Fremdschlüssel, Zeitstempel und vielleicht ein Attribut oder zwei) - Sie große Modelle haben können, dass Sie eine has_many :through
auf verwenden
Hilft Ihre Frage zu beantworten? Nicht sicher, wie viel davon Sie bereits kennen.