Tengo una clase de artículo con los siguientes atributos:
itemId,name,weight,volume,price,required_skills,required_items
.
Como los dos últimos atributos serán multivalorizados, los eliminé y creé nuevos esquemas como:
itemID,required_skill
( itemID
es la clave externa, itemID and required_skill
es la clave primaria).
Ahora, estoy confundido sobre cómo crear / usar esta nueva tabla. Estas son las opciones que me vinieron a la mente:
1) La relación entre Items y Required_skills es de uno a muchos, por lo que puedo crear una clase RequiredSkill, que pertenece a Item, que a su vez tiene n RequiredSkills. Entonces puedo hacer Item.get(1).requiredskills
. Esto me parece más lógico y me proporciona métodos y consultas como:
sugar.components.create :raw_material => water.name
sugar.components.create :raw_material => sugarcane.name
sugar.components
sugar.components.count
2) Dado que required_skills bien puede considerarse como constantes (ya que se parecen a las reglas), puedo ponerlas en una base de datos hash o gdbm u otra tabla sql y consultar desde allí, lo que no prefiero.
Mi pregunta es: ¿hay algo así como una tabla sin modelo en datamapper, donde datamapper es responsable de la creación e integridad de la tabla y me permite consultarla en forma de datamapper, pero no requiere una clase, como puedo hacerlo en sql ?
Resolví mi problema usando la primera forma: creé una nueva clase para cada proceso de normalización (que aparece como una asociación de uno a muchos arriba). Sin embargo, soy nuevo en la programación orientada a objetos y no sé si crear una nueva clase para cada normalización de este tipo es la forma habitual de hacerlo en datamapper, o más bien un hack? Esto, y si hay una mejor manera de hacerlo, es lo que me gustaría saber.
@JustinC
Al releer las asociaciones de datamapper.org varias veces, ahora veo que datamapper ciertamente requiere clases separadas para las uniones. Entonces respondiste mi pregunta. Sin embargo, desde que Robert Harvey colocó la recompensa, siento la responsabilidad de esperar un poco más por una respuesta sobre una forma dinámica.
Tu código se quejó con Cannot find the child_model Container for Item in containers
. Logré que funcione con el segundo ejemplo de asociación autorreferencial como se muestra a continuación (poniendo aquí como referencia a otros):
class Item
class Link
include DataMapper::Resource
storage_names[:default] = "requirement_links"
belongs_to :require, "Item", :key => true
belongs_to :required, "Item", :key => true
end
include DataMapper::Resource
property :id, Serial
property :name, String, :required => true
has n, :links_to_required_items, "Item::Link", :child_key => [:require_id]
has n, :links_to_requiring_items, "Item::Link", :child_key => [:required_id]
has n, :required_items, self,
:through => :links_to_required_items,
:via => :required
has n, :requiring_items, self,
:through => :links_to_requiring_items,
:via => :require
def require(others)
required_items.concat(Array(others))
save
self
end
def unrequire(others)
links_to_required_items.all(:required => Array(others)).destroy!
reload
self
end
end
Entonces puedo hacer:
jelly = Item.get :name => "Jelly"
sugar = Item.get :name => "Sugar"
jelly.require sugar
para requerir artículos y:
jelly.required_items.each { |i|; puts i.name }
para enumerar los requisitos, que son realmente geniales.
Después de leer su respuesta, veo que todavía tengo que normalizar más mi esquema de base de datos. Para ser honesto, no veo el punto de definir la relación entre materias primas y productos como autorreferencial. Quiero decir, si ese fuera un pequeño programa, ciertamente usaría un hash {:jelly => ":sugar => 3, :water => 5"}
para reflejar los artículos y cantidades requeridas, de acuerdo con el principio de YAGNI. Hacerlo como en la primera opción ya me proporciona consultas y métodos tan simples como los proporcionados por la asociación autorreferencial. (Sin embargo, debo admitir que se parece más a un procedimiento almacenado que a una llamada a un objeto).
Entonces, ¿le importaría explicar los beneficios de usar una asociación autorreferencial, que es difícil de entender / implementar para mí, en comparación con mi enfoque más simple? Soy nuevo en OOP y me pregunto si soy una especie de submodelo.
fuente
has n, :items, :through => Inventory
enfoque, obtuve consultas más eficientes en comparación con un enfoque similar al hash. ¿Qué depurador usaste por cierto?