9

Sono nuovo alle rotaie e sto provando a impostare una relazione molti-a-molti nel mio progetto di rotaie. Ho una piccola strategia, ma non sono sicuro se è il modo corretto.Come avere relazione molti-a-molti in rotaie

Obiettivo: Ho una tabella di utenti e una tabella di gruppi. Gli utenti possono far parte di molti gruppi e ogni gruppo può avere molti utenti.

Strategia:

  1. Impostare la migrazione degli utenti ad avere nome: stringa
  2. Impostare la migrazione Gruppo ad avere nome: stringa
  3. Impostare una migrazione Registrati tavolo
  4. Impostazione utente modello tale che avrebbe has_and_belongs_to_many: groups
  5. Impostare il modello di gruppo in modo che avrebbe has_and_belongs_to_many: users

Questa è la strategia corretta? Grazie!

RailCast Sommario dalla risposta: Per coloro che sono interessati - RailCast suggerisce di usare un has_many: attraverso l'associazione dal momento che la strategia ha la limitazione che non è possibile aggiungere informazioni supplementari specifiche del rapporto di cui sopra.

check-out: http://kconrails.com/tag/has_many/

risposta

14

In primo luogo, presumo, è necessario un modello utente con un campo "nome" e un modello di gruppo con un campo "nome".

È necessario un modello tra utenti e gruppi. Chiamiamolo raggruppamento:

rails g model grouping user_name:string group_name:string 

Nel modello di raggruppamento (grouping.rb), si mette:

belongs_to :user 
belongs_to :group 

del manuale-modello:

has_many :groupings, :dependent => :destroy 
has_many :groups, :through => :groupings 

E nel gruppo -model:

has_many :groupings, :dependent => :destroy 
has_many :users, :through => :groupings 

Nel file _form di modificare o aggiornare il profilo di un utente, si mette:

<div class="field"> 
    <%= f.label :group_names, "Groups" %> 
    <%= f.text_field :group_names %> 
</div> 

E, infine, l'Utente classe deve sapere, che cosa fare con le informazioni dal modulo. Inserire nel user.rb:

attr_writer :group_names 
    after_save :assign_groups 

    def group_names 
    @group_names || groups.map(&:name).join(' ') 
    end 

    private 

    def assign_groups 
    if @group_names 
     self.groups = @group_names.split(/\,/).map do |name| 
     if name[0..0]==" " 
      name=name.strip 
     end 
     name=name.downcase 
     Group.find_or_create_by_name(name) 
     end 
    end 
    end 

assign_groups rimuove gli spazi bianchi e downcases tutte le parole, in modo da non avere i tag ridondanti.

Ora, è possibile mostrare i gruppi per un utente nel file di spettacolo del suo profilo:

<p>Groups: 
    <% @user.groups.each do |group|%> 
    <%= group.name %> 
    <% end %> 
</p> 

Speranza, che aiuta.

+0

perché abbiamo: dependent =>: destroy per i raggruppamenti? – Karan

+3

perché l'utente non sarà più nel gruppo se si elimina l'utente o il gruppo. – tmaximini

+0

Perché non utilizzare la relazione ['has_and_belongs_to_many'] (http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association)? Semplificherebbe l'intero processo se non sono richiesti campi aggiuntivi nella tabella intermedia. – ferdynator

3

La buona notizia è che questo è già ben documentata.

Ruby on Rails Guide

Railscast tutorial

+0

Grazie! Il Railcast ha davvero aiutato. – Karan

+0

Grazie, ho trovato molto utile la documentazione che hai citato. Mi è anche piaciuta la risposta fornita da @The_Fritz perché fornisce un esempio conciso. –