Jak funguje asociace has_many :through v praxi
On 3 ledna, 2022 by adminKdyž začínáte pracovat s Rails a ActiveRecord, může být těžké pochopit koncept asociace has_many :through a hlavně to, jak ji lze použít v aplikaci Rails.
„řekněme, že mám skupinu, člena, členství… jak to pak vlastně POUŽÍT v modelech, kontrolérech a pohledech?“
„Používám vazbu has_many :through, která se zdá být funkční. Nyní potřebuji formulář, který mohu vykreslit, aby se uživatelé mohli připojit ke skupině nebo ji opustit.“
Především byste si měli být dostatečně jisti, že asociace has_many :through je pro návrh vaší aplikace dobrou volbou. Předpokládejme, že ano, a zde je návod, jak ji můžete uplatnit v praxi:
Řekněme, že vytváříte aplikaci s uživateli a skupinami a chcete vytvořit formulář, ve kterém se daný uživatel může připojit k libovolné skupině nebo ji opustit. Rozhodli jste se uživatele a skupiny propojit prostřednictvím tabulky Membership.
Vaše modely jsou strukturovány takto:
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
Vždycky mi pomůže, když si předtím, než začnu psát kontroléry nebo pohledy, promyslím, čeho chci dosáhnout, a pomocí konzoly Rails se ujistím, že jsem na správné cestě. Jinými slovy, snažím se přijít a s konečným cílem, a pak pracovat zpětně s pomocí konzole Rails, abych přišel na své řešení.
Takže, vzhledem k tomu, že chceme vykreslit formulář, který umožní uživateli připojit se ke skupině nebo ji opustit, měli bychom si položit otázku: „Co to znamená, aby se uživatel připojil ke skupině?“
Z hlediska databáze to v podstatě znamená, že v tabulce Membership
bude řádek se sloupci user_id
a group_id
odpovídajícími našemu danému uživateli a skupině. Naším úkolem je pak zařídit věci tak, aby když uživatel klikne na „odeslat“ ve svém formuláři, skončila tabulka Membership
s novým řádkem (nebo řádky) se správnými hodnotami user_id
a group_id
.
Ve formuláři/pohledi, který vykreslujeme pro uživatele, potřebujeme způsob, kterým uživatel může vybrat, ke kterým skupinám se chce připojit. A v kontroléru chceme extrahovat volby, které uživatel provedl ve formuláři, a použít tyto volby k vytvoření nových řádků v tabulce Membership
.
Představte si, že byste měli user_id
a group_id
, jak byste postupovali při vytváření tohoto nového řádku v tabulce Členství? ActiveRecord vám to usnadní. To, co chceme udělat, je pro daný záznam User
přidat k němu „členství“, takže když řekneme @user.groups
, dostaneme zpět seznam skupin, který obsahuje právě přidanou skupinu. Pokud uděláte toto:
#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
Tento kus kódu automaticky vytvoří nový řádek v tabulce Členství se správným group_id
a user_id
. A nyní kdykoli použijete @user.groups
, dostanete zpět seznam přidaných skupin. Pro větší jistotu si výše uvedené vyzkoušejte v konzoli Rails.
Podívejte se do níže uvedené příručky Rails, kde najdete další podrobnosti o tom, jaké metody vám ActiveRecord poskytuje při použití has_many :through
.
Předpokládám, že máte ve své aplikaci nastaven nějaký typ ověřování, který vám poskytuje přístup k metodě current_user
. Tuto metodu budeme potřebovat k získání našeho user_id
, a to prostřednictvím jednoduchého volání current_user.id
. Jakmile máte uživatele (s něčím jako @user = User.find(current_user.id)
), můžete použít výše uvedený kód k přidání skupin.
Další otázka zní: Jak napíšete svůj pohled tak, aby předával hodnoty group_id
kontroléru?
Jak napíšete svůj pohled, bude zcela záviset na toku, který očekáváte, že uživatelé projdou, a na dalších faktorech vaší aplikace. Řekněme, že se rozhodnete poskytnout uživateli seznam zaškrtávacích políček se seznamem skupin, ke kterým se může připojit nebo které může opustit. Zde je jednoduchý způsob, jak toho dosáhnout:
<% Group.all.each do |group| %> <%= check_box_tag "user", group.id, @user.group_ids.include?(group.id) %> <%= group.name %> <br /><% end %>
Použití check_box_tag
asi potřebuje vysvětlení:
První parametr "user"
říká systému Rails, aby seskupil všechna zaškrtávací políčka s tímto ID a předal je kontroléru jako pole (Array). To znamená, že ve svém kontroléru můžete provést params
a získat pěkný Ruby Array všech group_ids
, které uživatel vybral.
Poslední parametr pouze zajišťuje, že při vykreslování formuláře bude zaškrtnuta jakákoli skupina, do které uživatel aktuálně patří.
Výše uvedené by vám mělo pomoci s použitím has_many :through ve vaší aplikaci Rails, ale v závislosti na tom, co vaše aplikace dělá, jsem si téměř jistý, že narazíte na problémy, které v tomto příspěvku nejsou popsány. Pokud tedy stále tápete, podívejte se na následující:
1) Podívejte se na tento úžasný Rails cast, který vás provede celou škálou použití has_many :through. Pokud jste tak ještě neučinili, vřele vám doporučuji, abyste si na RailsCastu zřídili účet.
2) Rails ActiveRecord Guide on has_many :through
.
Napsat komentář