Как написать модель Mongoose в ES6 / ES2015
Я хочу написать свою модель мангуста в ES6. В основном заменить module.exports
и другие вещи ES5, где это возможно. Вот что у меня есть.
import mongoose from 'mongoose'
class Blacklist extends mongoose.Schema {
constructor() {
super({
type: String,
ip: String,
details: String,
reason: String
})
}
}
export default mongoose.model('Blacklist', Blacklist)
Я вижу эту ошибку в консоли.
if (!('pluralization' in schema.options)) schema.options.pluralization = this.options.pluralization;
^
TypeError: Cannot use 'in' operator to search for 'pluralization' in undefined
8 ответов
Я не уверен, почему вы пытаетесь использовать классы ES6 в этом случае. mongoose.Schema
является конструктором для создания новых схем. Когда вы делаете
var Blacklist = mongoose.Schema({});
вы создаете новую схему, используя этот конструктор. Конструктор разработан так, что ведет себя так же, как
var Blacklist = new mongoose.Schema({});
Какая ты альтернатива,
class Blacklist extends mongoose.Schema {
делает это создает подкласс класса схемы, но вы никогда не создаете его экземпляр
Вам нужно сделать
export default mongoose.model('Blacklist', new Blacklist());
но я бы не советовал. В том, что ты делаешь, нет ничего более ES6y. Предыдущий код вполне разумен и является рекомендуемым API для Mongoose.
Mongoose может изначально поддерживать классы es6 (начиная с 4.7 и без транспилятора…).
Просто пиши:
const mongoose = require('mongoose')
const { Model, Schema } = mongoose
const schema = new Schema({
type: String,
ip: String,
details: String,
reason: String,
})
class Tenant extends Model {}
module.exports = mongoose.model(Tenant, schema, 'tenant');
Зачем тебе это делать? mongoose.Schema
не предполагается использовать таким образом. Это не использует наследование.
mongoose.Schema
это конструктор, который принимает объект в качестве первого параметра как в ES5, так и в ES6. Нет необходимости в классах ES6 здесь.
Таким образом, даже с ES6 правильный путь должен иметь:
const Blacklist = mongoose.Schema({
type: String,
ip: String,
details: String,
reason: String,
});
Для тех, кто находит этот поиск вокруг, оригинальный вопрос кажется мне вполне актуальным. Я использую Babel для переноса ES6+ до 5. Мои пользовательские методы mongoose не очень хорошо работали с моим асинхронным / ожидающим кодом в моем вызывающем классе. особенно this
было null
в моем случае методы. Используя предоставленное здесь решение, я смог найти это решение, которое, надеюсь, поможет другим в поиске.
import mongoose from 'mongoose'
class Tenant extends mongoose.Schema {
constructor() {
const tenant = super({
pg_id: Number,
name: String,
...
})
tenant.methods.getAccountFields = this.getAccountFields
tenant.methods.getCustomerTypes = this.getCustomerTypes
tenant.methods.getContactFields = this.getContactFields
...
tenant.methods.getModelFields = this.getModelFields
return tenant
}
getAccountFields() {
return this.getModelFields(this.account_fields_mapping)
}
getCustomerTypes() {
//code
}
getContactFields() {
//code
}
...
getModelFields(fields_mapping) {
//code
}
}
export default mongoose.model('Tenant', new Tenant)
Чтобы сделать вещи ES6, как в классе, как говорится в вопросе, мне просто нужно было вызвать класс с new
в вывозимом mongoose.model
функция.
export default mongoose.model('Blacklist', new Blacklist)
Это может быть поздно для ответа, это может помочь тому, кто это ищет.
В схемах классов ES6 есть loadClass()
метод, который можно использовать для создания схемы Mongoose из класса ES6:
- Методы класса ES6 становятся методами Mongoose
- Статика класса ES6 становится статикой Mongoose
- Геттеры и сеттеры ES6 становятся виртуальными объектами Mongoose
Вот пример использования loadClass() для создания схемы из класса ES6:
class MyClass {
myMethod() { return 42; }
static myStatic() { return 42; }
get myVirtual() { return 42; }
}
const schema = new mongoose.Schema();
schema.loadClass(MyClass);
console.log(schema.methods); // { myMethod: [Function: myMethod] }
console.log(schema.statics); // { myStatic: [Function: myStatic] }
console.log(schema.virtuals); // { myVirtual: VirtualType { ... } }
Ссылка: это образец кода из документации мангуста, для более подробной информации mongoose doc
Я собираюсь дать ответ 2022 года и то, как я это делаю с ES6. Я думаю, что использование классов не приносит пользы при создании схемы, поскольку это просто определение или форма данных.
// package.json
{
...
"type": "module",
}
// root/models/users.model.js
import mongoose from 'mongoose'
const userSchema = new mongoose.Schema({ ... })
const UserModel = mongoose.model('Users', userSchema)
export { UserModel }
// root/routes/users.routes.js
import express from 'express'
import { UserModel } from '../models/users.model.js'
const userRouter = express.Router()
userRouter.post('/', async (req, res) => {
const user = UserModel.create({ ...req.body })
...
}
У меня были проблемы с использованиемexport default
иmodule.exports
ноexport { ... }
работал как положено.
Это будет работать:
import mongoose from 'mongoose';
const { Schema } = mongoose;
const userSchema = new Schema({
email: {
type: String,
required: true
},
firstName: {
type: String,
},
lastName: {
type: String
},
age: {
type: Number
}
});
export default mongoose.model('User', userSchema);