¿Cómo consultar desde dentro de Mongoose pre hook en una aplicación Node.js / Express?

Estoy creando un blog básico en Node.js / Express usando MongoDB w / Mongoose ORM.

Tengo un gancho de ‘guardar’ que me gustaría usar para generar automáticamente un blog / idea babosa para mí. Esto funciona bien, a excepción de la parte en la que quiero consultar para ver si hay otras publicaciones existentes con la misma babosa antes de continuar.

Sin embargo, parece que this no tiene acceso a .find o .findOne () y por eso sigo recibiendo un error.

¿Cuál es la mejor manera de abordar esto?

  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(); }); 

Desafortunadamente, no está bien documentado (no se menciona en la documentación de la API Document.js ), pero los documentos tienen acceso a sus modelos a través del campo del constructor . Lo uso todo el tiempo para registrar cosas desde complementos, lo que me da acceso a A qué modelo están unidos.

 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(); }); }); 

Para tu situación, deberías poder hacer:

 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); }); 

En this tienes el documento, no el modelo. El método findOne no está presente en el documento.

Si necesita el modelo, siempre puede recuperarlo como se muestra aquí . Pero más inteligente sería simplemente asignar el modelo a una variable en el punto de creación. Luego usa esta variable en cualquier lugar que desees. Si está en otro archivo, use module.exports y solicite obtenerlo en cualquier otro lugar de su proyecto. Algo como esto:

 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 })