I am facing an issue where the beforeCreate
hook in my Sequelize model is not being triggered when I attempt to create a new record. I have defined hooks in my model, but it seems they are not executing as expected. Below is the detailed description of the problem and my setup.
/* eslint-disable no-await-in-loop */
/* eslint-disable no-use-before-define */
const Sequelize = require('sequelize');
const sequelize = require('../../config/database');
const { User } = require('./User');
const { Company } = require('./Company');
const hooks = {
beforeCreate: async (project) => {
console.log('Before Create Hook Triggered');
console.log('Project before setting ID:', project);
if (!project.project_id) {
let uniqueIdentifier;
let isUnique = false;
while (!isUnique) {
uniqueIdentifier = `P${Math.floor(100000 + Math.random() * 900000)
.toString()
.padStart(6, '0')}`;
const existingProject = await Project.findOne({
where: { project_id: uniqueIdentifier },
});
if (!existingProject) {
isUnique = true;
}
}
console.log('Generated Project ID:', uniqueIdentifier); // Debug log
project.project_id = uniqueIdentifier;
console.log('Project after setting ID:', project); // Debug log
} else {
console.log('Project ID already set:', project.project_id); // Debug log
}
},
beforeValidate: (project) => {
console.log('Before Validate Hook Triggered');
if (!project.company_id) {
if (!project.procurement_manager_id) {
throw new Error('Internal Project: Procurement manager needed');
}
if (!project.project_manager_id) {
throw new Error('Internal Project: Project manager needed');
}
if (!project.finance_manager_id) {
throw new Error('Internal Project: Finance manager needed');
}
} else {
if (project.procurement_manager_id) {
throw new Error(
'External Project: Procurement manager should not be set',
);
}
if (project.project_manager_id) {
throw new Error('External Project: Project manager should not be set');
}
if (project.finance_manager_id) {
throw new Error('External Project: Finance manager should not be set');
}
if (!project.company_user_id) {
throw new Error('External Project: Company user needed');
}
}
},
};
const Project = sequelize.define(
'project',
{
id: {
type: Sequelize.UUID,
primaryKey: true,
allowNull: false,
defaultValue: Sequelize.UUIDV4,
},
name: {
type: Sequelize.STRING,
allowNull: false,
validate: {
isUnique(value, next) {
Project.findOne({
where: {
name: value,
id: { [Sequelize.Op.ne]: this.id },
},
})
.then((project) => {
if (project) {
return next('Sorry, This Project Already Exists');
}
return next();
})
.catch((err) => next(err));
},
},
},
contract_number: {
type: Sequelize.STRING,
allowNull: false,
},
description: {
type: Sequelize.TEXT,
allowNull: false,
},
status: {
type: Sequelize.STRING,
allowNull: false,
},
procurement_manager_id: {
type: Sequelize.UUID,
references: { model: User, key: 'id' },
},
project_manager_id: {
type: Sequelize.UUID,
references: { model: User, key: 'id' },
},
finance_manager_id: {
type: Sequelize.UUID,
references: { model: User, key: 'id' },
},
company_user_id: {
type: Sequelize.UUID,
references: { model: User, key: 'id' },
},
payment_status: {
type: Sequelize.STRING,
defaultValue: 'unpaid',
},
project_id: {
type: Sequelize.STRING,
allowNull: false,
validate: {
isUnique(value, next) {
Project.findOne({
where: {
project_id: value,
id: { [Sequelize.Op.ne]: this.id },
},
})
.then((project) => {
if (project) {
return next('Sorry, This Project ID Already Exists');
}
return next();
})
.catch((err) => next(err));
},
},
},
},
{
hooks,
timestamps: true,
createdAt: 'created_at',
updatedAt: 'updated_at',
},
);
// Define associations
Project.belongsTo(User, {
as: 'projectManager',
foreignKey: 'project_manager_id',
});
Project.belongsTo(User, {
as: 'procurementManager',
foreignKey: 'procurement_manager_id',
});
Project.belongsTo(User, {
as: 'financeManager',
foreignKey: 'finance_manager_id',
});
Project.belongsTo(User, {
as: 'companyUser',
foreignKey: 'company_user_id',
});
Project.belongsTo(User, { foreignKey: 'user_id' });
Project.belongsTo(Company, { foreignKey: 'company_id' });
User.hasMany(Project, { foreignKey: 'user_id' });
Company.hasMany(Project, { foreignKey: 'company_id' });
module.exports = { Project };
Expected Behavior
The beforeCreate
and beforeValidate
hooks should trigger as expected, logging the relevant debug information to the console.
**Actual Behaviour **
The beforeValidate is only trigerring