Pregunta

Hola a todos, tengo algo de un requisito interesante para mi proyecto. Necesito una relación has_one donde es o bien una clase u otra, pero sin herencia. Podría salirse con la herencia si es la única manera, pero los dos registros asociados tienen datos completamente diferentes y no están relacionadas en absoluto.

Lo que necesito averiguar es algo así como lo siguiente.

# 1. Foo never belongs to anything.
# 2. Foo MUST have one assigned sub-record for validity.
# 3. Foo can only have either Bar or Baz assigned.
# 4. Bar and Baz have only ONE common property, and aren't
#    related in either data or implementation.

class Foo < ActiveRecord::Base
  # Attributes: id, name, value
  has_one :assignment, :foreign_key => 'assigned_to', :readonly => true
          # Could really use an :object_type for has_one here...
end

class Bar < ActiveRecord::Base
  # Attributes: name,...
end

class Baz < ActiveRecord::Base
  # Attributes: name,...
end

Donde Foo tiene una asignación, de tipo ya sea Bar o Baz; que sólo comparten una columna común, lo que tal vez puede hacer que un objeto principal de eso. Sin embargo, si hago que heredan de un objeto común (cuando los datos que contienen realmente se naranjas y manzanas) deben hago una mesa para el registro? Puedo tal vez me fuera con él si el registro es un registro abstracto, pero los niños no lo son?

supongo que por ahora se puede ver mi dificultad. Soy bastante nuevo en RoR, pero amante de ella hasta ahora. Estoy seguro de que hay una forma de evitar esto, pero me aspen si no puedo entender lo que es.

¿Fue útil?

Solución

Usted está tratando de modelar algo que no encaja en el paradigma de base de datos relacional. Todas las referencias en SQL tienen un origen y un destino.

Fwiw, asociaciones polimórficas es también un anti-patrón porque rompe esta regla. Debe ser un indicio de que se trata de un diseño rompe cuando el documentación dice que debe renunciar a una restricción de integridad referencial para hacer que funcione!

Es necesario Foo tener dos relaciones has_one : una para bar y uno de Baz. A continuación, aplicar un poco de lógica de clase para tratar de asegurar sólo una referencia se rellena en cualquier instancia de Foo. Es decir, de las referencias a Bar y Baz, uno debe tener un valor y el otro debe ser nulo, pero esto es algo por su código para comprobar y hacer cumplir.

Otros consejos

Tal vez una manera de hacer esto, es crear asociaciones a-uno tiene en Foo, para Bar y Baz. A continuación, crear un método llamado misiones y asignación =, que puede ser la única manera de acceder bar y Baz. Puede comprobar cuál de los dos has_ones no es nula en el método get y volver que uno. En el método de asignación, puede-y comprueba cuál es el tipo de la variable pasada y establecer la correcta relación tiene uno a ese objeto y configure el otro a cero. Eso debería cubrir todas sus bases sin ser demasiado complicado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top