Do you want to request a feature or report a bug?
feature
It would be nice to have abstract schemas that you cannot instantiate, and instead must instantiate via discriminators.
var shapeSchema = new Schema({
name: String
}, {
discriminatorKey: "type",
abstract: true // <----
});
var Shape = db.model('Shape', shapeSchema);
var Circle = Shape.discriminator('Circle', new Schema({ radius: Number }));
new Shape()
would be invalid
Shape.create({type: "not a registered discriminator"})
would be invalid
Shape.create({type: "Circle"})
would be valid
new Circle()
would be valid
Shape.find()
would be valid
If you agree that this functionality would be useful, I can try to work on a PR.
Current workaround is to have a helper function used before Shape.create
that makes sure the value for the discriminator key is allowed.
I like the general idea, but how would abstract
work if you set it on a schema you pass to discriminator()
?
how would abstract work if you set it on a schema you pass to discriminator()
I think that should throw an error. (Can you think of a use case?) Unless someone is creating schemas at runtime, that would be a boot-time error that would be easy to spot and remedy.
Yeah that's a fair point, throwing an error seems sane. Can you implement this as a plugin? http://thecodebarbarian.com/2015/03/06/guide-to-mongoose-plugins Should be pretty easy to just throw it in the lib/plugins
folder
@zbjornson Did you ever manage to find time to implement this as a plugin?
@Faibk I haven't had a chance to yet, no. We use a static BaseModel.instantiate
method currently to achieve this effect for now, something like this:
/**
* Returns the model constructor based on the discriminator key __t.
* @param v: object containing at least the discriminator key __t
* @return function Model constructor
*/
Shape.statics.getModel = function (v, cb) {
if (v.__t === undefined) {
return cb(new Error("missing component type for component " + v));
}
if (!(v.__t in mongoose.models)) {
return cb(new Error("'" + v.__t + "' is not a valid Shape type"));
}
var Model = mongoose.model(v.__t);
cb(null, Model);
};
/**
* Creates an instance of the component based on the discriminator key __t.
* @param v: object containing the full model including the discriminator key __t.
* @return Model
*/
Shape.statics.instantiate = function (v, cb) {
Shape.getModel(v, function (e, Ctor) {
if (e) return cb(e);
cb(null, new Ctor(v));
});
};
Something new about abstract schema ? I have exactly the same need than @zbjornson.
Most helpful comment
Yeah that's a fair point, throwing an error seems sane. Can you implement this as a plugin? http://thecodebarbarian.com/2015/03/06/guide-to-mongoose-plugins Should be pretty easy to just throw it in the
lib/plugins
folder