Reputation: 9220
I would like to create a validator for Mongoose that causes .save()
to fail if the row already exists. At the moment my validators look somewhat like this (coffee):
model.schema.path('email').validate (email) =>
return email? and email.length > 0
, 'BLANK_EMAIL'
However, they are synchronous and therefore having a @model.find
checking for length inside there would not work. I was considering using something like the pseudo-code below but I don't know if it's possible, or if there's a much easier method that will follow the same mongoose validation pattern I'm already using. Thanks!
model.schema.pre 'save', (next) ->
self = @
model.find {email: self.email}, (err, rows) ->
if rows.length
# This bit is the pseudo-code:
model.schema.path('email').validate false
next()
Upvotes: 0
Views: 101
Reputation: 13500
http://mongoosejs.com/docs/api.html#schematype_SchemaType-validate
schema.path('email').validate(function (value, respond) {
mongoose.model("user").count({email: this.email}, function(err, num) {
respond(!(err || num)); // validation failed
})
}, '{PATH} failed validation.');
You might want to check for email: this.email, _id: {$ne: this._id}
, depending on your needs. The above snippet is untested, but you get the general idea.
Validators with two arguments (value & a callback) run asynchronously, as opposed to validators with a single argument (value), which must return a boolean. The callback receives a boolean which indicates that the error should be thrown. AFAIK, you can't pass an Error
instance to the callback.
Upvotes: 1