Wie eine has_many :through Assoziation in der Praxis funktioniert
On Januar 3, 2022 by adminWenn man anfängt, mit Rails und ActiveRecord zu arbeiten, kann es schwierig sein, das Konzept der has_many :through Assoziationen zu verstehen, und noch wichtiger, wie sie in Ihrer Rails-App verwendet werden können.
„Nehmen wir an, ich habe eine Gruppe, ein Mitglied, eine Mitgliedschaft… wie verwende ich das dann in meinen Modellen, Controllern und Ansichten?“
„Ich verwende eine has_many :through Beziehung, die zu funktionieren scheint. Ich brauche jetzt ein Formular, das ich rendern kann, damit Benutzer der Gruppe beitreten oder sie verlassen können.“
Zunächst einmal sollten Sie einigermaßen sicher sein, dass eine has_many :through-Beziehung eine gute Wahl für Ihr App-Design ist.
Angenommen, Sie erstellen eine Anwendung mit Benutzern und Gruppen und möchten ein Formular erstellen, in dem ein bestimmter Benutzer einer beliebigen Gruppe beitreten oder sie verlassen kann. Sie haben sich entschieden, Ihre Benutzer und Gruppen über die Tabelle Membership zu verknüpfen.
Ihre Modelle sind wie folgt strukturiert:
class User < ActiveRecord::Base has_many :memberships has_many :groups, through: :membershipsendclass Group < ActiveRecord::Base has_many :memberships has_many :users, through: :membershipsendclass Membership < ActiveRecord::Base belongs_to :user belongs_to :groupend
Ich finde es immer hilfreich, bevor ich mit dem Schreiben meiner Controller oder Views beginne, darüber nachzudenken, was ich erreichen möchte, und die Rails-Konsole zu verwenden, um sicherzustellen, dass ich auf dem richtigen Weg bin. Mit anderen Worten, ich versuche, mir ein Endziel zu setzen und arbeite dann mit Hilfe der Rails-Konsole rückwärts, um meine Lösung zu finden.
Wenn wir also ein Formular erstellen wollen, das es einem Benutzer ermöglicht, einer Gruppe beizutreten oder sie zu verlassen, sollten wir uns fragen: „Was bedeutet es, wenn ein Benutzer einer Gruppe beitritt?“
In Bezug auf die Datenbank bedeutet dies im Wesentlichen, dass die Tabelle Membership
eine Zeile mit den Spalten user_id
und group_id
enthält, die unserem Benutzer und der Gruppe entsprechen. Unsere Aufgabe besteht dann darin, die Dinge so zu organisieren, dass die Membership
-Tabelle eine neue Zeile (oder mehrere Zeilen) mit den korrekten user_id
– und group_id
-Werten enthält, wenn der Benutzer im Formular auf „Senden“ klickt.
In dem Formular/der Ansicht, das/die wir für den Benutzer rendern, benötigen wir eine Möglichkeit, mit der der Benutzer auswählen kann, welchen Gruppen er beitreten möchte. Und im Controller wollen wir die Auswahl, die der Benutzer im Formular getroffen hat, extrahieren und diese Auswahl verwenden, um neue Zeilen in der Tabelle Membership
zu erstellen.
Stellen Sie sich vor, Sie hätten eine user_id
und eine group_id
, wie würden Sie vorgehen, um diese neue Zeile in der Tabelle „Mitgliedschaft“ zu erstellen? ActiveRecord macht es einem leicht. Wir wollen für einen bestimmten User
-Datensatz eine „Mitgliedschaft“ hinzufügen, so dass wir, wenn wir @user.groups
sagen, eine Liste von Gruppen zurückbekommen, die die Gruppe enthält, die wir gerade hinzugefügt haben. Wenn Sie dies tun:
#assuming @user is your User [email protected] << Group.find(group_id)#if you have a list of group_ids(something like ), you can also do:@user.group_ids << group_ids
Dieses Codestück erstellt automatisch eine neue Zeile in der Tabelle „Mitgliedschaft“ mit den richtigen group_id
und user_id
. Wenn Sie nun @user.groups
verwenden, erhalten Sie eine Liste der von Ihnen hinzugefügten Gruppen zurück. Probieren Sie das in Ihrer Rails-Konsole aus.
Weitere Informationen zu den Methoden, die ActiveRecord Ihnen zur Verfügung stellt, wenn Sie has_many :through
verwenden, finden Sie im Rails-Leitfaden unten.
Ich gehe davon aus, dass Sie in Ihrer Anwendung eine Art von Authentifizierung eingerichtet haben, die Ihnen Zugriff auf die Methode current_user
gibt. Wir benötigen diese Methode, um unsere user_id
über einen einfachen current_user.id
-Aufruf zu erhalten. Sobald Sie Ihren Benutzer haben (mit etwas wie @user = User.find(current_user.id)
), können Sie den obigen Code verwenden, um Gruppen hinzuzufügen.
Die nächste Frage ist, wie Sie Ihre Ansicht so schreiben, dass sie die group_id
-Werte an den Controller weitergibt?
Wie Sie Ihre Ansicht schreiben, hängt ganz von dem Fluss ab, den Ihre Benutzer voraussichtlich durchlaufen werden, sowie von anderen Faktoren in Ihrer Anwendung. Nehmen wir an, Sie möchten Ihrem Benutzer eine Liste von Kontrollkästchen zur Verfügung stellen, in der die Gruppen aufgeführt sind, denen er beitreten oder die er verlassen kann. Hier ist ein einfacher Weg, um das zu erreichen:
<% Group.all.each do |group| %> <%= check_box_tag "user", group.id, @user.group_ids.include?(group.id) %> <%= group.name %> <br /><% end %>
Die Verwendung von check_box_tag
bedarf wahrscheinlich einer Erklärung.
Der erste Parameter "user"
weist Rails an, alle Checkboxen mit dieser ID zu gruppieren und sie als Array an den Controller zu übergeben. Das bedeutet, dass du in deinem Controller params
ein schönes Ruby Array mit allen group_ids
, die der Benutzer ausgewählt hat, erhalten kannst.
Der letzte Parameter stellt nur sicher, dass jede Gruppe, zu der der Benutzer derzeit gehört, überprüft wird, wenn das Formular gerendert wird.
Das oben genannte sollte dich dazu bringen, has_many :through in deiner Rails-App zu verwenden, aber je nachdem, was deine App macht, bin ich mir ziemlich sicher, dass du auf Probleme stoßen wirst, die in diesem Beitrag nicht behandelt werden. Wenn du also immer noch nicht weiterkommst, schau dir Folgendes an:
1) Sieh dir diesen erstaunlichen Rails-Cast an, der dich durch die gesamte Bandbreite der Verwendung von has_many :through führt. Wenn Sie es noch nicht getan haben, empfehle ich Ihnen, sich einen Account bei RailsCasts zuzulegen.
2) Rails ActiveRecord Guide on has_many :through
Schreibe einen Kommentar