Как написать модель 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);
Другие вопросы по тегам