Dan Moldovan
Dan Moldovan

Reputation: 3591

Mongoose async call to another model makes validation impossible

I have two mongoose Schemas which look like this:

var FlowsSchema = new Schema({
    name: {type: String, required: true},
    description: {type: String},
    active: {type: Boolean, default: false},
    product: {type: Schema.ObjectId, ref: 'ClientProduct'},
    type: {type: Schema.ObjectId, ref: 'ConversionType'},
});

this schema is then embedded in a parent schema that looks like this:

var ClientCampaignSchema = new Schema({
    name: {type: String, required: true},
    description: {type: String},
    active: {type: Boolean, default: false},
    activeFrom: {type: Date},
    activeUntil: {type: Date},
    client: {type: Schema.ObjectId, ref: 'Client', required: true},
    flows: [FlowsSchema]
});

and

var ConversionTypeSchema = new Schema({
    name: {type: Schema.Types.Mixed, required: true},
    requiresProductAssociation: {type: Boolean, default: false}
});

As you can see my FlowsSchema holds a reference towards the ConversionType. What I want to do is only allow a product to be added to a flow, if the associated conversiontype's 'requiresProductAssociation' is equal to true. Unfortunately, wether I use validators or middleware this would mean making a call to mongoose.model('ConversionType') which is automatically async and messes things up. What do?

p.s. if there would be a way to store a reference to that requiresProductAssociation boolean rather than the entire object that would be great because I wouldn't need to make the async call to that model anymore, but I don't know if that's possible.

Upvotes: 1

Views: 449

Answers (1)

JohnnyHK
JohnnyHK

Reputation: 312045

The docs for SchemaType#validate describe how to perform asynchronous validation for cases like this. An asynchronous validator function receives two arguments, the second being a callback function you call to asynchronously report whether the value is valid.

That lets you implement this validation as:

FlowsSchema.path('type').validate(function(value, respond) {
    mongoose.model('ConversionType').findById(value, function(err, doc) {
        respond(doc && doc.requiresProductAssociation);
    });
});

Upvotes: 1

Related Questions