2016-10-25 6 views
2

Wir verwenden geerbte Schemas mit Mongoose-Diskriminator-Funktionalität, die wir gemäß der documentation implementiert haben.Mongoose-Diskriminatoren, instanziieren Dokumente

Durch unsere REST-API möchten wir POST Dokumente der verschiedenen Typen und behandeln die Logik mit einer gemeinsamen Controller-Funktion.

Angenommen, wir haben eine REST Verfahren zum Erstellen eines Dokuments, das entweder GenericEvent von Super-Typ sein kann, oder Untertypen ClickedLinkEvent oder SignedUpEvent (auf das Beispiel aus den oben verknüpften docs folgen). Was ich zur Zeit ist, etwas zu tun wie:

var GenericEventModel = require('GenericEventModel'); 
var ClickedLinkEventModel = require('ClickedLinkEvent'); 
var SignedUpEventModel = require('SignedUpEvent'); 

// REST logic for creating a document of a specific type 
module.exports.createEvent = function(req, res, next) { 
    var modelType = req.params.type; // as provided via REST parameter 
    var Model = getModel(modelType); // get the appropriate model type 
    new Model(req.body).save(next); 
} 

// TODO want to avoid this 
function getMongooseModel(type) { 
    switch (modelType) { 
    case 'GenericEvent': return GenericEventModel; 
    case 'ClickedLinkEvent': return ClickedLinkEventModel; 
    case 'SignedUpEvent': return SignedUpEventModel; 
    // and many more, needs to be extended, every time a new type is added … 
    } 
} 

Nachdem die getMongooseModel Funktion manuell kuratieren, wenn ein neues Modelltyp wird, scheint eher fehleranfällig hinzugefügt, und ich vermute, andere Menschen, die auf dem Code arbeiten werden wird einfach vergessen.

Also, meine Frage: Gibt es eine bestehende Funktion in der Mongoose-API, die mir das geeignete Modell für einen bestimmten Diskriminatorschlüssel geben kann, indem ich alle bekannten Unterschemata ansehe?

Antwort

1

Eine bessere Implementierung sollte sein, ein Objekt anstelle eines Schalters zu verwenden.

var modelMap = { 
    'GenericEvent': GenericEventModel, 
    'ClickedLinkEvent': ClickedLinkEventModel, 
    'SignedUpEvent': SignedUpEventModel 
}; 

function getMongooseModel(type) { 
    return modelList[type]; 
} 

Danach, um Fehler zu vermeiden Sie Mongoose#plugin(fn, [opts]) um das modelMap Objekt zu füllen verwenden können.

Oder Sie können einfach Mongoose#model(name, [schema], [collection], [skipInit]) verwenden.

Definiert ein Modell oder ruft es ab.

So etwas sollte funktionieren:

module.exports.createEvent = function(req, res, next) { 
    var Model = mongoose.model(req.params.type); 
    (new Model(req.body)).save(next); 
} 

Mit einer passenden Erklärung des Modellklasse in Mungo, müssen Modellname Ihre Anfrage Parameter natürlich entsprechen.

var GenericEventModel = mongoose.model('GenericEvent', GenericEventModelSchema); 
+0

Ehrfürchtig. Wusste nicht, dass "Mongoose # Modell" verwendet werden könnte, um ** ein Modell ** zu bekommen. Das scheint genau das zu sein, wonach ich suche! :) Ich werde versuchen und zurückkommen! – qqilihq

+0

Funktioniert perfekt, nochmals vielen Dank! – qqilihq