First of all, this doesn't help.
Let's say, we have a User model:
const schema = new mongoose.Schema({
active: { type: Boolean },
avatar: { type: String }
});
const User = mongoose.model('User', schema);
When we update it (set an avatar):
// This should pass validation
User.update({ _id: id }, { $set: { avatar: 'user1.png' } });
We want to validate it based on current (or changed) active
attribute value.
Case #1
active
isfalse
- we should not be able to set avatar - it should not pass the validation
Case #2
active
istrue
- we should be able to set avatar - it should pass the validation
Ideas
- Use a custom validator
const schema = new mongoose.Schema({
active: { type: Boolean },
avatar: { type: String, validate: [validateAvatar, 'User is not active'] }
});
function validateAvatar (value) {
console.log(value); // user.avatar
console.log(this.active); // undefined
}
So this will not work as we don't have an access to active
field.
- Use pre "validate" hook
schema.pre('validate', function (next) {
// this will never be called
});
This hook doesn't work with update
method.
- Use pre "update" hook
schema.pre('update', function (next) {
console.log(this.active); // undefined
});
This will not work for us as it doesn't have an access to model fields.
- Use post "update" hook
schema.post('update', function (next) {
console.log(this.active); // false
});
This one works, but in terms of validation is not quite good choice, as the function is being called only when model was already saved.
Question
So is there a way to validate the model based on several fields (both saved in DB and new ones) before saving it, while using model.update()
method?
As a summary:
- Initial user object
{ active: false, avatar: null }
- Update
User.update({ _id: id }, { $set: { avatar: 'user1.png' } });
- Validation should have an access to
{ active: false, avatar: 'user1.png' }
- If validation fails, changes should not be passed to DB