9

Soy nuevo en los rieles, y estoy tratando de establecer una relación de muchos a muchos en mi proyecto de rieles. Tengo una pequeña estrategia, pero no estoy seguro si es la correcta.Cómo tener una relación de varios a varios en los carriles

Objetivo: Tengo una tabla de usuarios y una tabla de grupos. Los usuarios pueden formar parte de muchos grupos y cada grupo puede tener muchos usuarios.

Estrategia:

  1. Configurar la migración de usuarios a tener nombre: cadena
  2. Configurar la migración de grupo para tener el nombre: cadena
  3. Configurar una migración tabla de unión
  4. Configurar usuario modelo tal que tendría has_and_belongs_to_many: groups
  5. Configure el modelo de grupo de forma que tenga has_and_belongs_to_many: users

¿Esta sería la estrategia correcta? ¡Gracias!

Railcast Resumen de la respuesta: Para aquellos que estén interesados ​​- Railcast sugiere que utilice una has_many: a través de la asociación ya que la estrategia anterior tiene la limitación de que no se puede añadir información extra-relación específica.

la salida: http://kconrails.com/tag/has_many/

Respuesta

14

En primer lugar, supongo, que tienen un usuario-modelo con un campo "Nombre" y un grupo-modelo con un campo "Nombre".

Necesita un modelo entre usuarios y grupos. Digamos que es la agrupación:

rails g model grouping user_name:string group_name:string 

En el grupo-modelo (grouping.rb), que puso:

belongs_to :user 
belongs_to :group 

En la facilidad de uso modelo:

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

Y en el grupo -Modelo:

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

En el archivo _form editar o actualización el perfil de un usuario, que puso:

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

Y, por último, la clase de usuario tiene que saber, qué hacer con la información del formulario. Insertar en 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 elimina los espacios en blanco y downcases todas las palabras, por lo que no tendrá etiquetas redundantes.

Ahora, puede mostrar los grupos de un usuario en el archivo de presentación de su perfil:

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

esperanza, eso ayuda.

+0

¿por qué tenemos: dependiente =>: destruir para agrupaciones? – Karan

+3

porque el usuario ya no estará en el grupo si elimina el usuario o el grupo. – tmaximini

+0

¿Por qué no utilizar la relación ['has_and_belongs_to_many'] (http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association)? Simplificaría todo el proceso si no se requieren campos adicionales en la tabla intermedia. – ferdynator

3

La buena noticia es que esto ya está bien documentado.

Ruby on Rails Guide

Railscast tutorial

+0

Gracias! El Railcast realmente ayudó. – Karan

+0

Gracias, la documentación que mencionaste me pareció muy útil. También me gustó la respuesta @The_Fritz proporcionada porque proporciona un ejemplo conciso. –

Cuestiones relacionadas