Ho una classe Item con i seguenti attributi:
itemId,name,weight,volume,price,required_skills,required_items
.
Poiché gli ultimi due attributi saranno multivalore, li ho rimossi e creato nuovi schemi come:
itemID,required_skill
( itemID
è una chiave esterna, itemID and required_skill
è la chiave primaria.)
Ora, sono confuso su come creare / utilizzare questa nuova tabella. Ecco le opzioni che mi sono venute in mente:
1) La relazione tra articoli e Required_skills è uno-a-molti, quindi potrei creare una classe RequiredSkill, che appartiene all'elemento, che a sua volta ha n RequiredSkills. Quindi posso fare Item.get(1).requiredskills
. Mi sembra molto logico e mi fornisce metodi e query come:
sugar.components.create :raw_material => water.name
sugar.components.create :raw_material => sugarcane.name
sugar.components
sugar.components.count
2) Poiché require_skills può essere considerato come una costante (poiché assomigliano alle regole), posso inserirli in un database hash o gdbm o un'altra tabella sql e interrogare da lì, cosa che non preferisco.
La mia domanda è: c'è qualcosa come una tabella modellistica in datamapper, in cui il datamapper è responsabile della creazione e dell'integrità della tabella e mi permette di interrogarlo in modalità datamapper, ma non richiede una classe, come posso fare in sql?
Ho risolto il mio problema utilizzando il primo modo: ho creato una nuova classe per ogni processo di normalizzazione (che appare come associazione uno a molti sopra). Tuttavia, io sono nuovo alla programmazione orientata agli oggetti e non so se la creazione di una nuova classe per ciascuna di tali normalizzazioni sia il solito modo di farlo in datamapper, o piuttosto un hack? Questo, e se c'è un modo migliore per farlo, è quello che mi piacerebbe sapere.
@JustinC
Rileggendo più volte le datamapper.org associazioni , ora vedo che il datamapper richiede certamente classi separate per i join . Quindi hai risposto alla mia domanda. Tuttavia, da quando Robert Harvey ha piazzato la taglia, sento la responsabilità di aspettare un po 'di più per una risposta su un modo dinamico.
Il tuo codice si è lamentato di Cannot find the child_model Container for Item in containers
. Sono riuscito a farlo funzionare con il secondo esempio di associazione autoreferenziale come di seguito (mettendo qui come riferimento ad altri):
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
Quindi posso fare:
jelly = Item.get :name => "Jelly"
sugar = Item.get :name => "Sugar"
jelly.require sugar
per richiedere elementi e:
jelly.required_items.each { |i|; puts i.name }
per elencare i requisiti, che sono davvero fantastici.
Dopo aver letto la tua risposta, vedo che devo ancora normalizzare ulteriormente lo schema del mio database. Per essere onesti, non vedo il punto di definire la relazione tra materie prime e prodotti come autoreferenziali. Voglio dire, se quello fosse un programma di piccole dimensioni, certamente userei un hash come {:jelly => ":sugar => 3, :water => 5"}
per riflettere gli articoli e gli importi richiesti, secondo il principio di YAGNI. Farlo come nella prima opzione mi fornisce già query e metodi semplici come quelli forniti dall'associazione autoreferenziale. (Tuttavia, devo ammettere che sembra più una stored procedure piuttosto che una chiamata di metodo a un oggetto.)
Quindi, potrebbe esserti molto utile spiegare i vantaggi dell'uso di un'associazione autoreferenziale, che è difficile da capire / implementare per me, rispetto al mio approccio più semplice? Sono nuovo di OOP e mi chiedo se sono un po 'sottodimensionato.