Jak has_many :through association działa w praktyce
On 3 stycznia, 2022 by adminKiedy zaczynasz pracować z Railsami i ActiveRecord, może być ciężko owinąć głowę wokół koncepcji has_many :through associations, i co ważniejsze, jak mogą być one użyte w twojej aplikacji Railsowej.
„Powiedzmy, że mam grupę, członka, członkostwo… jak właściwie UŻYĆ tego w moich modelach, kontrolerach i widokach?”
„Używam relacji has_many :through, która wydaje się działać. Potrzebuję teraz formularza, który mogę renderować, aby użytkownicy dołączali lub opuszczali grupę.”
Po pierwsze, powinieneś być dość pewny, że relacja has_many :through jest dobrym wyborem dla twojego projektu aplikacji. Zakładając, że tak jest, oto jak możesz zastosować to w praktyce.
Powiedzmy, że budujesz aplikację z Użytkownikami i Grupami, i chcesz zbudować formularz, w którym dany użytkownik może dołączyć lub opuścić dowolną grupę. Zdecydowałeś się powiązać swoich użytkowników i grupy poprzez tabelę Membership.
Twoje modele są zbudowane w ten sposób:
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
Zawsze uważam za pomocne, zanim zacznę pisać moje kontrolery lub widoki, aby przemyśleć to, co chcę osiągnąć i użyć konsoli Rails, aby upewnić się, że jestem na właściwej ścieżce. Innymi słowy, staram się wymyślić cel końcowy, a następnie pracować wstecz, z pomocą konsoli Rails, aby wymyślić moje rozwiązanie.
Więc, biorąc pod uwagę, że chcemy renderować formularz, który pozwala użytkownikowi dołączyć lub opuścić grupę, powinniśmy zadać sobie pytanie, „co to znaczy, aby użytkownik dołączył do grupy?”
Jeśli chodzi o bazę danych, oznacza to w zasadzie, że tabela Membership
będzie miała wiersz z kolumnami user_id
i group_id
odpowiadającymi naszemu użytkownikowi i grupie. Naszym zadaniem jest więc zaaranżowanie takich rzeczy, że kiedy użytkownik kliknie 'submit’ na swoim formularzu, tabela Membership
kończy się nowym wierszem (lub wierszami) z poprawnymi wartościami user_id
i group_id
.
W formularzu/widoku, który renderujemy dla użytkownika, potrzebujemy sposobu, w jaki użytkownik może wybrać grupy, do których chce dołączyć. A w kontrolerze, chcemy wyodrębnić wybory, które użytkownik dokonał w formularzu i użyć tych wyborów do utworzenia nowych wierszy w tabeli Membership
.
Po pierwsze, wyobraź sobie, że masz user_id
i group_id
, jak byś sobie poradził z utworzeniem nowego wiersza w tabeli Membership? ActiveRecord sprawia, że jest to łatwe. To, co chcemy zrobić, to dla danego rekordu User
dodać do niego „członkostwo”, tak, że kiedy powiemy @user.groups
, otrzymamy z powrotem listę grup, która zawiera grupę, którą właśnie dodaliśmy. Jeśli zrobisz tak:
#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
Ten fragment kodu automatycznie utworzy nowy wiersz w tabeli Membership z odpowiednimi group_id
i user_id
. I teraz za każdym razem, gdy użyjesz @user.groups
, otrzymasz z powrotem listę grup, które dodałeś. Dla większej pewności, wypróbuj powyższe w swojej konsoli Railsów.
Sprawdź poniższy przewodnik po Railsach, aby uzyskać więcej szczegółów na temat tego, jakie metody ActiveRecord dostarcza ci, gdy używasz has_many :through
.
Założę, że masz jakiś rodzaj uwierzytelniania skonfigurowany w swojej aplikacji, co daje ci dostęp do metody current_user
. Będziemy potrzebowali tej metody, aby uzyskać nasz user_id
, poprzez proste wywołanie current_user.id
. Kiedy już masz swojego użytkownika (z czymś w rodzaju @user = User.find(current_user.id)
), możesz użyć powyższego kodu, aby dodać grupy.
Następnym pytaniem jest, jak napisać swój widok tak, aby przekazywał wartości group_id
do kontrolera?
To, jak napiszesz swój widok, będzie w pełni zależało od przepływu, przez który mają przejść użytkownicy i innych czynników w twojej aplikacji. Załóżmy, że zdecydujesz się dostarczyć użytkownikowi listę pól wyboru z listą grup, do których może dołączyć lub z których może odejść. Oto prosty sposób by to osiągnąć:
<% Group.all.each do |group| %> <%= check_box_tag "user", group.id, @user.group_ids.include?(group.id) %> <%= group.name %> <br /><% end %>
Użycie check_box_tag
prawdopodobnie wymaga wyjaśnienia.
Pierwszy parametr "user"
mówi Railsom by zgrupowały wszystkie checkboxy z tym ID razem i przekazały je do kontrolera jako Array. Oznacza to, że w twoim kontrolerze, możesz zrobić params
i otrzymać ładną Rubinową tablicę wszystkich group_ids
, które wybrał użytkownik.
Ostatni parametr po prostu zapewnia, że każda Grupa, do której należy użytkownik jest sprawdzana kiedy formularz jest renderowany.
Powyżej powinieneś zacząć używać has_many :through w swojej aplikacji Railsowej, ale w zależności od tego co robi twoja aplikacja, jestem prawie pewien, że napotkasz problemy, które nie są ujęte w tym poście. Więc jeśli nadal utknąłeś, sprawdź następujące rzeczy:
1) Sprawdź ten niesamowity rzut Railsów, który zabiera cię przez całą gamę używania has_many :through. Jeśli jeszcze tego nie zrobiłeś, gorąco polecam założenie konta na RailsCasts.
2) Rails ActiveRecord Guide on has_many :through
.
Dodaj komentarz