#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

Comments

Feel Free to Comment

We'll never share your email with anyone else.
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.