Using ES6 classes for Sequelize 4 models
Tags: javascript, node, es6, webdev
Published: 2018-05-09 12:23:24

---
title: Using ES6 classes for Sequelize 4 models
published: true
tags: JavaScript,Node,es6,web development
canonical_url: https://codewithhugo.com/using-es6-classes-for-sequelize-4-models/
cover_image: https://codewithhugo.com/img/eugene-lim-unsplash.jpg
---

The ES2015 or ES6 specification introduced `class` to JavaScript.
Libraries like React went from `React.createClass` to `class MyComponent extends React.Component`, ie went from rolling their own constructor to leveraging a language built-in to convey the programmer’s intent.

For a Node.js web application’s persistence layer, a few databases come to mind like [MongoDB](https://www.mongodb.com/) (possibly paired with [mongoose](http://mongoosejs.com/)), or a key-value store like [Redis](https://redis.io/).

To run a relational database with a Node application, [Sequelize](http://docs.sequelizejs.com/), “An easy-to-use multi SQL dialect ORM for Node.js” is a good option. It allows the application to run backed by a MySQL or PostgreSQL instance and provides an easy way to map from entities' representation in the database to JavaScript and vice versa.

Sequelize’s API for model definitions looks like the following (from the docs [http://docs.sequelizejs.com/manual/tutorial/upgrade-to-v4.html](http://docs.sequelizejs.com/manual/tutorial/upgrade-to-v4.html)):

```js
const MyModel = sequelize.define("MyModel", {
  // fields and methods
});
```

To add class and instance methods you would write the following:

```js
// Class Method
MyModel.associate = function (models) {};
// Instance Method
MyModel.prototype.someMethod = function () {..}
```

This is necessary pre-ES6 since there was no concept of classical inheritance. Since we have class now, why not leverage them? For developers who are used to having classes, the following would likely look familiar:

```js
class MyModel extends Sequelize.Model {
  static associate(models) {}
  someMethod() {}
}
```

Sequelize actually supports this, but the documentation is a bit lacking. One of the only place to find a reference to how to do this is in a GitHub issue: https://github.com/sequelize/sequelize/issues/6524.

Here’s a cheat sheet for things you would want to do and how to achieve it using ES6 classes + inheriting from `Sequelize.Model`:

* [Defining fields on a model](https://codewithhugo.com/using-es6-classes-for-sequelize-4-models/#typed-fields)
* [Creating associations](https://codewithhugo.com/using-es6-classes-for-sequelize-4-models/#assocations)
* [Custom table name](https://codewithhugo.com/using-es6-classes-for-sequelize-4-models/#custom-table-name)
* [Custom model name](https://codewithhugo.com/using-es6-classes-for-sequelize-4-models/#custom-model-name)
* [Wrap queries](https://codewithhugo.com/using-es6-classes-for-sequelize-4-models/#queries)
* [Instance methods](https://codewithhugo.com/using-es6-classes-for-sequelize-4-models/#instance-methods)
* [Initialising all models](https://codewithhugo.com/using-es6-classes-for-sequelize-4-models/#initialise-all)

> This was sent out on the [Code with Hugo newsletter](https://buttondown.email/hugo) last Monday.
> [Subscribe](https://buttondown.email/hugo) to get the latest posts right in your inbox (before anyone else).

# Initialise the model with typed field(s)

```js
const Sequelize = require("sequelize");
class MyModel extends Sequelize.Model {
  static init(sequelize, DataTypes) {
    return super.init(
      {
        myField: DataTypes.STRING
      },
      { sequelize }
    );
  }
}
```

# Associate your model to other models

```js
const Sequelize = require("sequelize");
class MyModel extends Sequelize.Model {
  static associate(models) {
    this.myAssociation = this.belongsTo(models.OtherModel);
    // or
    this.myAssociation = models.MyModel.belongsTo(models.OtherModel);
  }
}
```

# Setting a custom table name for your model

```js
const Sequelize = require("sequelize");
class MyModel extends Sequelize.Model {
  static init(sequelize, DataTypes) {
    return super.init(
      {
        // field definitions
      },
      {
        tableName: "myModels",
        sequelize
      }
    );
  }
}
```

# Setting a custom model name for your model (for Sequelize)

```js
const Sequelize = require("sequelize");
class MyModel extends Sequelize.Model {
  static init(sequelize, DataTypes) {
    return super.init(
      {
        // field definitions
      },
      {
        modelName: "myModel",
        sequelize
      }
    );
  }
}
```

# Wrap queries

```js
const Sequelize = require("sequelize");
class MyModel extends Sequelize.Model {
  static getId(where) {
    return this.findOne({
      where,
      attributes: ["id"],
      order: [["createdAt", "DESC"]]
    });
  }
}
```

# Instance methods

```js
const Sequelize = require("sequelize");
class MyModel extends Sequelize.Model {
  getFullName() {
    return `${this.firstName} ${this.lastName}`;
  }
}
```

# Initialise all your models

`require()` followed by `model.init()` is an alternative to `sequelize.import(path)`, it’s a bit clearer what is and isn’t imported and under what name.

```js
const Sequelize = require("sequelize");
const sequelize = new Sequelize();
// pass your sequelize config here

const FirstModel = require("./first-model");
const SecondModel = require("./second-model");
const ThirdModel = require("./third-model");

const models = {
  First: FirstModel.init(sequelize, Sequelize),
  Second: SecondModel.init(sequelize, Sequelize),
  Third: ThirdModel.init(sequelize, Sequelize)
};

// Run `.associate` if it exists,
// ie create relationships in the ORM
Object.values(models)
  .filter(model => typeof model.associate === "function")
  .forEach(model => model.associate(models));

const db = {
  ...models,
  sequelize
};

module.exports = db;
```

For any questions about using Sequelize in this manner or developing Node apps backed by relational databases, feel free to comment below or tweet to me [@hugo\_\_df](https://twitter.com/hugo__df).

Cover photo by [Eugene Lim](https://unsplash.com/photos/sorCkbu4Nzw?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com/search/photos/square?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)

> This was sent out on the [Code with Hugo newsletter](https://buttondown.email/hugo) last Monday.
> [Subscribe](https://buttondown.email/hugo) to get the latest posts right in your inbox (before anyone else).