Hoe een has_many :through associatie in de praktijk werkt
On januari 3, 2022 by adminWanneer je begint te werken met Rails en ActiveRecord, kan het moeilijk zijn om het concept van has_many :through associaties te doorgronden, en belangrijker nog, hoe ze in je Rails-app kunnen worden gebruikt.
“Laten we zeggen dat ik groep, lid, lidmaatschappen … hoe kan ik dan eigenlijk GEBRUIK dit in mijn modellen, controllers en views?”
“Ik ben met behulp van een has_many :door relatie die lijkt te werken. Ik heb nu een formulier nodig dat ik kan renderen om gebruikers de groep te laten joinen of verlaten.”
Op de eerste plaats moet je er redelijk zeker van zijn dat een has_many :through-relatie een goede keuze is voor het ontwerp van je app. Ervan uitgaande dat u dat bent, volgt hier hoe u het in de praktijk kunt brengen.
Laten we zeggen dat u een app bouwt met Gebruikers en Groepen, en dat u een formulier wilt bouwen waarin een bepaalde gebruiker zich bij een willekeurige groep kan aansluiten of deze kan verlaten. Je hebt ervoor gekozen om je gebruikers en groepen te koppelen via de tabel Membership.
Jouw modellen zijn als volgt gestructureerd:
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
Ik vind het altijd nuttig om, voordat ik mijn controllers of views ga schrijven, na te denken over wat ik wil bereiken en de Rails console te gebruiken om er zeker van te zijn dat ik op het juiste pad zit. Met andere woorden, ik probeer te komen met een met een einddoel, en dan terug te werken met behulp van de Rails console om mijn oplossing te achterhalen.
Dus, gezien het feit dat we willen een formulier waarmee een gebruiker toe te treden tot of verlaten van een groep weer te geven, moeten we ons afvragen, “wat betekent het om een gebruiker lid van een groep?”
Voor zover het de database betreft, betekent het in wezen dat de Membership
tabel een rij zal hebben met de user_id
en group_id
kolommen die overeenkomen met onze gegeven gebruiker en groep. Onze taak is dan om de dingen zo te orkestreren dat wanneer de gebruiker op ‘submit’ klikt op zijn formulier, de Membership
tabel een nieuwe rij (of rijen) krijgt met de juiste user_id
en group_id
waarden.
In het formulier/view dat we renderen voor de gebruiker, hebben we een manier nodig waarop de gebruiker kan selecteren bij welke groepen hij zich wil aansluiten. En in de controller willen we de keuzes die de gebruiker in het formulier heeft gemaakt extraheren en die gebruiken om nieuwe rijen in de tabel Membership
te maken.
Vooreerst, stel dat je een user_id
en een group_id
had, hoe zou je dan die nieuwe rij in de tabel Lidmaatschap gaan maken? ActiveRecord maakt het gemakkelijk. Wat we willen doen is, voor een gegeven User
record, er een ‘lidmaatschap’ aan toevoegen, zodat wanneer we @user.groups
zeggen, we een lijst van groepen terugkrijgen die de groep bevat die we zojuist hebben toegevoegd. Als u dit doet:
#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
Dit stukje code zal automatisch een nieuwe rij aanmaken in de tabel Lidmaatschap met de juiste group_id
en user_id
. En nu wanneer u @user.groups
gebruikt, krijgt u een lijst van groepen terug die u hebt toegevoegd. Voor extra vertrouwen, probeer het bovenstaande in je Rails console.
Kijk naar de Rails gids hieronder voor meer details over welke methoden ActiveRecord je biedt wanneer je has_many :through
gebruikt.
Ik ga ervan uit dat je een soort van authenticatie hebt opgezet in je app, die je toegang geeft tot de current_user
methode. We zullen deze methode nodig hebben om onze user_id
te krijgen, via een eenvoudige current_user.id
oproep. Zodra u uw gebruiker hebt (met iets als @user = User.find(current_user.id)
), kunt u de bovenstaande code gebruiken om groepen toe te voegen.
De volgende vraag is, hoe schrijf je je view zodanig dat het de group_id
waarden doorgeeft aan de controller?
Hoe je je view schrijft, hangt volledig af van de stroom die je verwacht dat je gebruikers doorlopen en andere factoren in je app. Laten we zeggen dat u besluit om uw gebruiker te voorzien van een lijst van selectievakjes waarin de groepen die ze kunnen aansluiten of verlaten. Hier is een eenvoudige manier om dat te bereiken:
<% Group.all.each do |group| %> <%= check_box_tag "user", group.id, @user.group_ids.include?(group.id) %> <%= group.name %> <br /><% end %>
Het gebruik van check_box_tag
behoeft waarschijnlijk enige uitleg.
De eerste parameter "user"
vertelt Rails om alle checkboxes met dit ID te groeperen en dit als een Array aan de controller door te geven. Dit betekent dat je in je controller params
kunt doen en een mooie Ruby Array krijgt van alle group_ids
die de gebruiker heeft gekozen.
De laatste parameter zorgt er gewoon voor dat elke groep waartoe de gebruiker op dat moment behoort, wordt gecontroleerd wanneer het formulier wordt weergegeven.
Het bovenstaande zou je op weg moeten helpen met het gebruik van has_many :through in je Rails app, maar afhankelijk van wat je app doet, ben ik er vrij zeker van dat je problemen zult tegenkomen die niet in deze post zijn behandeld. Dus als je nog steeds vastzit, bekijk dan het volgende:
1) Bekijk deze geweldige Rails cast die je meeneemt door het hele scala van het gebruik van has_many :through. Als u nog niet hebt, zou ik sterk aanbevelen dat je jezelf een account op RailsCasts.
2) Rails ActiveRecord Guide op has_many :through
Geef een antwoord