Come funziona in pratica un’associazione has_many :through
Il Gennaio 3, 2022 da adminQuando iniziate a lavorare con Rails e ActiveRecord, può essere difficile capire il concetto di associazioni has_many :through, e soprattutto come possono essere usate nella vostra applicazione Rails.
“diciamo che ho un gruppo, un membro, un’appartenenza… come faccio ad utilizzarli nei miei modelli, controller e viste?”
“Sto usando una relazione has_many :through che sembra funzionare. Ora ho bisogno di un modulo che posso rendere per far sì che gli utenti si uniscano o lascino il gruppo.”
Prima di tutto, dovreste essere ragionevolmente sicuri che un’associazione has_many :through sia una buona scelta per il design della vostra applicazione. Supponendo che tu lo sia, ecco come puoi metterla in pratica.
Diciamo che stai costruendo un’applicazione con Utenti e Gruppi, e vuoi costruire un modulo dove un dato utente può unirsi o lasciare qualsiasi gruppo. Avete scelto di associare i vostri utenti e gruppi attraverso la tabella Membership.
I vostri modelli sono strutturati così:
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
Trovo sempre utile, prima di iniziare a scrivere i miei controller o le mie viste, pensare a ciò che voglio realizzare, e usare la console Rails per assicurarmi di essere sulla strada giusta. In altre parole, cerco di arrivare ad un obiettivo finale, e poi lavoro a ritroso con l’aiuto della console Rails per capire la mia soluzione.
Quindi, dato che vogliamo rendere un modulo che permetta ad un utente di unirsi o lasciare un gruppo, dovremmo chiederci, “cosa significa far unire un utente ad un gruppo?”
Per quanto riguarda il database, significa essenzialmente che la tabella Membership
avrà una riga con le colonne user_id
e group_id
corrispondenti al nostro dato utente e gruppo. Il nostro compito è quindi quello di orchestrare le cose in modo tale che quando l’utente fa clic su “invia” nel suo modulo, la tabella Membership
finisce con una nuova riga (o righe) con i valori user_id
e group_id
corretti.
Nel modulo/visualizzazione che rendiamo per l’utente, abbiamo bisogno di un modo in cui l’utente possa selezionare quali gruppi vuole unirsi. E nel controller, vogliamo estrarre le scelte che l’utente ha fatto nel modulo e usare quelle scelte per creare nuove righe nella tabella Membership
.
Prima di tutto, immaginate di avere un user_id
e un group_id
, come fareste a creare quella nuova riga nella tabella Membership? ActiveRecord lo rende facile. Quello che vogliamo fare è, per un dato record User
, aggiungere un ‘membership’ ad esso, in modo che quando diciamo @user.groups
, otteniamo una lista di gruppi che include il gruppo che abbiamo appena aggiunto. Se fate così:
#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
Questo pezzo di codice creerà automaticamente una nuova riga nella tabella Membership con i giusti group_id
e user_id
. E ora, ogni volta che userete @user.groups
, otterrete una lista di gruppi che avete aggiunto. Per maggiore sicurezza, provate quanto sopra nella vostra console Rails.
Guardate la guida Rails qui sotto per maggiori dettagli su quali metodi ActiveRecord vi fornisce quando usate has_many :through
.
Suppongo che abbiate qualche tipo di autenticazione impostata nella vostra applicazione, che vi dà accesso al metodo current_user
. Avremo bisogno di questo metodo per ottenere il nostro user_id
, attraverso una semplice chiamata current_user.id
. Una volta che avete il vostro utente (con qualcosa come @user = User.find(current_user.id)
), potete usare il codice di cui sopra per aggiungere i gruppi.
La prossima domanda è: come scrivete la vostra vista in modo che passi i valori group_id
al controller?
Come scrivete la vostra vista dipenderà interamente dal flusso che vi aspettate che gli utenti passino e da altri fattori della vostra app. Diciamo che decidete di fornire al vostro utente una lista di caselle di controllo che elencano i gruppi a cui possono unirsi o lasciare. Ecco un modo semplice per farlo:
<% Group.all.each do |group| %> <%= check_box_tag "user", group.id, @user.group_ids.include?(group.id) %> <%= group.name %> <br /><% end %>
L’uso di check_box_tag
probabilmente ha bisogno di qualche spiegazione.
Il primo parametro "user"
dice a Rails di raggruppare tutte le checkbox con questo ID e passarle al controller come Array. Ciò significa che nel vostro controller, potete fare params
e ottenere un bel Ruby Array di tutti i group_ids
che l’utente ha scelto.
L’ultimo parametro assicura solo che ogni gruppo a cui l’utente appartiene attualmente sia controllato quando il modulo viene reso.
Quanto sopra dovrebbe farvi andare avanti con l’uso di has_many :through nella vostra applicazione Rails, ma a seconda di ciò che fa la vostra applicazione sono abbastanza sicuro che incontrerete problemi che non sono trattati in questo post. Quindi, se siete ancora bloccati, date un’occhiata a quanto segue:
1) Guardate questo incredibile cast di Rails che vi porta attraverso l’intera gamma di utilizzo di has_many :through. Se non l’avete ancora fatto, vi consiglio vivamente di farvi un account su RailsCasts.
2) Rails ActiveRecord Guide on has_many :through
Lascia un commento