2012-03-30 9 views
0

Angenommen, ich arbeite an einem MongoMapper Klasse, die wie folgt aussieht:Verwenden Sie im MongoMapper optionale Tasten oder einen Auffangschlüssel?

class Animal 
    include MongoMapper::Document 

    key :type, String, :required => true 
    key :color, String 
    key :feet, Integer 
end 

Jetzt möchte ich eine Flügelspannweite des Vogels speichern. Wäre es besser, dies zu schreiben, auch wenn es für viele Dokumente irrelevant ist und fühlt sich ein bisschen unsauber:

key :wingspan, Float 

Oder das, obwohl es sich um ein indescriptive ist catch-all, die wie ein Hack fühlt:

key :metadata, Hash 

Es scheint, als ob der: -Metadaten-Ansatz (für den es Präzedenzfälle in dem Code gibt, den ich vererbe) für das Mongo-Dokument als Ganzes fast überflüssig ist: Beide sollen schemalose Buckets von Schlüssel-Wert-Paaren sein.

Allerdings scheint es auch, dass das Hinzufügen von Tier-spezifischen Schlüsseln ein rutschiger Hang zu einem ziemlich hässlichen Modell ist.

Alle Alternativen (eine Bird-Unterklasse erstellen)?

Antwort

1

MongoMapper speichert keine Schlüssel, die nil sind. Wenn Sie also key :wingspan definiert haben, werden nur die Dokumente gespeichert, die diesen Schlüssel tatsächlich speichern.

Wenn Sie sich entscheiden, den Schlüssel nicht zu definieren, können Sie ihn trotzdem mit my_bird[:wingspan] = 23 setzen. (Der [] Aufruf wird tatsächlich automatisch einen Schlüssel für Sie definieren; ähnlich, wenn ein Dokument von MongoDB mit einem Schlüssel zurückkommt, der nicht explizit definiert ist, wird ein Schlüssel für ihn und alle Dokumente dieser Klasse definiert - es ist ein Fehler zu definieren es für die ganze Klasse, aber seit nil Schlüssel sind nicht gespeichert, es ist nicht so sehr ein Problem.)

Wenn Vogel hat auch ein eigenes Verhalten (wahrscheinlich tut es), dann macht eine Unterklasse Sinn. Für Vögel und Tiere würde ich diesen Weg nehmen, da jeder Vogel ein Tier ist. MongoDB ist viel schöner als ActiveRecord für Single Table/Single Collection Vererbung, weil Sie keine Milliarden Migrationen benötigen und Ihr Code macht deutlich, welche Attribute mit welchen Klassen gehen.

+0

Interessant - Ich habe gerade herum gespielt und bestätigt, dass undefinierte Schlüssel tatsächlich gespeichert und abgerufen werden. Also, was ist der Punkt der Definition von Schlüsseln in Ihrem Modell überhaupt (abgesehen von den Standardeinstellungen und: erforderlich => wahr)? – Ross

+0

Nun, der 'Schlüssel'-Aufruf ist 'def my_attr' und' def my_attr = ', also kannst du' bird.wingspan' machen. Bei nicht definierten Schlüsseln wird 'key' erst aufgerufen, wenn ein Objekt _aus der Datenbank_ geladen wird. Wenn Ihre Anwendung also kalt ist (zB Tests), wird' Bird.new.wingspan' einen 'NoMethodError' auslösen, da' key: pingspan' hasn ist Es ist noch nicht geschehen. –

1

Es ist schwierig, eine gute Antwort zu geben, ohne zu wissen, wie Sie die Datenbank in Zukunft erweitern und wie Sie die Informationen, die Sie speichern, verwenden möchten. Wenn Sie eine große Anzahl von Vögeln speichern und eine Spannweite zusammenfassen möchten, wäre die Flügelspannweite hilfreich, auch wenn sie für andere Tiere nicht verwendet würde. Wenn Sie beabsichtigen, beliebige zufällige Informationen für jedes bekannte Tier zu speichern, gibt es zu viele Möglichkeiten, dies in einem Schema zu verfolgen, und der Metadaten-Ansatz wäre nützlicher.