如何为所有模式注册mongoose插件?

9

我需要翻译的内容:

我错过了什么?Mongoose文档说mongoose.plugin()会为所有模式注册插件。但是这并没有起作用。我可以在每个模式上注册我的插件。

我的插件:

module.exports = function (schema, options) {

    schema.set('toObject',{
        transform: function (doc, ret, options) {
            return {
                test: 'It worked!'
            };
        }
    });
};

我的架构:

var testPlugin = require('test-plugin.js');

var personSchema = mongoose.Schema({

    _id : { type: String, default: $.uuid.init },

    ssn : { type: String, required: true, trim: true },

    first : { type: String, required: true, trim: true },
    middle : { type: String, required: true, trim: true },
    last : { type: String, required: true, trim: true }
});
personSchema.plugin(testPlugin);

var model = mongoose.model('Person', personSchema);

module.exports = model;

上面的代码能够正常运行,但是下面的代码却无法正常工作:
var personSchema = mongoose.Schema({

    _id : { type: String, default: $.uuid.init },

    ssn : { type: String, required: true, trim: true },

    first : { type: String, required: true, trim: true },
    middle : { type: String, required: true, trim: true },
    last : { type: String, required: true, trim: true }
});

var model = mongoose.model('Person', personSchema);

module.exports = model;

我的测试应用:

var testPlugin = require('test-plugin.js');
mongoose.plugin(testPlugin);

mongoose.Promise = global.Promise;
mongoose.connect(config.db);
mongoose.connection.on('error', function (err) {
    if (err) { throw err; }
});
mongoose.connection.once('open', function (err) {
    if (err) { throw err; }

    seeds.doSeed(function(err){
        if (err) { return process.exit(1); }

        models.Person.find({}, function(err, people){
            if (err) { throw err; }

            var person = people[0];
            var oPerson = person.toObject();

            console.log(JSON.stringify(oPerson));
        });
    });
});

我尝试将mongoose.plugin(testPlugin)移动到app.js文件的不同位置,包括连接后等等...但是没有效果。
4个回答

11

插件可能没有使用 mongoose.plugin(myMongoosePlugin) 注册,因为 mongoose 模型是在全局注册插件之前创建的。

  • 如果您有 expressjs 路由:

请确保在您注册/创建使用 mongoose 模型与数据库通信的 expressjs 路由之前,在您的 app.js (server.js) 中注册 mongoose 插件。

例如:

app.js

const express = require(express);
const mongoose = require('mongoose');
const myMongoosePlugin = require('<Mongoose Plugin file path>');

mongoose.plugin(myMongoosePlugin);

let app = express();

//register expressjs routes
require('<Express routes file path>')(app, express.Router());

// or create expressjs routes
app.post('/person', (req, res, next) => {
    //where someMethod is using person mongoose model
    this.someController.someMethod(someArguments)
        .then((user) => {
            res.json(user);
        }).catch((error) => {
            next(error);
        });
});

// ... Some other code ...
mongoose.connect(<databaseConnectionString>);
app.listen(<Port>);

1
这对我没有用 - 我仍然遇到了OP的问题。Mongoose 5.5.5使用mongoose-lean-virtuals 0.4.3。 - steampowered
@steampowered 你能详细说明一下吗? - Andrei Surzhan
对我来说,问题在于我的一个模型在全局应用插件之前进行了注册。显然,这必须发生在任何模型注册之前。这是我的 Github 问题,更详细的阐述:https://github.com/Automattic/mongoose/issues/8088 - steampowered

1
尝试在app.js文件中也要求您的模型。 在mongoose.plugin(testPlugin)之后的某个地方。

这实际上也是我的问题。我正在异步设置插件,并错误地在此设置完成之前加载了模型。因此,插件从未有机会将自己应用于模型。 - Adam Reis

0
这只是对@Andrei Surzhan所说的另一种看法。
关键是要在路由之前应用插件。
我最近遇到了这个问题,插件在全局范围内无法工作,但当我在创建Schema时逐个添加它们时就可以工作。
供参考,我的项目结构是这样的。
// server.js file
require('dotenv').config();
const http = require('http');
const mongoose = require('mongoose');
const myPlugin = require('path-to-my-plugin');

mongoose.plugin(myPlugin);

const app = require('./app');

const PORT = process.env.PORT || 8000;
const server = http.createServer(app);

// MONGO CONNECTION
mongoose.connect(process.env.MONGODB_URI);
mongoose.connection.on('open', () => console.log('MongoDB connection ready!'));
mongoose.connection.on('error', console.error);

server.listen(PORT, console.log(`Listening on PORT ${PORT}`));


// app.js file
const express = require('express');

// Routes
const clientsRouter = require('./routes/clients/clients.router');
const paymentsRouter = require('./routes/payments/payments.router');

const app = express();
// Parse incoming requests with JSON payloads
app.use(express.json());

// Parse incoming requests with Form payloads
app.use(
  express.urlencoded({
    extended: false,
  })
);

app.use('/clients', clientsRouter);
app.use('/payments', paymentsRouter);

module.exports = app;

正如您在 server.js 中所看到的,我们甚至在导入 app.js 之前就添加了插件,这是因为当我们导入 app.js 时,我们将调用路由,而插件不会被传递。


另一种方法是在每个模式中添加插件。

例如

// clients.model.js
const mongoose = require('mongoose');
const myPlugin = require('path-to-my-plugin');

const clientSchema = new mongoose.Schema({ ... });
clientSchema.plugin(myPlugin);

module.exports = mongoose.model('Client', clientSchema);

0

这不是最好的解决方案,但是可行的。你必须在每个文件中定义你的Schema,然后导出它。

const mongoose = require('mongoose');

const UserSchema = new mongoose.Schema({ ... })

module.exports = UserSchema;

然后,您应该实现一个文件来设置您的模型,例如:


const mongoose = require('mongoose');

// import all of your schemas

const userSchema = require(./user/modelSchema);
const TicketSchema = require(./Ticket/modelSchema);

// ***  implement your (Global Plugin) here ***

mongoose.plugin(myPlugin);

// define and create all of your models

const User = mongoose.model('User', userSchema);
const Ticket = mongoose.model('Ticket', TicketSchema);

module.exports = {
userModle: User,
ticketModel: Ticket,
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接