Ich habe eine Item-Klasse mit folgenden Attributen:
itemId,name,weight,volume,price,required_skills,required_items
.
Da die letzten beiden Attribute mehrwertig sein werden, habe ich sie entfernt und neue Schemata erstellt wie:
itemID,required_skill
( itemID
ist Fremdschlüssel, itemID and required_skill
ist Primärschlüssel.)
Jetzt bin ich verwirrt, wie diese neue Tabelle erstellt / verwendet wird. Hier sind die Optionen, die mir in den Sinn kamen:
1) Die Beziehung zwischen Items und Required_skills ist eins zu viele, daher kann ich eine RequiredSkill-Klasse erstellen, die zu Item gehört und wiederum n RequiredSkills hat. Dann kann ich tun Item.get(1).requiredskills
. Das klingt für mich am logischsten und bietet mir Methoden und Abfragen wie:
sugar.components.create :raw_material => water.name
sugar.components.create :raw_material => sugarcane.name
sugar.components
sugar.components.count
2) Da require_skills durchaus als Konstanten betrachtet werden können (da sie Regeln ähneln), kann ich sie in eine Hash- oder GDBM-Datenbank oder eine andere SQL-Tabelle einfügen und von dort aus abfragen, was ich nicht bevorzuge.
Meine Frage ist: Gibt es so etwas wie eine modelllose Tabelle in Datamapper, in der Datamapper für die Erstellung und Integrität der Tabelle verantwortlich ist und es mir ermöglicht, sie auf Datamapper-Weise abzufragen, aber keine Klasse erfordert, wie ich es in SQL tun kann ?
Ich habe mein Problem auf die erste Weise gelöst: Ich habe für jeden Normalisierungsprozess eine neue Klasse erstellt (die oben als Eins-zu-Viele-Zuordnung angezeigt wird). Ich bin jedoch neu in der objektorientierten Programmierung und weiß nicht, ob das Erstellen einer neuen Klasse für jede solche Normalisierung die übliche Methode im Datamapper oder eher ein Hack ist. Dies und ob es einen besseren Weg gibt, dies zu tun, würde ich gerne wissen.
@ JustinC
Die Rereading datamapper.org Verbände mehrmals, jetzt sehe ich , dass DataMapper erfordert sicherlich separate Klassen für Joins. Also hast du meine Frage beantwortet. Seit Robert Harvey das Kopfgeld platziert hat, fühle ich mich jedoch verpflichtet, etwas länger auf eine Antwort über einen dynamischen Weg zu warten.
Ihr Code hat sich beschwert Cannot find the child_model Container for Item in containers
. Ich habe es geschafft, es mit dem zweiten Beispiel einer selbstreferenziellen Assoziation wie unten zum Laufen zu bringen (hier als Referenz für andere):
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
Also kann ich tun:
jelly = Item.get :name => "Jelly"
sugar = Item.get :name => "Sugar"
jelly.require sugar
Gegenstände benötigen und:
jelly.required_items.each { |i|; puts i.name }
Anforderungen aufzulisten, die wirklich toll sind.
Nachdem ich Ihre Antwort gelesen habe, sehe ich, dass ich mein Datenbankschema noch weiter normalisieren muss. Um ehrlich zu sein, sehe ich keinen Sinn darin, die Beziehung zwischen Rohstoffen und Produkten als selbstreferenziell zu definieren. Ich meine, wenn das ein kleines Programm wäre, würde ich sicherlich einen Hash verwenden {:jelly => ":sugar => 3, :water => 5"}
, der die erforderlichen Elemente und Beträge gemäß dem YAGNI-Prinzip widerspiegelt. Wenn ich es wie in der ersten Option mache, bekomme ich bereits Abfragen und Methoden, die so einfach sind wie die, die von der selbstreferenziellen Zuordnung bereitgestellt werden. (Ich muss jedoch zugeben, dass es eher wie eine gespeicherte Prozedur als wie ein Methodenaufruf für ein Objekt aussieht.)
Könnten Sie also etwas dagegen haben, die Vorteile einer selbstreferenziellen Assoziation zu erklären, die für mich im Vergleich zu meinem einfacheren Ansatz schwer zu verstehen / zu implementieren ist? Ich bin neu bei OOP und frage mich, ob ich irgendwie untermodelliert bin.