25

Soy bastante nuevo en Rails, y estoy tratando de hacer una relación HABTM polimórfica. El problema es que tengo tres modelos que quiero relacionar.HABTM Relación polimórfica

El primero es el modelo de evento y luego hay dos tipos de asistentes: usuarios y contactos.

Lo que quiero hacer es poder relacionarme como un asistente tanto con los usuarios como con los contactos. Por lo tanto, lo que tengo en este momento en mi código es:

Evento Modelo

has_and_belongs_to_many :attendees, :polymorphic => true 

Modelo de Usuario

has_and_belongs_to_many :events, :as => :attendees 

Contacto Modelo

has_and_belongs_to_may :events, :as => :attendees 
  1. ¿Cómo debe ser la migración de la tabla HABTM? Estoy un poco confundido y no he encontrado ayuda en eso.
  2. ¿Va a funcionar?

Respuesta

61

No, no puedes hacer eso, no existe una asociación polimórfica has_and_belongs_to_many.

Lo que puedes hacer es crear un modelo intermedio. Probablemente sería algo como esto:

class Subscription < ActiveRecord::Base 
    belongs_to :attendee, :polymorphic => true 
    belongs_to :event 
end 

class Event < ActiveRecord::Base 
    has_many :subscriptions 
end 

class User < ActiveRecord::Base 
    has_many :subscriptions, :as => :attendee 
    has_many :events, :through => :subscriptions 
end 

class Contact < ActiveRecord::Base 
    has_many :subscriptions, :as => :attendee 
    has_many :events, :through => :subscriptions 
end 

De esta manera el modelo de suscripción se comporta como la mesa de enlace en una N: N relación, pero le permite tener el comportamiento polimórfico para el evento.

0

Resolveu parcialmente.

Soluciona el problema dado el marco que tenemos a nuestra disposición, pero agrega complejidad y código "innecesarios". Al crear un modelo intermediario (que llamaré B), y dado que A -> B -> C es "A tiene_muchos B que tienen muchas C", tenemos otro Modelo AR que cargará una implementación más de la clase AR en la memoria una vez que sea cargado, y instanciará con el único propósito de llegar a instancias de C. Siempre puedes decir que si usas la asociación: a través de asociación, no cargas la asociación B, pero entonces te quedará un modelo aún más obsoleto, que solo estará allí para ver pasar la caravana.

De hecho, esta podría ser una característica que falta en Active Record. Lo propondría como una función para agregar, ya que ha sido motivo de preocupación para mí (así es como llegué a este post con la esperanza de encontrar una solución :)).

Cumprimentos

Cuestiones relacionadas