简体   繁体   English

如何扩展Sequelize模型?

[英]How to extend a Sequelize model?

Is there a way that I could use a base class that has all the common attributes and methods for my models but not linked with a database table, and then I could extend this base class when defining new models. 有没有办法可以使用一个基类,它具有我的模型的所有公共属性和方法,但没有与数据库表链接,然后我可以在定义新模型时扩展这个基类。

Here I have created the base, person model in node express. 在这里,我在node express中创建了基础,人员模型。 I need the person class to be extended from the base class. 我需要从基类扩展person类。

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;
      }
    }
  });

In the documentation it's stated that 在文档中说明了这一点

Sequelize Models are ES6 classes.You can very easily add custom instance or class level methods. Sequelize Models是ES6类。您可以非常轻松地添加自定义实例或类级别方法。

How can I do this using ES6 extends class pattern? 我怎样才能使用ES6扩展类模式?

There's a question similar to this but has not been updated recently. 有一个类似的问题,但最近没有更新。 How to extend Sequelize model 如何扩展Sequelize模型

How can I do this using ES6 extends class pattern? 我怎样才能使用ES6扩展类模式?

The statement in Sequelize docs is a little bit confusing for developers. Sequelize docs中的声明对开发人员来说有点混乱。 That does not mean that you can extend the defined model with ES6 class syntax as follow. 这并不意味着您可以使用ES6类语法扩展已定义的模型,如下所示。

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

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

But you can define instance methods by accessing protoype like below. 但您可以通过访问如下所示的原型来定义实例方法。

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"
});

The statement you mentioned in Sequelize doc actually says is that you can enhance model behaviour using prototype based extension, so you cannot do something like model inheritance you try to do in the question. 你在Sequelize doc中提到的声明实际上是说你可以使用基于原型的扩展来增强模型行为,所以你不能做你尝试在问题中做的模型继承。

There are lots of discussion about implementation proposal of ES6 class syntax in Sequelize like this , but it is still under discussion it looks. 有很多关于Sequelize像ES6类语法的实施方案讨论这个 ,但它仍然是讨论它看起来。

As it seems that extending class model is not possible with Sequelize, how about extending the config object of the sequelize object? 由于Sequelize似乎无法扩展类模型,如何扩展sequelize对象的配置对象呢? It is slighlty more work, but provides the closest experience and remains relatively clean. 这是更多的工作,但提供最接近的体验,并保持相对清洁。 Of course using both attributes and options parameters requires using 2 separate classes or proper destructuring of a combined class. 当然,使用attributesoptions参数需要使用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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM