#express js #node #node js #sequelize #mysql

How to create model association in Sequelize - express JS / Node JS

In the very initial days of my work in Node JS if faced this issue. Though Sequelize provide a great ORM for MySQL but the association within the models is a bit tricky. you can find more about associations here

Before getting any further, if you want to get a setup for fully function code setup here it is

For the sake of understanding, lets consider two Models please inside the model directory, models/author.js and models/post.js. Models will look like as follows respectively.

Author Model

'use strict';
const {
  Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
  class Author extends Model {
    /**
     * Helper method for defining associations.
     * This method is not a part of Sequelize lifecycle.
     * The `models/index` file will call this method automatically.
     */
    static associate(models) {
      // define association here
    }
  };

  Author.init({
    slug: DataTypes.STRING,
    name: DataTypes.STRING,
  }, {
    sequelize,
    modelName: 'Author',
    tableName: 'authors',
  });


  return Author;
};

Post Model

'use strict';
const {
    Model,
} = require('sequelize');

module.exports = (sequelize, DataTypes) => {
    class Post extends Model {
        /**
         * Helper method for defining associations.
         * This method is not a part of Sequelize lifecycle.
         * The `models/index` file will call this method automatically.
         */
        static associate(models) {
            this.belongsTo(models.Author, {as: 'Author'});
        }
    }


    Post.init({
        slug: DataTypes.STRING,
        title: DataTypes.STRING,
        excerpt: DataTypes.STRING
    }, {
        sequelize,
        modelName: 'Post',
        tableName: 'posts',
    });

    return Post;
};

As shown in the post model, a belongs too association is made between Post and author. But as the comment suggest, associate method is not a part of Sequelize lifecycle. we have to call it manually.

To achieve that, we need to create models/index.js with the following content.

index.js

'use strict';

const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/database.json')[env];
const db = {};

let sequelize;
if (config.use_env_variable) {
  sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
  sequelize = new Sequelize(config.database, config.username, config.password, config);
}

fs
  .readdirSync(__dirname)
  .filter(file => {
    return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js');
  })
  .forEach(file => {
    const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes);
    db[model.name] = model;
  });

Object.keys(db).forEach(modelName => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;

Ones you are done with this you can access all you models vie models/index.js

const {Post, Author} = require('../../models');

You can find more about hoe to use association in accessing data here

GitHub Repo for the above code

mohammed-samgan-khan

Hi, I am Samgan, I excel at solving complex problems involving logic and step by step breakdown of the problem. Besides, to develop complex algorithms, I specialise in problem framing, systems design, and product development strategy. Sometimes I also enjoy public speaking.  

I am also the creator of penit.ink, a site which provides young writers with a free hand place to show their creation to the world. Irrespective of the niche, if you write this place is defiantly for you.