Как расширить модель Sequelize?

Есть ли способ, которым я мог бы использовать базовый класс, который имеет все общие атрибуты и методы для моих моделей, но не связан с таблицей базы данных, а затем я мог бы расширить этот базовый класс при определении новых моделей.

Здесь я создал базовую модель человека в node express. Мне нужно, чтобы класс человека расширялся из базового класса.

const person = sequelizeClient.define('person', {
    name: {
      type: DataTypes.STRING,
      allowNull: false
    }
  }, {
    hooks: {
      beforeCount(options) {
        options.raw = true;
      }
    }
  });

  const base = sequelizeClient.define('base', {
    id: {
      type: Sequelize.INTEGER,
      autoIncrement: true,
      primaryKey: true
    },
    createdBy: {
      type: Sequelize.INTEGER,
    },
    updatedBy: {
      type: Sequelize.INTEGER,
    },
    deletedBy: {
      type: Sequelize.INTEGER,
    }
  }, {
    hooks: {
      beforeCount(options) {
        options.raw = true;
      }
    }
  });

В документации указано, что

Модели Sequelize - это классы ES6. Вы можете легко добавить собственные методы класса или класса.

Как это сделать, используя ES6 расширяет класс шаблонов?

Есть вопрос, похожий на этот вопрос, но не обновлявшийся в последнее время. Как расширить модель Sequelize

Ответ 1

  Как я могу сделать это, используя ES6 extends pattern pattern?

Заявление в Sequelize docs немного сбивает с толку разработчиков. Это не означает, что вы можете расширить определенную модель с помощью синтаксиса класса ES6 следующим образом.

const User = db.define('User', {
  name: sequelize.STRING,
  age: sequelize.INTEGER
});

// This is impossible.
class Staff extends User {
  ...
}

Но вы можете определить методы экземпляра, обратившись к прототипу, как показано ниже.

const User = db.define('User', {
  name: sequelize.STRING,
  age: sequelize.INTEGER
});

User.Instance.prototype.test = function() {
  return 'Name: ${this.name}, Age: ${this.age}'
}

User.create({ name: "John", age: 10 });
User.findOne().then((user) => {
  console.log(user.test()) // "Name: John, Age: 10"
});

Утверждение, которое вы упомянули в Sequelize doc, на самом деле гласит, что вы можете улучшить поведение модели, используя расширение на основе прототипа, поэтому вы не можете сделать что-то вроде наследования модели, которое пытаетесь сделать в вопросе.

Существует много дискуссий о предложении реализации синтаксиса класса ES6 в Sequelize, например, this, но он все еще находится в стадии обсуждения.

Ответ 2

Поскольку кажется, что с Sequelize расширение модели классов невозможно, как насчет расширения объекта config объекта sequelize? Это немного больше работы, но обеспечивает самый близкий опыт и остается относительно чистым. Конечно, использование параметров attributes и options требует использования 2 отдельных классов или надлежащей деструктуризации объединенного класса.

class Base {
    constructor() {
        this.id = {
            type: Sequelize.INTEGER,
            autoIncrement: true,
            primaryKey: true
        };
        ...
    }
}

class Person extends Base {
    constructor() {
        super();
        this.name = {
            type: DataTypes.STRING,
            allowNull: false
        };
        ...
    }
}

// using separate class for attributes
const person = sequelize.define('person', new Person());

// possible destructuring of attributes/options
const someModel= sequelize.define('someModel', (new SomeModel()).attributes, (new SomeModel()).options);