Sling Academy
Home/Node.js/How to extend an existing model in Sequelize

How to extend an existing model in Sequelize

Last updated: December 29, 2023

Introduction

Sequelize is a robust SQL ORM for Node.js, and it provides an intuitive way to work with relational databases. One of the features of Sequelize is model extension, which allows developers to add functionality to existing models or to modify their behavior. This tutorial will guide you through various ways to extend an existing model in Sequelize with code examples ranging from basic to advanced scenarios.

Basic Model Extension

First, let’s start with a fundamental example of extending a model. Assume you have a User model, and you want to add a method to it after it has been defined:

const { Model } = require('sequelize');
class User extends Model {}
User.init({
  // model definition...
}, { sequelize });

User.prototype.sayHello = function() {
  return `Hello, my name is ${this.name}!`;
};

By adding a method to the prototype of the User model, all instances of User will now have access to the sayHello method.

Implementing Instance Methods

User.prototype.fullName = function() {
  return `${this.firstName} ${this.lastName}`;
};

This instance method can be used to concatenate the first name and last name of a user into a full name.

Adding Static Class Methods

User.findByEmail = async function(email) {
  return await this.findOne({ where: { email } });
};

Static class methods allow you to add custom functions that are not tied to individual instances but that still have access to the model.

Using Model Hooks

Sequelize also supports hooks, which are functions that run before or after certain actions. An example would be hashing a password before saving a user:

User.beforeSave(async (user) => {
  if (user.password) {
    user.password = await bcrypt.hash(user.password, 10);
  }
});

Keep in mind that hooks should be used with caution, as they can introduce side-effects that are hard to track down.

Advanced Model Extension

As you become more comfortable with Sequelize, you can undertake more advanced extensions, such as using mixins.

function MyModelMixin(model) {
  model.prototype.someMethod = function () {
    // ... implementation ...
  };

  return model;
}

const ExtendedUser = MyModelMixin(User);

This mixin pattern allows you to compose your model with additional behavior. You could have multiple mixins and apply them to different models as needed.

Utilizing Scopes

User.addScope('activeUsers', {
  where: { isActive: true }
});

Scopes are a way to pre-define queries that you can reuse throughout your application. Here we add a scope to retrieve active users easily.

Model Inheritance

In some cases, you may want to create a completely new model that inherits from the existing one, such as a specialized type of user:

class AdminUser extends User {
  // Additional model definition or override methods
}

AdminUser.init({
  // additional or overridden fields
}, {
  sequelize,
  modelName: 'adminUser'
});

This would allow you to carry over the behavior of the User model to the AdminUser.

Conclusion

Extending Sequelize models allows for flexible and maintainable code as your application grows. By adding methods, utilizing hooks, implementing scopes, and using inheritance, your database layer can remain robust and feature-rich. With the examples provided, you’re now equipped to enhance your Sequelize models dynamically. Always ensure that extensions serve a functional purpose and that they maintain the integrity of your application’s data flow.

Next Article: Sequelize.js: How to Validate Numbers and Text Length

Previous Article: What is Model Synchronization in Sequelize?

Series: Sequelize.js Tutorials

Node.js

You May Also Like

  • NestJS: How to create cursor-based pagination (2 examples)
  • Cursor-Based Pagination in SequelizeJS: Practical Examples
  • MongooseJS: Cursor-Based Pagination Examples
  • Node.js: How to get location from IP address (3 approaches)
  • SequelizeJS: How to reset auto-increment ID after deleting records
  • SequelizeJS: Grouping Results by Multiple Columns
  • NestJS: Using Faker.js to populate database (for testing)
  • NodeJS: Search and download images by keyword from Unsplash API
  • NestJS: Generate N random users using Faker.js
  • Sequelize Upsert: How to insert or update a record in one query
  • NodeJS: Declaring types when using dotenv with TypeScript
  • Using ExpressJS and Multer with TypeScript
  • NodeJS: Link to static assets (JS, CSS) in Pug templates
  • NodeJS: How to use mixins in Pug templates
  • NodeJS: Displaying images and links in Pug templates
  • ExpressJS + Pug: How to use loops to render array data
  • ExpressJS: Using MORGAN to Log HTTP Requests
  • NodeJS: Using express-fileupload to simply upload files
  • ExpressJS: How to render JSON in Pug templates