Block saving of repeated data

3

How do I check the controller, if an email already exists in the mongoose database and thus, does the lock save it again?

    
asked by anonymous 10.07.2015 / 22:07

2 answers

2

The best way to do this is to establish a unique index in the field. This can be done by adding unique: true to the field definition in the schema:

var UserSchema = new mongoose.Schema({
  email: { type: String, unique: true }
  // ...
});

You can read about this feature here: link

And about unique indexes in MongoDB here: link

Saves and updates will fail without further changes to your code when duplicate values are being entered. Vitor's response is valid, but subject to race conditions (and if a user with a duplicate email is inserted between find and save ?).

You can then treat the error that MongoDB will return in duplicate values:

// Ou dê match no código do erro (E11000)
if(_.contains(err.message, 'duplicate key error') &&
   _.contains(err.message, 'users.$email')) {
  err = new Error('This email is already registered');
  err.status = 400;
}

throw err;
    
01.09.2015 / 00:45
1

You can make a validator that only allows the inclusion or change of a user if the email address is not exists in collection:

UserSchema.path('email').validate(function (email, done) {
    var User = mongoose.model('User')

    // Check only when it is a new user or when email field is modified
    if (this.isNew || this.isModified('email')) {
        User.find({ email: email }).exec(function (err, users) {
            done(!err && users.length === 0)
        })
    } else done(true);
}, 'Email já registrado.');

controller check the error after trying to save the user:

/* Create new user. */
exports.new = function(req, res) {
  var user = new User(req.body);
  user.save(function(err){
    if (err & err.errors.email) 
      return res.status(400).json({message: err.errors.email.type});
    else 
      return res.sendStatus(201);
    }
  });
};
    
14.07.2015 / 21:24