Как выполнить запрос изнутри предварительного запроса Mongoose в приложении Node.js/Express?
Я создаю базовый блог в Node.js/Express, используя MongoDB с Mongoose ORM.
У меня есть pre 'save' hook, который я бы хотел использовать для автоматического создания пула блога/идеи для меня. Это работает отлично и хорошо, за исключением той части, где я хочу выполнить запрос, чтобы увидеть, есть ли какие-либо другие существующие сообщения с тем же самым промахом, прежде чем продолжить.
Однако, похоже, что 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();
});
Ответы
Ответ 1
К сожалению, он не задокументирован очень хорошо (не упоминается об этом в Документах Document.js API), но документы имеют доступ к их моделям через 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);
});
Ответ 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
})