Forum: Rails-ES me matan las relaciones n a n

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Aitor (Guest)
on 2007-06-07 22:17
ando bastante liado con este tipo de relaciones ya que no se cual es la
mejor manera de tratar con ellas.

1. por un lado  la relación entre las tablas se puede realizar (ejemplo
de usuarios y grupos)
modelo grupos
  has_and_belongs_to_many :usuarios

modelo usuario
  has_and_belongs_to_many :grupos

y una tabla intermedia usuario_grupos con usuario_id y grupo_id

2. otra forma de relacionarlas ya que estoy con REST es la que he usado
y según he leído en un post de la lista seria tratando la pertenencia
con un modelo mas que seria usuario_grupo
modelo grupo
  has_many : usuariogrupos
  has_many :users, :through => : usuariogrupos

modelo usuario
  has_many :usuariogrupos
    has_many :grupos, :through => : usuariogrupos

modelo usuario_grupo
  belongs_to :usuario
   belongs_to :grupo

¿Cuando es mejor usar una forma y cuando otra?

Con la segunda forma al hacer por ejemplo
  @usuariosgrupos = UsuarioGrupo.find( :all )

   @usuariosgrupos.each do |u|
    Usuario.find( u.usuario_id.nombre )
    Grupo.find( u.grupo_id.nombre )

¿esto no cargaría en exceso la base de datos ya que son muchas
consultas?
¿no se podria hacer un find del modelo usuario_grupo y obtener ya todos
los datos?

otro inconveniente que me he encontrado a sido a la hora de eliminar una
pertenencia ya que la tabla usuario_grupos no contiene un id automatico
no se puede hacer un usuario_grupo_path( id ), :method => :delete
¿esto como se puede solucionar?

Vaya liada y rollo que he soltado y que de preguntas, espero haberme
explicado bien,

Muchas gracias por la ayuda.
Un saludo.
Aitor.
Rafael G. (Guest)
on 2007-06-08 13:24
(Received via mailing list)
Aitor escribió:
>
>   has_many :usuariogrupos
>     has_many :grupos, :through => : usuariogrupos
>
> modelo usuario_grupo
>   belongs_to :usuario
>    belongs_to :grupo
>
> ¿Cuando es mejor usar una forma y cuando otra?
>
Siguiendo con tus modelos:

                M:N
Usuario  ---<>---- Grupo

Con el método 1(HABTM) sólo podrás almacenar la pertenencia de usuarios
a grupos o viceversa, sin ninguna información extra a parte de la que te
proporcione el usuario o el grupo.

Si necesitaras por ejemplo saber la fecha de entrada de los usuarios en
los grupos la relación sería algo tal que así:

                M:N
Usuario ---<>---- Grupo
                  |
                  *Fecha

(Siendo fecha un atributo de la tabla M-N que relaciona  Usuario y
Grupo.)

Entonces en este caso sí que necesitarías el método 2 (through).


Resumiendo:
    Si solo necesitas saber que hay relación entre 2 modelos puedes usar
HABTM.
    Si necesitas almacenar información extra en la tabla "intermedia"
through.

Saludos!

--
Rafael Garcia Ortega

Prueba gratis nuestro nuevo producto GASTOSgem
(http://www.gastosgem.com)
Rafael G. (Guest)
on 2007-06-08 13:27
(Received via mailing list)
>                 M:N
> Usuario ---<>---- Grupo
>                   |
>                   *Fecha
>
> (Siendo fecha un atributo de la tabla M-N que relaciona  Usuario y Grupo.)
>
Lo especifiqué debajo con el comentario por si acaso no se veía bien y
efectivamente no se vio bien.
El atributo fecha saldría de los <>

--
Rafael Garcia Ortega

Prueba gratis nuestro nuevo producto GASTOSgem
(http://www.gastosgem.com)
aitor (Guest)
on 2007-06-08 15:59
gracias por la explicación,
al final lo estoy realizando con la segunda forma comentada usando
:through y añadiendo un id autonumerico a la tabla intermedia para así
poder usar rest.

un saludo.
Manuel González Noriega (Guest)
on 2007-06-08 16:14
(Received via mailing list)
On 08/06/07, aitor <removed_email_address@domain.invalid> wrote:
> gracias por la explicación,
> al final lo estoy realizando con la segunda forma comentada usando
> :through y añadiendo un id autonumerico a la tabla intermedia para así
> poder usar rest.
>

Si es así, es más elegante que el modelo "intermedio" tenga un nombre
más apropiado que usuariogrupo, como por ejemplo "pertenencia" Así
creas "pertenencias", editas "pertenencias", etc.

En Latinoamérica dirían "membresía", que a mi me suena muy bien también ;)

--
Manuel, que
piensa que eres una excelente persona y medra en torno a
http://simplelogica.net y/o http://simplelogica.net/logicola/
Recuerda comer mucha fruta y verdura.
Emilio T. (Guest)
on 2007-06-12 02:18
(Received via mailing list)
On 6/7/07, Aitor <removed_email_address@domain.invalid> wrote:
>
> y una tabla intermedia usuario_grupos con usuario_id y grupo_id

El correcto nombre seria grupos_usuarios ambos en plural y puestos en
orden alfabetico.

>     has_many :grupos, :through => : usuariogrupos
>    @usuariosgrupos.each do |u|
>     Usuario.find( u.usuario_id.nombre )
>     Grupo.find( u.grupo_id.nombre )
>
> ¿esto no cargaría en exceso la base de datos ya que son muchas
> consultas?
> ¿no se podria hacer un find del modelo usuario_grupo y obtener ya todos
> los datos?

Si queres traer todos los datos con relaciones incluidas tenes que
usar :include. Por ejemplo:
cats=Category.find :all, :include => :products

Ahi realiza una consulta donde trae las categorias y a la vez los
productos relacionados con esas categorias.

>
> otro inconveniente que me he encontrado a sido a la hora de eliminar una
> pertenencia ya que la tabla usuario_grupos no contiene un id automatico
> no se puede hacer un usuario_grupo_path( id ), :method => :delete
> ¿esto como se puede solucionar?

Si te referis a que cuando borres un elemento de una clase borres las
dependencias tambien eso se puede especificar con :dependent.

>
> Vaya liada y rollo que he soltado y que de preguntas, espero haberme
> explicado bien,
>
> Muchas gracias por la ayuda.
> Un saludo.
> Aitor.

Te explico a mi entender:

Cuando vos tenes 2 tablas las cuales estan en una relacion n x n,
surge una tabla en el medio que tiene los id y eso que veo que ya
entendes. Esa tabla posee solo los ids y el nombre es como te
explique.

Esa tabla en tu modelo no existe, es solo una tabla que va a guardar
relaciones y lo mantiene rails por detras de la escena. La tabla sera
usada para hacer joins.

Ahora suponiendo que vos tenes una tabla que ademas de relaciones 2
tablas con sus ids tiene otro atributo por ejemplo: usuarios y
empresas, n a n pero ademas en un usuario tiene un rol en una empresa,
esta 3ra tabla pasa a ser parte de tu modelo porque ademas de
relacionar 2 tablas tiene un atributo. La tabla esta por ejemplo
podria ser empleos.

Hay un caso bien explicado en "Agile development..."

Saludos!
This topic is locked and can not be replied to.