CampbellSoftwareSolutions / mongoose-id-validator

Mongoose plug in to validate ObjectID references point to valid existing documents.
Other
47 stars 26 forks source link

mongoose-id-validator does not appear to work on encapsulated objects #4

Closed andersje closed 9 years ago

andersje commented 9 years ago

I have a datastructure which is defined thus:

var productSchema = new mongoose.Schema({ name: String, users: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true }], });

var userSchema = new.mongoose.Schema({ username: { type: String, required: true, }, });

/* next piece of code */

badProductBadUser = { name: 'this should not work', users: [ { user_id: 'deadbeef667', }, ], }

/* above product values succeed, when I believe they should not */

Does this make sense?

martin-css commented 9 years ago

I'm not sure that you are using the validator correctly. I can only go on your code snippet and appreciate that your actual production/test code may be different.

The purpose of the validator is to check that ID values in one document that refer to another document that actually exists. If you are saving users in a separate collection from products and wish to make sure that ID references are to valid users then this is for you.

However, if you are saving the user as an embedded object in the same document then there is no need for this plugin.

You seem to be creating an arbitrary object inside the array of references which does not match the user schema and does not have a _id field. Hence this will not be checked by mongoose-id-validator.

Please see below as a tested example of validation which does work.

//Define schemas
var productSchema = new mongoose.Schema({
    name: String,
    users: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User',
        required: true
    }]
});
productSchema.plugin(validator);

var userSchema = new mongoose.Schema({
    username: {
        type: String,
        required: true
    }
});

//Create models
var User = mongoose.model('User', userSchema);
var Product = mongoose.model('Product', productSchema);

//Create test model instances
var user = new User({username: 'deadbeef667'});
var badProductBadUser = new Product({
    name: 'this should not work',
    users: [user]
});

//Attempt validation. Should fail because user object has never been saved to DB.
badProductBadUser.validate(function (err) {
    err.should.property('name', 'ValidationError');
    err.errors.should.property('users');
    done();
});

If you feel that there is an issue, please give further details. Ideally some test code that illustrates your example of not working would be great.

andersje commented 9 years ago

it looks like estanley beat me to the punch with explaining the issue -- we've been tracking the same issue here, and his PR actually fixed it in our code. I'll close this issue, as it's now resolved :)