25

我正在使用带有 Mongoose ORM 的 MongoDB 在 Node.js / Express 中构建一个基本博客。

我有一个预“保存”钩子,我想用它来为我自动生成一个博客/想法。这工作得很好,除了我想在继续之前查询是否有任何其他现有帖子具有相同 slug 的部分。

但是,似乎this无法访问 .find 或 .findOne() ,因此我不断收到错误消息。

解决这个问题的最佳方法是什么?

  IdeaSchema.pre('save', function(next) {
    var idea = this;

    function generate_slug(text) {
      return text.toLowerCase().replace(/[^\w ]+/g,'').replace(/ +/g,'-').trim();
    };

    idea.slug = generate_slug(idea.title);

    // this has no method 'find'
    this.findOne({slug: idea.slug}, function(err, doc) {
      console.log(err);
      console.log(doc);
    });

    //console.log(idea);
    next();
  });
4

2 回答 2

63

不幸的是,它没有很好地记录(在Document.js API 文档中没有提到它),但是 Documents 可以通过该字段访问他们的模型constructor- 我一直使用它来记录插件中的内容,这让我可以访问哪个他们所依附的模型。

module.exports = function readonly(schema, options) {
    schema.pre('save', function(next) {
        console.log(this.constructor.modelName + " is running the pre-save hook.");

        // some other code here ...

        next();
    });
});

对于您的情况,您应该能够:

IdeaSchema.pre('save', function(next) {
    var idea = this;

    function generate_slug(text) {
        return text.toLowerCase().replace(/[^\w ]+/g,'').replace(/ +/g,'-').trim();
    };

    idea.slug = generate_slug(idea.title);

    // this now works
    this.constructor.findOne({slug: idea.slug}, function(err, doc) {
        console.log(err);
        console.log(doc);
        next(err, doc);
    });

    //console.log(idea);
});
于 2014-10-08T23:44:05.363 回答
2

this你有文件,而不是模型。文档中不存在方法 findOne。

如果您需要模型,您可以随时检索它,如此处所示。但更聪明的做法是在创建时将模型分配给变量。然后在任何你想要的地方使用这个变量。如果它在另一个文件中,则使用 module.exports 并要求在项目中的其他任何地方获取它。像这样的东西:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/dbname', function (err) {
// if we failed to connect, abort
if (err) throw err;
var IdeaSchema = Schema({
    ...
});
var IdeaModel = mongoose.model('Idea', IdeaSchema);
IdeaSchema.pre('save', function(next) {
    var idea = this;

    function generate_slug(text) {
        return text.toLowerCase().replace(/[^\w ]+/g,'').replace(/ +/g,'-').trim();
    };

    idea.slug = generate_slug(idea.title);

    // this has no method 'find'
    IdeaModel.findOne({slug: idea.slug}, function(err, doc) {
        console.log(err);
        console.log(doc);
    });

    //console.log(idea);
    next();
   });
// we connected ok
})
于 2013-10-09T20:34:32.097 回答