Ich versuche zu verstehen, was has_many :through
und wann ich es verwenden soll (und wie). Ich verstehe es jedoch nicht. Ich lese Beginning Rails 3 und habe versucht zu googeln, kann es aber nicht verstehen.
quelle
Ich versuche zu verstehen, was has_many :through
und wann ich es verwenden soll (und wie). Ich verstehe es jedoch nicht. Ich lese Beginning Rails 3 und habe versucht zu googeln, kann es aber nicht verstehen.
Angenommen, Sie haben zwei Modelle: User
und Group
.
Wenn Sie möchten, dass Benutzer zu Gruppen gehören, können Sie Folgendes tun:
class Group < ActiveRecord::Base
has_many :users
end
class User < ActiveRecord::Base
belongs_to :group
end
Was ist, wenn Sie zusätzliche Metadaten rund um die Assoziation verfolgen möchten? Zum Beispiel, wenn der Benutzer der Gruppe beigetreten ist oder welche Rolle der Benutzer in der Gruppe spielt?
Hier machen Sie die Assoziation zu einem erstklassigen Objekt:
class GroupMembership < ActiveRecord::Base
belongs_to :user
belongs_to :group
# has attributes for date_joined and role
end
Dadurch wird eine neue Tabelle eingeführt und die group_id
Spalte aus der Benutzertabelle entfernt.
Das Problem mit diesem Code ist, dass Sie jeden anderen Ort, an dem Sie die Benutzerklasse verwenden, aktualisieren und ändern müssen:
user.groups.first.name
# becomes
user.group_memberships.first.group.name
Diese Art von Code ist zum Kotzen und macht das Einführen solcher Änderungen schmerzhaft.
has_many :through
gibt Ihnen das Beste aus beiden Welten:
class User < ActiveRecord::Base
has_many :groups, :through => :group_memberships # Edit :needs to be plural same as the has_many relationship
has_many :group_memberships
end
Jetzt können Sie es wie ein normales behandeln has_many
, aber Sie können das Assoziationsmodell bei Bedarf nutzen.
Beachten Sie, dass Sie dies auch mit tun können has_one
.
Bearbeiten: Erleichtert das Hinzufügen eines Benutzers zu einer Gruppe
def add_group(group, role = "member")
self.group_associations.build(:group => group, :role => role)
end
user
Modell eine Methode hinzufügen, um die Gruppe hinzuzufügen. So etwas wie die Bearbeitung, die ich gerade gemacht habe. Hoffe das hilft.user.groups << group
? Oder wird alles von diesem Verein erledigt?Angenommen, Sie haben diese Modelle:
Ein Auto
has_one :engine
Ein Motor
belongs_to :car
Ein Motor
has_many :pistons
Kolben
belongs_to :engine
Ein
has_many :pistons, through: :engine
Autokolben
has_one :car, through: :engine
Im Wesentlichen delegieren Sie eine Modellbeziehung an ein anderes Modell, sodass
car.engine.pistons
Sie dies einfach tun müssen , anstatt anrufen zu müssencar.pistons
quelle
ActiveRecord-Verknüpfungstabellen
has_many :through
undhas_and_belongs_to_many
Beziehungen funktionieren über eine Verknüpfungstabelle , bei der es sich um eine Zwischentabelle handelt, die die Beziehung zwischen anderen Tabellen darstellt. Im Gegensatz zu einer JOIN-Abfrage werden Daten tatsächlich in einer Tabelle gespeichert.Praktische Unterschiede
Mit
has_and_belongs_to_many
benötigen Sie keinen Primärschlüssel und greifen über ActiveRecord-Beziehungen und nicht über ein ActiveRecord-Modell auf die Datensätze zu. Normalerweise verwenden Sie HABTM, wenn Sie zwei Modelle mit einer Viele-zu-Viele-Beziehung verknüpfen möchten.Sie verwenden eine
has_many :through
Beziehung, wenn Sie mit der Verknüpfungstabelle als Rails-Modell interagieren möchten. Dazu gehören Primärschlüssel und die Möglichkeit, den verknüpften Daten benutzerdefinierte Spalten hinzuzufügen. Letzteres ist besonders wichtig für Daten, die für die verknüpften Zeilen relevant sind, aber nicht wirklich zu den zugehörigen Modellen gehören - beispielsweise zum Speichern eines berechneten Werts, der aus den Feldern in der verknüpften Zeile abgeleitet wird.Siehe auch
In einem Handbuch zu aktiven Datensatzzuordnungen lautet die Empfehlung:
quelle