2015-01-28 2 views
1

Mongoose에서 개체를 찾아 저장하는 도우미 메서드를 추가하려면 어떻게해야합니까? 한 친구가 도우미 방법을 사용하라고 말했지만 하루가 지나면 일할 수 없습니다. 난 항상 (노드가 컴파일 할 때 ... 나는 그것을 실행하기 전에) findOne() 또는 save() 중 하나가 존재하지 않거나 그 다음 콜백이 정의되어 있지 않습니다 말하는 오류가 나타납니다, _schema.statics을몽구스 도우미 메서드에는 findOne 메서드가 없습니다?

내가 해봤 _schema.methods을 ... 아무것도 당신이 때문에 this와 사용의 문제로 실행하는 생각

var email = require('email-addresses'), 
    mongoose = require('mongoose'), 
    strings = require('../../utilities/common/strings'), 
    uuid = require('node-uuid'), 
    validator = require('validator'); 

var _schema = new mongoose.Schema({ 
    _id: { 
     type: String, 
     trim: true, 
     lowercase: true, 
     default: uuid.v4 
    }, 
    n: {     // Name 
     type: String, 
     required: true, 
     trim: true, 
     lowercase: true, 
     unique: true, 
     index: true 
    } 
}); 

//_schema.index({ 
// d: 1, 
// n: 1 
//}, { unique: true }); 

_schema.pre('save', function (next) { 

    if (!this.n || strings.isNullOrWhitespace(this.n)){ 
     self.invalidate('n', 'Domain name required but not supplied'); 
     return next(new Error('Domain name required but not supplied')); 
    } 

    var a = email.parseOneAddress('[email protected]' + this.n); 
    if (!a || !a.local || !a.domain){ 
     self.invalidate('n', 'Name is not valid domain name'); 
     return next(new Error('Name is not valid domain name')); 
    } 

    next(); 
}); 

_schema.statics.validateForSave = function (next) { 

    if (!this.n || strings.isNullOrWhitespace(this.n)){ 
     return next(new Error('Domain name required but not supplied')); 
    } 

    var a = email.parseOneAddress('[email protected]' + this.n); 
    if (!a || !a.local || !a.domain){ 
     return next(new Error('Name is not valid domain name')); 
    } 

    next(); 
} 

_schema.statics.findUnique = function (next) { 

    this.validateForSave(function(err){ 
     if (err){ return next(err); } 
     mongoose.model('Domain').findOne({ n: this.n }, next); 
     //this.findOne({ n: this.n }, next); 
    }); 
} 

_schema.statics.init = function (next) { 

    this.findUnique(function(err){ 
     if (err){ return next(err); } 
     this.save(next); 
    }); 
} 

var _model = mongoose.model('Domain', _schema); 

module.exports = _model; 
+0

몽구스가'_id'를 생성하는 대신'_id'를'uuid'로 설정하는 이유가 있습니까? – EmptyArsenal

+0

나는 순차적 또는 거의 순차적 인 ID를 원하지 않기 때문에. –

+0

@ G.Deward : 죄송합니다. 나는 노력했다. 조건에 따르면, 내가 편집 한 경우에만 현상금을 할당 할 수 있습니다. 불행히도, 두 명의 동료가 그것을 (@bulk과 @dleh) 거부했다. 그들은 용어가 지정하지 않은 것을 알고 있거나 내 주석을 읽지 않았다. http://stackoverflow.com/help/bounty –

답변

0

... 작동하지 않습니다. 새 기능을 입력 할 때마다 this의 컨텍스트가 변경됩니다. this에 대한 자세한 내용은 mdn에서 확인할 수 있습니다.

또한 콜백은 아무 것도 몽구스 메서드로 전달할 수 없습니다. 예를 들어 내가 만들 수 있다면 가장 기본적인 방법 II는 다음 할 것 "저장"

_schema.statics.basicSearch = function(uniqueName, next) { 
    var query = {n: uniqueName}; 

    _model.findOne(query, function(err, myUniqueDoc) { 
    if (err) return next(err); 
    if (!myUniqueDoc) return next(new Error("No Domain with " + uniqueName + " found")); 
    next(null, myNewDoc); 
    }); 
} 
: 나는 다음을 사용 고유 한 문서에 대한 도메인 콜렉션을 검색하기를 원한다면 지금

_schema.statics.basicCreate = function(newDocData, next) { 
    new _model(newDocData).save(next); 
} 

0

몽구스는 무슨 일을위한 built in validations 있습니다

_schema.path("n").validate(function(name) { 
    return name.length; 
}, "Domain name is required"); 


_schema.path("n").validate(function(name) { 

    var a = email.parseOneAddress("[email protected]" + name); 
    if (!a || !a.local || !a.domain) { 
     return false; 
    } 
    return true; 
}, "Name is not a valid domain name"); 

그것은 부울을 반환합니다. false이면 명시된 메시지로 .save() 콜백에 오류를 전달합니다. 고유성 확인하는 경우 : 당신이 findOne() 콜백 내부 문서에 액세스 할 수 있도록

_schema.path("n").validate(function(name, next) { 

    var self = this; 

    this.model("Domain").findOne({n: name}, function(err, domain) { 
     if (err) return next(err); 

     if (domain) { 
      if (self._id === domain._id) { 
       return next(true); 
      } 
      return next(false); 
     } 
     return next(true); 
    }); 
}, "This domain is already taken"); 

현재 self = this을 사용하고 있습니다. 이름이 존재하고 찾은 결과가 문서 자체가 아닌 경우 false이 콜백에 전달됩니다.

나는 .statics.methods 문서에서 작동, 모델에 작동 명확히하기 위해

_schema.statics, _schema.methods을 시도했습니다. 젠은 그래서 여기에 방법의 예는, 정적의 좋은 예를 주었다

_schema.methods.isDotCom = function() { 

    return (/.com/).test(this.n); 
} 

var org = new Domain({n: "stuff.org"}); 
var com = new Domain({n: "things.com"}); 

org.isDotCom(); // false 
com.isDotCom(); // true 

의견 : 그것은 몽구스가 검증을 가지고 깔끔한하지만 그것이 무슨 일이 일어나고 잊어하는 것은 매우 쉽습니다. 또한 다른 곳에서 다른 유효성 검사를 사용하는 동안 앱의 한 영역에서 일부 유효성 검사를 수행 할 수 있습니다. 매번 똑같은 일을해야한다는 것을 확실히 알지 못하면 그 대부분을 사용하지 않아도되고 절대하지 않아도됩니다.

방법/통계는 다른 이야기입니다. 확인을해야 할 때마다 정규식 테스트를 작성하는 대신 isDotCom()으로 전화하는 것이 매우 편리합니다. 그것은 당신에게 타이핑을 줄이고 코드를 더 읽기 쉽게 만드는 단일하고 간단한 작업을 수행합니다. 불리언 검사에 메소드를 사용하면 가독성이 높아집니다. findByName (Zane 's basicSearch)과 같은 통계를 정의하면 반복적으로 간단한 쿼리를 수행한다는 것을 알게되면 매우 좋습니다.

몽구스를 핵심 기능이 아닌 유틸리티로 취급하십시오.

관련 문제