猫鼬鉴别器,实例化文档

Mongoose discriminators, instantiate documents

我们使用具有 Mongoose 鉴别器功能的继承模式,我们根据 documentation.

实施

通过我们的 REST API,我们想要 POST 不同类型的文档并使用通用控制器功能处理逻辑。

假设,我们有一个用于创建文档的 REST 方法,它可以是超类型 GenericEvent,或子类型 ClickedLinkEvent,或 SignedUpEvent(遵循示例来自上面链接的文档)。我目前正在做的是:

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 …
  }
}

每当添加新模型类型时都必须手动管理 getMongooseModel 函数似乎很容易出错,我怀疑其他将要处理代码的人会忘记它。

所以,我的问题是:Mongoose API 中是否存在一个函数,它可以通过查看所有已知的子模式为我提供适合给定鉴别器键的模型?

更好的实现应该是使用对象而不是开关。

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

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

之后,为了避免错误,您可以使用 Mongoose#plugin(fn, [opts]) 来填充 modelMap 对象。

或者您可以只使用 Mongoose#model(name, [schema], [collection], [skipInit])

Defines a model or retrieves it.

像这样的东西应该可以工作:

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

在 mongoose 中正确声明您的模型 class,模型名称当然必须与您的请求参数匹配。

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