Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. I need the person class to be extended from the base class.

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.

How can I do this using ES6 extends class pattern?

There's a question similar to this but has not been updated recently. How to extend Sequelize model

like image 462
v1shva Avatar asked Nov 28 '17 09:11

v1shva


People also ask

How do you increment in Sequelize?

To add the AUTO_INCREMENT attribute into the columns of your tables with Sequelize, you need to add the autoIncrement attribute into your Sequelize Model definition. For example, suppose you want to add an auto increment id column into the Users table.

How do I update a Sequelized model?

The Model. upsert() method is a new method added in Sequelize v6 that allows you to perform an update statement only when a row with matching values already exist. To update a row, you need to specify the primary key of the row, which is the id column in case of the Users table.

How do you make a Sequelize model?

Sequelize set up Install Sequelize database driver for the database you would like to use by running one of the commands below. Install npm package Sequelize-CLI. Create a project folder. In your project folder path, run the command below to initialize Sequelize in the folder.

How do I add data to Sequelize?

To insert new rows into your SQL table, you need to first create a Sequelize Model object. In Sequelize, a Model is an object that represents your SQL table, giving information to Sequelize about the name, the columns, and their data types.


2 Answers

How can I do this using ES6 extends class pattern?

The statement in Sequelize docs is a little bit confusing for developers. That does not mean that you can extend the defined model with ES6 class syntax as follow.

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.

There are lots of discussion about implementation proposal of ES6 class syntax in Sequelize like this, but it is still under discussion it looks.

like image 138
IzumiSy Avatar answered Oct 21 '22 13:10

IzumiSy


As it seems that extending class model is not possible with Sequelize, how about extending the config object of the sequelize object? 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.

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);
like image 40
Eggon Avatar answered Oct 21 '22 15:10

Eggon