2012-02-23 13 views
18

Lo que quiero decir es que si tengo dos modelos, conectados por una asociación has_and_belongs_to_many, ¿puedo almacenar otros datos en la tabla de unión para cada asociación? Es decir, los datos adicionales no formarían parte de un solo registro en ninguna de las tablas, sino en lugar de la conexión entre ellos.Rieles: ¿es posible agregar un atributo adicional a una asociación has_and_belongs_to_many?

Mis modelos actuales son los siguientes:

class Part < ActiveRecord::Base 
    has_and_belongs_to_many :assemblies 
    has_and_belongs_to_many :packages 
    belongs_to :user 

    validates :name, :user_id, :presence => true 
end 

class Package < ActiveRecord::Base 
    has_and_belongs_to_many :parts 
    belongs_to :user 
end 

Así que el punto es que cada parte está disponible en muchos paquetes y cada paquete tiene diferentes partes. Lo que quiero agregar es una cantidad. Esa no sería la cantidad de cada parte, sino de cada paquete de cada parte.

No puedo encontrar cómo hacerlo en ActiveRecord. Si no estuviera usando rails/activerecord, solo agregaría una columna de cantidad a la tabla de unión que relaciona las partes con los paquetes. Obviamente podría hacer este cambio en una migración, pero ¿cómo accedería al valor usando ActiveRecord?

Respuesta

25

Respuesta corta no, no se puede con una relación HABTM. Solo está pensado para relaciones simples de muchos a muchos.

Deberá usar una relación has_many: through. En este escenario, creará un modelo de unión (PartPackage) donde podrá definir los atributos adicionales que necesita.

class Part < ActiveRecord::Base 
    has_many :part_packages 
    has_many :packages, :through => :part_packages 

    has_and_belongs_to_many :assemblies 
    belongs_to :user 

    validates :name, :user_id, :presence => true 
end 

class PartPackage < ActiveRecord::Base 
    belongs_to :part 
    belongs_to :package 
end 

class Package < ActiveRecord::Base 
    has_many :part_packages 
    has_many :parts, :through => :part_packages 
    belongs_to :user 
end 
14

Hay una diferencia clave entre has_many :through y has_and_belongs_to_many los carriles de guía explica las diferencias entre las dos opciones con mayor detalle, sin embargo, si desea agregar los datos que describe la relación a continuación, utilizar has_many :through y se puede tener acceso al modelo eso une a los dos.

Esto es lo que has_many: a través de miradas como: Credit to the Rails guide.

+0

¿Qué programa usaste para hacer un bosquejo tan bonito? – MicFin

+0

(mi referencia interna n. ° 485) ¿Cómo se actualiza la cita_fecha al mismo tiempo que se crea el registro completo y también cómo se lee el atributo adicional más adelante? Solo puedo hacerlo a través de Appointment.find_by ............. pero me gustaría algo menos raro como patient.appointsments.first.appointment_date – ace

+0

Puede actualizar el atributo appointment_date de la siguiente manera: belongs_to: physician ,: touch =>: cita_fecha. – hashrocket

0

En realidad, esto es posible.

1) añadir una clave cantidad a los packages_parts tabla de unión

2) Agregar a su modelo de pieza

has_and_belongs_to_many :packages, -> { select("packages.*, 
packages_parts.quantity") } 

Ahora usted puede hacer part.packages[0].quantity, por ejemplo.

Lo que hace esto es decirle a Rails que busque la clave de cantidad siempre que obtenga los paquetes para una pieza específica.

(Usted puede hacer lo mismo para su modelo de paquete si usted quiere hacer package.parts.first.quantity así - sólo hay que poner esto en el modelo de paquetes también, en sustitución de 'paquetes' con 'partes')

Más información: https://ducktypelabs.com/using-scope-with-associations/

Cuestiones relacionadas