How can I automatically create a new record in a database when another one is created using Sequelize.js?

765 views Asked by At

I am using Sequelize version 5 as my ORM with a User and Profile model defined. There is a one to one relationship between the two models, and I would like for a profile to be automatically created when a user is created. How can I accomplish this? My models are defined as follows:

user.js

'use strict';
module.exports = (sequelize, DataTypes) => {
    const User = sequelize.define(
        'User',
        {
            name: DataTypes.STRING,
            username: DataTypes.STRING,
            email: DataTypes.STRING,
            password: DataTypes.STRING,
        },
        {}
    );

    User.associate = function (models) {
        User.hasOne(models.Profile);
    };
    return User;
};

profile.js

'use strict';
module.exports = (sequelize, DataTypes) => {
    const Profile = sequelize.define(
        'Profile',
        {
            location: DataTypes.STRING,
            websiteUrl: DataTypes.STRING,
            bio: DataTypes.TEXT,
            userId: DataTypes.INTEGER,
        },
        {}
    );
    Profile.associate = function (models) {
        Profile.belongsTo(models.User);
    };
    return Profile;
};

I also have the following migrations:

User migration

'use strict';
module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('Users', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      name: {
        type: Sequelize.STRING
      },
      username: {
        type: Sequelize.STRING
      },
      email: {
        type: Sequelize.STRING
      },
      password: {
        type: Sequelize.STRING
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });
  },
  down: (queryInterface, Sequelize) => {
    return queryInterface.dropTable('Users');
  }
};

profile migration

'use strict';
module.exports = {
    up: (queryInterface, Sequelize) => {
        return queryInterface.createTable('Profiles', {
            id: {
                allowNull: false,
                autoIncrement: true,
                primaryKey: true,
                type: Sequelize.INTEGER,
            },
            location: {
                type: Sequelize.STRING,
            },
            websiteUrl: {
                type: Sequelize.STRING,
            },
            bio: {
                type: Sequelize.TEXT,
            },
            userId: {
                type: Sequelize.INTEGER,
                references: {
                    model: 'Users',
                    key: 'id',
                },
            },
            createdAt: {
                allowNull: false,
                type: Sequelize.DATE,
            },
            updatedAt: {
                allowNull: false,
                type: Sequelize.DATE,
            },
        });
    },
    down: (queryInterface, Sequelize) => {
        return queryInterface.dropTable('Profiles');
    },
};

1

There are 1 answers

0
Andrew Nolan On

You can create a hook where you define the creation of the profile. You can also try to use the Special Mixins available from relations

Hook approach:

module.exports = (sequelize, DataTypes) => {
  const User = sequelize.define(
    'User',
    {
        name: DataTypes.STRING,
        username: DataTypes.STRING,
        email: DataTypes.STRING,
        password: DataTypes.STRING,
    },
    {
       hooks: {
         afterCreate(user, options) => {
            Profile.create({userId: user.id)
       }
      }
    }
  );

  User.associate = function (models) {
    User.hasOne(models.Profile);
  };
  return User;
};

Mixin Approach

const user = await User.create({...userData});
const profile = await User.createProfile({userId: user.id, ...profileData});