52

Rails tiene una asociación has_one :through que ayuda a establecer una asociación uno a uno con un tercer modelo pasando por un segundo modelo. ¿Cuál es el uso real de eso, además de hacer una asociación de acceso directo, que de otro modo sería un paso adicional de distancia.Rails has_one: a través de la asociación

Tomando este ejemplo de los rieles guide:

class Supplier < ActiveRecord::Base 
    has_one :account 
    has_one :account_history, :through => :account 
end 

class Account < ActiveRecord::Base 
    belongs_to :supplier 
    has_one :account_history 
end 

class AccountHistory < ActiveRecord::Base 
    belongs_to :account 
end 

podría permitirnos hacer algo como:

supplier.account_history 

que de otro modo se llegaría como:

supplier.account.history 

si se trata de solo para un acceso más simple, entonces técnicamente podría haber una asociación de uno a uno t conecta un modelo con un enésimo modelo que pasa por modelos n-1 para facilitar el acceso. ¿Hay algo más que me falta además del atajo?

Respuesta

47
  1. lógica, bien puede ser que suene un poco débil para esto, pero sería lógico decir que "tengo un proveedor que tenga una cuenta conmigo, quiero ver todo el historial de la cuenta de este proveedor ", por lo que tiene sentido para mí poder acceder directamente al historial de la cuenta del proveedor.

  2. Eficiencia, esto para mí es la razón principal por la que usaría :through, simplemente porque este emite una instrucción de combinación en lugar de llamar proveedor, y luego cuenta y luego account_history. notó la cantidad de llamadas a la base de datos?

    • usando :through, 1 llamada para obtener el proveedor, 1 llamada para obtener account_history (carriles automáticamente utiliza :join para recuperar a través de la cuenta)

    • usando asociación normal, 1 llamada para obtener proveedor, 1 llamada a obtener la cuenta, y 1 llamada para obtener account_history

Eso es lo que pienso =) espero que ayude!

+2

Creo que el argumento de la lógica es bastante válido. Suena más natural decir, obtener el historial de cuenta de este proveedor y no el historial de la cuenta del proveedor. Muy sutil, pero aún más fácil de recordar, teniendo en cuenta la filosofía de Ruby/Rails de oraciones fluidas en lugar de código. Sé que podemos ver las consultas DB reales que se emiten, pero, ¿especifica Rails cómo estas llamadas a métodos se traducirían a SQL? – Anurag

+10

Esto también evita violar la Ley de Demeter. –

+2

@TomCrayford, realmente no veo cómo funciona. ¿Esto no hace que la relación sea menos directa? –

6
  • Asociación inversa: tener en cuenta la facilidad de uso de miembros del grupo situación clásica. Si un usuario puede ser miembro en muchos grupos, entonces un grupo tiene muchos miembros o usuarios, y un usuario tiene muchos grupos. Pero si el usuario solo puede ser miembro de un grupo, el grupo todavía tiene muchos miembros: class User has_one :group, :through => :membership pero class Group has_many :members, :through => memberships. El modelo intermedio membership es útil para realizar un seguimiento de la relación inversa.

  • Capacidad de expansión: una relación fácil has_one :through puede ampliarse y extenderse a una relación has_many :through

7

Me sorprende que nadie ha tocado Asociación Objetos.

Una relación has_many (o has_one) :through facilita el uso de la association object pattern que es cuando se tienen dos cosas relacionadas entre sí, y que relación misma tiene atributos (es decir, una fecha en que se hizo la asociación o cuando expira).

Esto es considered by some para ser una buena alternativa al has_and_belongs_to_many Ayudante de ActiveRecord. El razonamiento detrás de esto es que es muy probable que necesites cambiar la naturaleza de la asociación o agregarla, y cuando estés dentro de un par de meses en un proyecto, esto puede ser muy doloroso si la relación se estableció inicialmente como a has_and_belongs_to_many (el segundo enlace entra en detalle). Si se configura inicialmente utilizando una relación has_many :through, luego de un par de meses de iniciado el proyecto, es fácil renombrar el modelo de combinación o agregarle atributos, facilitando a los desarrolladores la respuesta a los requisitos cambiantes. Plan para el cambio

Cuestiones relacionadas