Cum funcționează în practică o asociație has_many :through
On ianuarie 3, 2022 by adminCând începeți să lucrați cu Rails și ActiveRecord, poate fi greu să înțelegeți conceptul de asociații has_many :through și, mai ales, cum pot fi utilizate în aplicația Rails.
„Să spunem că am group, member, memberships… cum pot apoi să UTILIZ acest lucru în modelele, controlorii și vizualizările mele?”
„Folosesc o relație has_many :through care pare să funcționeze. Acum am nevoie de un formular pe care să îl pot reda pentru ca utilizatorii să se alăture sau să părăsească grupul.”
În primul rând, ar trebui să fiți rezonabil de încrezător că o asociere has_many :through este o alegere bună pentru proiectarea aplicației dumneavoastră. Presupunând că sunteți, iată cum o puteți pune în practică.
Să spunem că construiți o aplicație cu Utilizatori și Grupuri și doriți să construiți un formular în care un anumit utilizator poate să se alăture sau să părăsească orice grup. Ați ales să asociați utilizatorii și grupurile prin intermediul tabelului Membership.
Modelurile dvs. sunt structurate astfel:
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
Întotdeauna mi se pare util, înainte de a începe să scriu controlorii sau vizualizările mele, să mă gândesc la ceea ce vreau să realizez și să folosesc consola Rails pentru a mă asigura că sunt pe drumul cel bun. Cu alte cuvinte, încerc să vin cu un obiectiv final și apoi lucrez în sens invers cu ajutorul consolei Rails pentru a-mi găsi soluția.
Atunci, având în vedere că vrem să redăm un formular care permite unui utilizator să se alăture sau să părăsească un grup, ar trebui să ne întrebăm: „ce înseamnă ca un utilizator să se alăture unui grup?”
În ceea ce privește baza de date, înseamnă, în esență, că tabelul Membership
va avea un rând cu coloanele user_id
și group_id
care corespund utilizatorului și grupului nostru dat. Sarcina noastră este de a orchestra lucrurile în așa fel încât, atunci când utilizatorul face clic pe „submit” în formularul său, tabelul Membership
să aibă un nou rând (sau rânduri) cu valorile corecte user_id
și group_id
.
În formularul/vizualizarea pe care o redăm pentru utilizator, avem nevoie de o modalitate prin care utilizatorul să poată selecta grupurile la care dorește să se alăture. Iar în controler, dorim să extragem alegerile pe care utilizatorul le-a făcut în formular și să folosim aceste alegeri pentru a crea noi rânduri în tabelul Membership
.
În primul rând, imaginați-vă că ați avea un user_id
și un group_id
, cum ați proceda pentru a crea acel nou rând în tabelul Membership? ActiveRecord o face ușor. Ceea ce dorim să facem este ca, pentru o anumită înregistrare User
, să adăugăm un „membership” la aceasta, astfel încât, atunci când spunem @user.groups
, să primim înapoi o listă de grupuri care include grupul pe care tocmai l-am adăugat. Dacă faceți acest lucru:
#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
Această bucată de cod va crea automat un nou rând în tabelul Membership cu group_id
și user_id
corecte. Și acum, ori de câte ori veți folosi @user.groups
, veți primi înapoi o listă de grupuri pe care le-ați adăugat. Pentru un plus de încredere, încercați cele de mai sus în consola Rails.
Consultați ghidul Rails de mai jos pentru mai multe detalii despre ce metode vă oferă ActiveRecord atunci când folosiți has_many :through
.
Voi presupune că aveți un anumit tip de autentificare configurat în aplicația dvs., care vă oferă acces la metoda current_user
. Vom avea nevoie de această metodă pentru a obține user_id
noastră, printr-un simplu apel current_user.id
. Odată ce aveți utilizatorul (cu ceva de genul @user = User.find(current_user.id)
), puteți folosi codul de mai sus pentru a adăuga grupuri.
Întrebarea următoare este: cum vă scrieți vizualizarea astfel încât să transmită valorile group_id
către controler?
Cum vă scrieți vizualizarea va depinde în întregime de fluxul prin care vă așteptați ca utilizatorii să treacă și de alți factori din aplicația dumneavoastră. Să presupunem că decideți să oferiți utilizatorului dvs. o listă de căsuțe de selectare care enumeră grupurile la care se poate alătura sau pe care le poate părăsi. Iată un mod simplu de a realiza acest lucru:
<% Group.all.each do |group| %> <%= check_box_tag "user", group.id, @user.group_ids.include?(group.id) %> <%= group.name %> <br /><% end %>
Utilizarea lui check_box_tag
are probabil nevoie de câteva explicații.
Primul parametru "user"
îi spune lui Rails să grupeze toate căsuțele de selectare cu acest ID și să le transmită controlorului sub forma unui Array. Ceea ce înseamnă că în controlerul dvs. puteți face params
și să obțineți un frumos Array Ruby cu toate group_ids
pe care utilizatorul le-a ales.
Ultimul parametru asigură doar că orice Grup din care face parte utilizatorul în prezent este verificat atunci când formularul este redat.
Cele de mai sus ar trebui să vă ajute să începeți să folosiți has_many :through în aplicația dvs. Rails, dar în funcție de ceea ce face aplicația dvs. sunt destul de sigur că veți întâmpina probleme care nu sunt acoperite în această postare. Deci, dacă sunteți încă blocat, verificați următoarele:
1) Consultați acest uimitor casting Rails care vă trece prin întreaga gamă de utilizare a lui has_many :through. Dacă nu ați făcut-o deja, vă recomand să vă faceți un cont pe RailsCasts.
2) Ghidul Rails ActiveRecord despre has_many :through
.
Lasă un răspuns