Como um has_many :através de associação funciona na prática
On Janeiro 3, 2022 by adminQuando você está começando a trabalhar com Rails e ActiveRecord, pode ser difícil envolver sua cabeça no conceito de has_many :através de associações, e mais importante como elas podem ser usadas em seu aplicativo Rails.
“vamos dizer que eu tenho grupo, membro, membros…como eu realmente uso isso nos meus modelos, controladores e views?”
“Eu estou usando um has_many :através de um relacionamento que parece estar funcionando. Agora eu preciso de um formulário que eu possa renderizar para que os usuários entrem ou saiam do grupo.”
Primeiro off, você deve estar razoavelmente confiante que um has_many :através de associação é uma boa escolha para o seu design de aplicação. Assumindo que você está, aqui está como você pode colocá-lo em prática.
Vamos dizer que você está construindo uma aplicação com Usuários e Grupos, e você quer construir um formulário onde um determinado usuário pode entrar ou sair de qualquer grupo. Você escolheu associar seus usuários e grupos através da tabela Membership.
Seu modelos são estruturados assim:
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
Eu sempre acho útil antes de começar a escrever meus controladores ou views, para pensar no que eu quero realizar, e usar o console Rails para garantir que estou no caminho certo. Em outras palavras, eu tento chegar a um objetivo final, e então trabalho para trás com a ajuda do console Rails para descobrir minha solução.
Então, dado que queremos renderizar um formulário que permite a um usuário entrar ou sair de um grupo, devemos nos perguntar, “o que significa ter um usuário entrando em um grupo?”
No que diz respeito à base de dados, significa essencialmente que a tabela Membership
terá uma linha com as colunas user_id
e group_id
correspondentes ao nosso dado utilizador e grupo. Nossa tarefa então é orquestrar coisas como quando o usuário clica em ‘submeter’ no seu formulário, a tabela Membership
termina com uma nova linha (ou linhas) com os corretos user_id
e group_id
valores.
No formulário/visualização que nós renderizamos para o usuário, precisamos de uma maneira pela qual o usuário possa selecionar quais grupos ele quer se juntar. E no controlador, queremos extrair as escolhas que o usuário fez no formulário e usar essas escolhas para criar novas linhas na tabela Membership
tabela.
Primeiro, imagine que você tinha um user_id
e um group_id
, como você iria criar essa nova linha na tabela Membership? O ActiveRecord torna tudo mais fácil. O que queremos fazer é, para um dado User
record, adicionar-lhe uma ‘membership’, para que quando dissermos @user.groups
, tenhamos de volta uma lista de grupos que inclua o grupo que acabámos de adicionar. Se você fizer isso:
#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
Este pedaço de código irá criar automaticamente uma nova linha na tabela de Membros com a direita group_id
e user_id
. E agora sempre que você usar @user.groups
, você receberá de volta uma lista de grupos que você adicionou. Para maior confiança, tente o acima em seu console Rails.
Cheque o guia do Rails abaixo para mais detalhes sobre quais métodos o ActiveRecord fornece quando você usa has_many :through
.
I’m going to assume que você tem algum tipo de autenticação configurado em seu aplicativo, o que lhe dá acesso ao método current_user
. Vamos precisar deste método para obter o nosso user_id
, através de uma simples chamada current_user.id
. Uma vez que você tenha seu usuário (com algo como @user = User.find(current_user.id)
), você pode usar o código acima para adicionar grupos.
A próxima pergunta é, como você escreve sua view de forma que ela passe os valores group_id
para o controlador?
Como você escreve sua view dependerá totalmente do fluxo que você espera que seus usuários passem e outros fatores em sua aplicação. Digamos que você decide fornecer ao seu usuário uma lista de caixas de seleção listando os grupos que eles podem entrar ou sair. Aqui está uma maneira simples de fazer isso:
<% Group.all.each do |group| %> <%= check_box_tag "user", group.id, @user.group_ids.include?(group.id) %> <%= group.name %> <br /><% end %>
O uso de check_box_tag
provavelmente precisa de alguma explicação.
O primeiro parâmetro "user"
diz ao Rails para agrupar todas as checkboxes com esse ID e passá-lo para o controlador como um Array. O que isso significa está no seu controller, você pode fazer params
e obter um bom Ruby Array de todos os group_ids
que o usuário escolheu.
O último parâmetro apenas garante que qualquer grupo ao qual o usuário pertence atualmente é verificado quando o formulário é renderizado.
O acima deve fazer você usar has_many :through no seu aplicativo Rails, mas dependendo do que o seu aplicativo faz eu tenho certeza que você vai encontrar problemas que não são cobertos neste post. Então se você ainda estiver preso, confira o seguinte:
1) Confira este incrível elenco de Rails que o leva através de toda a gama de uso de has_many :through. Se você ainda não o fez, eu recomendo que você tenha uma conta no RailsCasts.
2) Guia ActiveRecord do Rails em has_many :through
Deixe uma resposta