Próbuję utworzyć model użytkownika, który ma unikalną nazwę użytkownika. Oto kod dla tego:

var mongoose = require("mongoose");

var Schema = mongoose.Schema;

var UserSchema = new Schema({
    username: String,
    password: String,
});

UserSchema.virtual("password_confirmation").get(function() {
    return this.pw_conf;
}).set(function(value) {
    this.pw_conf = value;
});

UserSchema.path("username").required(true);
UserSchema.path("password").required(true);

UserSchema.pre("save",function(next, done) {
    var self = this;
    mongoose.models["User"].findOne({username : self.username},function(err, user) {
        if(user) {
            self.invalidate("user","username must be unique");
        }
        done();
    });
    next();
});

UserSchema.pre("save",function(next) {
    if(this.pw_conf !== this.password) {
        next(new Error("Must specify the password confirmation"));
    }
    else {
        next();
    }
});

module.exports = mongoose.model("User",UserSchema);

Testowałem również, aby sprawdzić, czy działa wyjątkowość:

var User = require("./users"),
  mongoose = require("mongoose");
var u = new User();

mongoose.connect('mongodb://localhost/my_database');

u.username = "me";
u.password = "password";
u.password_confirmation = "password";
u.save(function(err) {
    if(err) {
        console.log(err);
    }
    mongoose.disconnect();
});

Problem polega na tym, że nie. Za każdym razem uruchomiłem kod, otrzymuję nowy obiekt. Jestem świadomy, że prawdopodobnie istnieją inne sposoby zapewnienia wyjątkowości, ale chciałbym to zrobić w ten sposób. Czy nie powinienem dzwonić do done po poradzę sobie z wynikiem metody findOne? Czy dzwonię źle next?

24
Geo 9 sierpień 2012, 00:22

4 odpowiedzi

Najlepsza odpowiedź

Aby użyć równoległe oprogramowanie (z {x0}} i done parametry) , Musisz przejść true jako drugi parametr.

Poza tym istnieją dwie możliwości:

Twoja nazwa self.invalidate powinna odwołać się do "username" zamiast "user". Jeśli to go nie naprawi, możesz wyraźnie zawierać rzeczy, przekazując obiekt błędu do done, jeśli chcesz przerwać operację zapisu:

UserSchema.pre("save", true, function(next, done) {
    var self = this;
    mongoose.models["User"].findOne({username: self.username}, function(err, user) {
        if(err) {
            done(err);
        } else if(user) {
            self.invalidate("username", "username must be unique");
            done(new Error("username must be unique"));
        } else {
            done();
        }
    });
    next();
});
29
JohnnyHK 11 kwiecień 2016, 16:44

http://mongoosejs.com/docs/api.html#schematype_schematype-Unique Czy sposób na wyjazd. Wykorzystuje rzeczywiste indeksy mongodb, aby upewnić się, że twoje pole jest wyjątkowe. Nie ma potrzeby oprogramowania pośredniego .pre.

Cieszyć się!

33
rdrey 8 sierpień 2012, 20:51

Jest naprawdę dobra wtyczka dla mangusta, która jest naprawdę łatwa w instalacji i użytkowaniu. Dokumentacja jest doskonała i działa dla mnie po raz pierwszy.

Ale jest problem z ponownym oszczędzaniem.

https://npmjs.org/package/mongoose-Unique-validator.

5
thomas-peter 2 październik 2013, 11:31

Czy uważasz za korzystanie z asynchronicznego walidatora, aby złapać błąd?

UserSchema.path('username').validate(function (value, done) {
  User.count({ username: value }, function (error, count) {
    // Return false if an error is thrown or count > 0
    done(!(error || count));
  });
}, 'unique'); 
3
furf 21 sierpień 2013, 23:49