Estoy tratando de entender qué has_many :through
es y cuándo usarlo (y cómo). Sin embargo, no lo entiendo. Estoy leyendo Beginning Rails 3 y probé en Google, pero no puedo entender.
fuente
Estoy tratando de entender qué has_many :through
es y cuándo usarlo (y cómo). Sin embargo, no lo entiendo. Estoy leyendo Beginning Rails 3 y probé en Google, pero no puedo entender.
Digamos que tiene dos modelos: User
y Group
.
Si desea que los usuarios pertenezcan a grupos, puede hacer algo como esto:
class Group < ActiveRecord::Base
has_many :users
end
class User < ActiveRecord::Base
belongs_to :group
end
¿Qué sucede si desea realizar un seguimiento de metadatos adicionales en torno a la asociación? Por ejemplo, cuando el usuario se unió al grupo, o ¿cuál es el rol del usuario en el grupo?
Aquí es donde hace que la asociación sea un objeto de primera clase:
class GroupMembership < ActiveRecord::Base
belongs_to :user
belongs_to :group
# has attributes for date_joined and role
end
Esto introduce una nueva tabla y elimina la group_id
columna de la tabla del usuario.
El problema con este código es que tendría que actualizar cada vez que use la clase de usuario y cambiarla:
user.groups.first.name
# becomes
user.group_memberships.first.group.name
Este tipo de código apesta, y hace que la introducción de cambios como este sea dolorosa.
has_many :through
te ofrece lo mejor de ambos mundos:
class User < ActiveRecord::Base
has_many :groups, :through => :group_memberships # Edit :needs to be plural same as the has_many relationship
has_many :group_memberships
end
Ahora puede tratarlo como algo normal has_many
, pero obtenga el beneficio del modelo de asociación cuando lo necesite.
Tenga en cuenta que también puede hacer esto con has_one
.
Editar: facilitando la adición de un usuario a un grupo
def add_group(group, role = "member")
self.group_associations.build(:group => group, :role => role)
end
user
modelo para agregar el grupo. Algo así como la edición que acabo de hacer. Espero que esto ayude.user.groups << group
? ¿O todo lo maneja esta asociación?Digamos que tienes estos modelos:
Un automóvil
has_one :engine
Un motor
belongs_to :car
Un motor
has_many :pistons
Pistón
belongs_to :engine
Un coche
has_many :pistons, through: :engine
pistón
has_one :car, through: :engine
Esencialmente, está delegando una relación de modelo a otro modelo, por lo que en lugar de tener que llamar
car.engine.pistons
, simplemente puede hacercar.pistons
fuente
Tablas de unión de ActiveRecord
has_many :through
y lashas_and_belongs_to_many
relaciones funcionan a través de una tabla de unión , que es una tabla intermedia que representa la relación entre otras tablas. A diferencia de una consulta JOIN, los datos se almacenan en una tabla.Diferencias prácticas
Con
has_and_belongs_to_many
, no necesita una clave principal y accede a los registros a través de las relaciones ActiveRecord en lugar de a través de un modelo ActiveRecord. Por lo general, utiliza HABTM cuando desea vincular dos modelos con una relación de muchos a muchos.Utiliza una
has_many :through
relación cuando desea interactuar con la tabla de unión como un modelo Rails, completa con claves primarias y la capacidad de agregar columnas personalizadas a los datos unidos. Esto último es particularmente importante para los datos que son relevantes para las filas unidas, pero que en realidad no pertenecen a los modelos relacionados, por ejemplo, almacenar un valor calculado derivado de los campos en la fila unida.Ver también
En A Guide to Active Record Associations , la recomendación dice:
fuente