Sequelize: Error: Error: Table1 is not associated to Table2 - mysql

I am trying to create the following associations using sequelize but I keep getting the following error “Error: Error: customer is not associated to order!”. I have bi-directional associations according to what I found in the documentation. I am confused about what the problem could be because when I look into the database tables I can see the foreign keys. For this example, I am trying to pull the order and customer associated with the particular order. Technically, I could do three seaprate db pull but that seems inefficient as opposed to joins.
'use strict';
module.exports = function(sequelize, DataTypes) {
var user = sequelize.define('user', {
username: DataTypes.STRING(30), //remove
password: DataTypes.STRING(255),
emailaddress: DataTypes.STRING(255),
firstname: DataTypes.STRING(30),
middlename: DataTypes.STRING(30), //remove
lastname: DataTypes.STRING(30),
approve: DataTypes.BOOLEAN,
roles: DataTypes.STRING(50),
isactive: DataTypes.BOOLEAN
}, {
classMethods: {
associate: function(models) {
// associations can be defined here
this.hasMany(models.order);
}
}
});
user.hook('afterCreate', function(usr, options) {
//hash the password
return user.update({ password: passwd }, {
where: {
id: usr.id
}
});
});
return user;
};
'use strict';
module.exports = function(sequelize, DataTypes) {
var order = sequelize.define('order', {
ponumber: DataTypes.STRING(30), //remove
orderdate: DataTypes.DATE,
shippingmethod: DataTypes.STRING(30),
shippingterms: DataTypes.STRING(30),
deliverydate: DataTypes.DATE,
paymentterms: DataTypes.STRING(30),
overridediscount: DataTypes.BOOLEAN,
shippingaddress: DataTypes.STRING(30),
shippingcity: DataTypes.STRING(30),
shippingstate: DataTypes.STRING(20),
shippingzipcode: DataTypes.STRING(10),
isactive: DataTypes.BOOLEAN
}, {
associate: function(models) {
// associations can be defined here
this.belongsTo(models.user);
this.belongsTo(models.customer);
}
});
order.hook('afterCreate', function(ord, options) {
//generate po number
return order.update({ ponumber: ponumbr }, {
where: {
id: ord.id
}//,
//transaction: options.transaction
});
});
return order;
};
'use strict';
module.exports = function(sequelize, DataTypes) {
var customer = sequelize.define('customer', {
customernumber: DataTypes.STRING(30), //remove
customerspecificationid: DataTypes.INTEGER,
customertypeid: DataTypes.INTEGER,
sportid: DataTypes.INTEGER,
customername: DataTypes.STRING(20), //remove
address: DataTypes.STRING(30),
city: DataTypes.STRING(30),
state: DataTypes.STRING(30),
zipcode: DataTypes.STRING(30),
ordercomplete: DataTypes.BOOLEAN,
isactive: DataTypes.BOOLEAN
}, {
associate: function(models) {
// associations can be defined here
this.hasMany(models.order);
}
});
customer.hook('afterCreate', function(cust, options) {
//generate the customer number
return customer.update({ customernumber: custnumber }, {
where: {
id: cust.id
}
});
});
return customer;
};
Here is the constructor and method inside of a repository class I want to join
constructor(model){
super(model.order);
this.currentmodel = model;
}
findById(id){
let that = this;
return new Promise(
function(resolve, reject) {
that.model.find({
where: { id: id },
include: [ that.currentmodel.customer, that.currentmodel.user ]
})
.then(function(order){
resolve(order);
})
.catch(function(err){
reject(err);
})
});
}
I have reviewed the documentation and searched the internet looking for a fix to this issue but I am not finding any answers. Could someone please shed some light on what I could be missing?
For the example above, I am trying to retrieve the user and the customer tied to the order record via the primary key. All of the findBy scenarios I have found so far would be getting a list of orders tied to the customer and user. What do I need to change in order to retrieve the order and customer whose foreign keys are tied to this order?

The problem is probably with how you are setting you association, kindly mention your strategy.
Following is working fine if you use the express index.js file setup and then query http://docs.sequelizejs.com/en/1.7.0/articles/express/
'use strict';
module.exports = function(sequelize, DataTypes) {
var customer = sequelize.define('customer', {
customernumber: DataTypes.STRING(30), //remove
customerspecificationid: DataTypes.INTEGER,
customertypeid: DataTypes.INTEGER,
sportid: DataTypes.INTEGER,
customername: DataTypes.STRING(20), //remove
address: DataTypes.STRING(30),
city: DataTypes.STRING(30),
state: DataTypes.STRING(30),
zipcode: DataTypes.STRING(30),
ordercomplete: DataTypes.BOOLEAN,
isactive: DataTypes.BOOLEAN
}, {
associate: function(models) {
// associations can be defined here
models.customer.hasMany(models.order);
}
});
customer.hook('afterCreate', function(cust, options) {
//generate the customer number
return customer.update({ customernumber: custnumber }, {
where: {
id: cust.id
}
});
});
return customer;
};
'use strict';
module.exports = function(sequelize, DataTypes) {
var order = sequelize.define('order', {
ponumber: DataTypes.STRING(30), //remove
orderdate: DataTypes.DATE,
shippingmethod: DataTypes.STRING(30),
shippingterms: DataTypes.STRING(30),
deliverydate: DataTypes.DATE,
paymentterms: DataTypes.STRING(30),
overridediscount: DataTypes.BOOLEAN,
shippingaddress: DataTypes.STRING(30),
shippingcity: DataTypes.STRING(30),
shippingstate: DataTypes.STRING(20),
shippingzipcode: DataTypes.STRING(10),
isactive: DataTypes.BOOLEAN
}, {
associate: function(models) {
// associations can be defined here
models.order.belongsTo(models.user);
models.order.belongsTo(models.customer);
}
});
order.hook('afterCreate', function(ord, options) {
//generate po number
return order.update({ ponumber: ponumbr }, {
where: {
id: ord.id
}//,
//transaction: options.transaction
});
});
return order;
};
'use strict';
module.exports = function(sequelize, DataTypes) {
var user = sequelize.define('user', {
username: DataTypes.STRING(30), //remove
password: DataTypes.STRING(255),
emailaddress: DataTypes.STRING(255),
firstname: DataTypes.STRING(30),
middlename: DataTypes.STRING(30), //remove
lastname: DataTypes.STRING(30),
approve: DataTypes.BOOLEAN,
roles: DataTypes.STRING(50),
isactive: DataTypes.BOOLEAN
}, {
classMethods: {
associate: function(models) {
// associations can be defined here
models.user.hasMany(models.order);
}
}
});
user.hook('afterCreate', function(usr, options) {
//hash the password
return user.update({ password: passwd }, {
where: {
id: usr.id
}
});
});
return user;
};
// index.js file where you shall associate the routes
var fs = require('fs')
, path = require('path')
, Sequelize = require('sequelize')
, lodash = require('lodash')
, sequelize = new Sequelize('sequelize_test', 'root', 'root')
, db = {}
fs.readdirSync(__dirname)
.filter(function(file) {
return (file.indexOf('.') !== 0) && (file !== 'index.js')
})
.forEach(function(file) {
var model = sequelize.import(path.join(__dirname, file))
db[model.name] = model
})
Object.keys(db).forEach(function(modelName) {
if (db[modelName].options.hasOwnProperty('associate')) {
db[modelName].options.associate(db)
}
})
// sequelize.sync({force: true})
module.exports = lodash.extend({
sequelize: sequelize,
Sequelize: Sequelize
}, db)
Put the above db code in respective files in db folder or whatever you like to name it and then you can use your query
var db = require('./db');
db.order.find({
where: { id: 0 },
include: [ db.customer, db.user ]
})
.then(function(order){
console.log(order)
})

Related

Adding Many to Many Data Sequelize

Case: I have 2 tables; one for users and one for assignments. A user can have many assignments and an assignment can be assigned to many users. I have a form in the frontend to add assignment and assign the users for the assignment and I am really confused on how to add the assignment and user to the joint table 'user_assignment'. Can someone point where I am having the mistake? Also for this, I refer to Advanced M:N Associations.
I also attach my code for the Users and Assignments model, and other relevant code parts.
user.model.js
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define("users", {
firstName: {
type: DataTypes.STRING,
allowNull: false,
},
lastName: {
type: DataTypes.STRING,
allowNull: false,
},
department: {
type: DataTypes.STRING,
allowNull: false,
},
email: {
type: DataTypes.STRING,
allowNull: false,
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
role: {
type: DataTypes.STRING,
allowNull: false,
},
});
return User;
};
assignment.model.js
module.exports = (sequelize, DataTypes) => {
const Assignment = sequelize.define("assignments", {
title: {
type: DataTypes.STRING,
allowNull: false,
},
department: {
type: DataTypes.STRING,
allowNull: false,
},
urgency: {
type: DataTypes.STRING,
allowNull: false,
},
assignmentBegin: {
type: DataTypes.STRING,
allowNull: false,
},
assignmentEnd: {
type: DataTypes.STRING,
allowNull: false,
},
description: {
type: DataTypes.STRING,
allowNull: false,
},
});
return Assignment;
};
database/index.js
...
db.user = require("../models/user.model")(sequelize, Sequelize);
db.assignment = require("../models/assignment.model")(sequelize, Sequelize);
...
db.user.belongsToMany(db.assignment, {
through: "user_assignment",
as: "assignments",
foreignKey: "userId",
});
db.assignment.belongsToMany(db.user, {
through: "user_assignment",
as: "users",
foreginKey: "assignmentId",
});
...
assignment.controller.js
const db = require("../database");
const Assignment = db.assignment;
const User = db.user;
exports.create = async (req, res) => {
const {
participant,
title,
department,
urgency,
assignmentBegin,
assignmentEnd,
description,
} = req.body;
await Assignment.create({
title: title,
department: department,
urgency: urgency,
assignmentBegin: assignmentBegin,
assignmentEnd: assignmentEnd,
description: description
}).then(async result => {
for (i = 0; i < participant.length; i++) {
const user = await User.findByPk(participant[i])
// console.log(user.id)
await UserController.addAssignment(user.id, result.id);
// await UserController.addAssignment(2, 1)
}
}).catch(err => {
res.json({ message: "ERROR WHILE CREATING ASSIGNMENT!" });
console.log(">>> ERROR WHILE CREATING ASSIGNMENT!")
});
}
Any pointers on what I should do would be great!
I'd recommend you define the model associations inside each of the model files. Also you should hash/encrypt your passwords before saving them to the DB, you can use the .comparePassword() function outside of the model in a controller when logging in etc.
models/User.js
const Promise = require('bluebird')
const bcrypt = Promise.promisifyAll(require('bcrypt'))
function hashPassword (user) {
const SALT_FACTOR = 12
if (!user.changed('password')) {
return;
} else {
user.setDataValue('password', bcrypt.hashSync(user.password, SALT_FACTOR))
}
}
module.exports = User = (sequelize, DataTypes) => {
const User = sequelize.define('User', {
firstName: {
type: DataTypes.STRING,
allowNull: false,
},
lastName: {
type: DataTypes.STRING,
allowNull: false,
},
department: {
type: DataTypes.STRING,
allowNull: false,
},
email: {
type: DataTypes.STRING,
allowNull: false,
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
role: {
type: DataTypes.STRING,
allowNull: false,
},
{
hooks: {
beforeCreate: hashPassword,
beforeUpdate: hashPassword
}
})
User.associate = models => {
User."Association type here"(models."Model to associate",
{Options (For many to many add your "through" table here)}
)
// Example:
User.belongsToMany(models.Assignment, {
through: "UserAssignment"
})
}
User.prototype.comparePassword = function (password) {
return bcrypt.compareSync(password, this.password)
}
return User
}
And in the associated Model (models/Assignment.js):
module.exports = Assignment = (sequelize, DataTypes) => {
const Assignment = sequelize.define('Assignment', {
title: {
type: DataTypes.STRING,
allowNull: false,
},
department: {
type: DataTypes.STRING,
allowNull: false,
},
urgency: {
type: DataTypes.STRING,
allowNull: false,
},
assignmentBegin: {
type: DataTypes.STRING,
allowNull: false,
},
assignmentEnd: {
type: DataTypes.STRING,
allowNull: false,
},
description: {
type: DataTypes.STRING,
allowNull: false,
},
},
{
timestamps: false
})
Assignment.associate = models => {
Assignment.belongsToMany(models.User, {
through: "UserAssignment"
})
}
return Role
}
The joint table (models/UserAssignment.js):
module.exports = UserAssignment = (sequelize, DataTypes) => {
const UserAssignment = sequelize.define('UserAssignment', {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true
}
},
{
timestamps: false
})
return UserAssignment
}
And finally my index.js file (models/index.js), it programatically adds the models to the DB:
'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/config.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;
As an extra note, you can shorten down your createAssignment function in your controller by doing this instead:
const {
participant,
title,
department,
urgency,
assignmentBegin,
assignmentEnd,
description,
} = req.body;
await Assignment.create({
title: title,
department: department,
urgency: urgency,
assignmentBegin: assignmentBegin,
assignmentEnd: assignmentEnd,
description: description
}).then(async result => {
result.addUsers(participant)
}).catch(err => {
res.json({ message: "ERROR WHILE CREATING ASSIGNMENT!" });
console.log(">>> ERROR WHILE CREATING ASSIGNMENT!")
});
Hope this helps, if not lmk ill try to help some more.

Sequelize model.create is not a function

I'm new to sequelize and trying to set it up for my new project. I checked some answers on this, but couldnt get past my error. Can someone point out how to fix this.
models/index.js
// Database service
// Connects to the database
const { Sequelize } = require('sequelize');
const path = require('path');
const sequelize = new Sequelize(process.env.DB_NAME, process.env.DB_USER, process.env.DB_PASS, {
host: process.env.DB_HOST,
dialect: 'mysql',
logging: process.env.QUERY_LOGGING == "true" ? console.log : false,
pool: {
max: 10,
min: 0,
acquire: 30000,
idle: 10000
}
});
module.exports = sequelize
models/users.js
const sequelize = require("./index")
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define('Users', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
firstName: {
type: DataTypes.STRING,
allowNull: false
},
lastName: {
type: DataTypes.STRING
},
profileURL: {
type: DataTypes.STRING
},
emailId: {
type: DataTypes.STRING,
allowNull: false
},
passwordHash: {
type: DataTypes.STRING,
allowNull: false
},
street: {
type: DataTypes.STRING
},
city: {
type: DataTypes.STRING,
allowNull: false
},
phone: {
type: DataTypes.STRING
},
newsletter: {
type: DataTypes.STRING
},
visibility: {
type: DataTypes.BOOLEAN,
defaultValue: true
},
},{
});
return User;
};
And finally, I'm importing the User model in my service file like below:
const User = require("../models/users")
const createUser = async(req) => {
const {firstName, lastName, profileURL, emailId, passwordHash, street, city, phone, newsletter, visibility} = req.body
const user = await User.create({
firstName,
lastName,
profileURL,
emailId,
passwordHash,
street,
city,
phone,
newsletter,
visibility
})
console.log("new user==>>", user)
return
}
module.exports = { createUser }
However, I get the following error.
TypeError: User.create is not a function
Can someone point out what I could be doing wrong? I realize it could be something minor.
Thank you
You export a function that registers the User model and not the model itself. So you just need to call it passing sequelize instance and DataTypes somewhere like database.js where you will register all models and their associations or directly in models/index.js:
const UserModelConstructor = require("../models/users")
const { DataTypes } = require("sequelize");
...
const UserModel = UserModelConstructor(sequelize, DataTypes);
module.exports = {
sequelize,
User: UserModel
}
You can look at how to register multiple models and association in my other answer here
Please don't forget to remove this line
const sequelize = require("./index")
from models/users.js

No Sequelize instance passed for discordjs

https://github.com/qaiswaz/ticket
hear is the code please help me I've bean searching for a solution for a week now.
every time i try to run the bot hear is what it says
bot is online
Executing (default): SELECT 1+1 AS result
connected to DB
Error: No Sequelize instance passed
at Function.init (C:\Users\qaisw\OneDrive\Desktop\ALL FILES\discording\ticket\node_modules\sequelize\lib\model.js:921:13)
at Function.init (C:\Users\qaisw\OneDrive\Desktop\ALL FILES\discording\ticket\models\TicketConfig.js:5:20)
at C:\Users\qaisw\OneDrive\Desktop\ALL FILES\discording\ticket\bot.js:13:22
at processTicksAndRejections (internal/process/task_queues.js:88:5)
bot.js
require('dotenv').config();
const { Client } = require('discord.js');
const client = new Client({ partials: ['MESSAGE', 'REACTION'] });
const db = require('./database');
const Ticket = require('./models/Ticket');
const TicketConfig = require('./models/TicketConfig');
client.once('ready', () => {
console.log('bot is online');
db.authenticate()
.then(() => {
console.log('connected to DB');
Ticket.init(db);
TicketConfig.init(db);
Ticket.sync();
TicketConfig.sync();
}).catch((err) => console.log(err));
});
client.on('message', async message => {
if (message.author.bot || message.channel.type === 'dm') return;
if (message.content.toLowerCase() ==='?setup' && message.guild.ownerID === message.author.id) {
try {
const filter = (m) => m.author.id === message.author.id;
message.channel.send('please enter the message id for this ticket');
const msgId = (await message.channel.awaitMessages(filter, { max: 1})).first().content;
console.log(msgId)
const fetchMsg = message.channel.messages.fetch(msgId);
message.channel.send('please enter the category id for this ticket');
const categoryId = (await message.channel.awaitMessages(filter, { max: 1})).first().content;
console.log(categoryId)
const categoryChannel = client.channels.catche.get(categoryId);
message.channel.send('please enter all of the roles that have access to tickets');
const roles = (await message.channel.awaitMessages(filter, {max: 1})).first().content.split(/,\s*/);
if (fetchMsg && categoryChannel) {
for (const roleId of roles)
if (!message.guild.roles.cache.get(roleId)) throw new Error('role does not exist');
const ticketConfig = await TicketConfig.create({
messageId: msgId,
guildId: message.guild.id,
roles: json.stringify(roles),
parentId: categoryChannel.id
});
message.channel.send('saved config to db');
}else throw new error('invaild fields');
}catch (err) {
}
}
});
client.login(process.env.BOT_TOKEN);
database.js
const { Sequelize } = require('sequelize');
module.exports = new Sequelize(process.env.DB_NAME, process.env.DB_USER, process.env.DB_PASS, {
dialect: 'mysql',
host: process.env.DB_HOST
});
*models/Ticket.js
const { DataTypes, Model } = require('sequelize');
module.exports = class Tickets extends Model {
static init(sequelize) {
return super.init( {
ticketId: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
},
channelId: {
type: DataTypes.STRING,
},
guildId: {
type: DataTypes.STRING,
},
resolved:{
type: DataTypes.BOOLEAN,
},
closedMessageId:{
type: DataTypes.STRING,
},
authorId:{
type: DataTypes.STRING,
},
},
{
sequelize: sequelize,
modelName: 'Ticket'
})
}
}
models/TicketConfig.js
const { DataTypes, Model } = require('sequelize');
module.exports = class TicketConfig extends Model {
static init(sequelize) {
return super.init({
messegeId: {
type: DataTypes.STRING,
primaryKey: true
},
guildld: {
type: DataTypes.STRING
},
roles: {
type: DataTypes.STRING
},
parentld: {
type: DataTypes.STRING
},
sequelize: sequelize,
modelName: 'TicketConfig',
})
}
}
I added sequelizeInstance while define model
*models/Ticket.js
const { DataTypes, Model } = require('sequelize');
const sequelizeInstance = require('./database');
module.exports = class Tickets extends Model {
static init(sequelize) {
return super.init( {
ticketId: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
},
channelId: {
type: DataTypes.STRING,
},
guildId: {
type: DataTypes.STRING,
},
resolved:{
type: DataTypes.BOOLEAN,
},
closedMessageId:{
type: DataTypes.STRING,
},
authorId:{
type: DataTypes.STRING,
},
},
{
sequelize: sequelizeInstance, // <-
modelName: 'Ticket'
})
}
}
models/TicketConfig.js
const { DataTypes, Model } = require('sequelize');
const sequelizeInstance = require('./database')
module.exports = class TicketConfig extends Model {
static init(sequelize) {
return super.init({
messegeId: {
type: DataTypes.STRING,
primaryKey: true
},
guildld: {
type: DataTypes.STRING
},
roles: {
type: DataTypes.STRING
},
parentld: {
type: DataTypes.STRING
},
sequelize: sequelizeInstance, // <-
modelName: 'TicketConfig',
})
}
}

Sequelize include options cannot get another models

I have two model that are belongs to each other (order_items.js & products.js) productId as a foreign key in order_items, code as below:
order_items.js
const { DataTypes } = require('sequelize')
const db_config = require(`../config/config`)
const Product = require('./product')
const OrderItem = db_config.define('order_item', {
productId : { type: DataTypes.INTEGER, allowNull:false, references: {model: Product, key: 'id'} },
quantity: { type: DataTypes.INTEGER }
}, {
freezeTableName: true
})
module.exports = OrderItem
product.js
const { DataTypes } = require('sequelize')
const db_config = require(`../config/config`)
const Category = require('./category')
const Product = db_config.define('product', {
productName : { type: DataTypes.STRING, allowNull:false },
productPrice: { type: DataTypes.INTEGER, allowNull:false },
productDescription: { type: DataTypes.STRING, allowNull:true },
productImage: { type: DataTypes.STRING, allowNull:true },
productStock: { type: DataTypes.INTEGER, validate: { min: 0 }, defaultValue: 0, allowNull: false },
CategoryId: { type: DataTypes.INTEGER, allowNull:false, defaultValue: 1, references: {model: Category, key: 'id'}}
}, {
freezeTableName: true
})
module.exports = Product
order_routes.js
router.get('/', async (req, res) => {
try {
const dataList = await OrderItem.findAll({include: [{model:Product, required:true}]})
res.send({
status: "success",
message: "data found",
data: dataList
})
} catch (err) {
res.send({
status: "failed",
message: err})
}
})
Result in postman
Can anyone help please? what I'm trying to do is that when I get the order_item, it also get the products refers to the id of the products
Where are the associations in the model definition? I see a reference on column field but you also needs to do below definitions seperately
Inside OrderItem Model File
OrderItem.associate = models => {
OrderItem.belongsTo(Product, {as: "product", foreignKey: "productId", sourceKey: "id"});
};
Inside Products Model File
Product.associate = models => {
Product.hasMany(OrderItem, {as: "orders", foreignKey: "productId", sourceKey: "id"});
};
Also I would suggest you to store price in OrderItem collection as well so in case in future when the product price changes your past order data is not incorrect.

Unable to insert id into a table that belongs to a foreign key referenced table using Sequelize

I am building serverless application using node js and using claudia-api-builder as a framework to launch APIs in AWS.
In app.js file, i call the required api as
const ApiBuilder = require('claudia-api-builder');
const api = new ApiBuilder();
module.exports = api;
api.post('/api/auth/validatephonenumber', async function (request)
{
return new Promise((resolve, reject) => {
index.loadDatabase().then((db) => {
resolve(loginController.validatePhonenumber(db, request));
});
});
});
Below is my code:
async function validatePhonenumber(db, request) {
return new Promise(
async (resolve, reject) => {
let emailid;
await db.EmailRegistration.sync().then(function () {
emailid = db.EmailRegistration.findOne({
where: { email: { [Op.eq]: mailid } },
attributes: ['id'],
});
});
if (emailid != null) {
console.log(`email id: ${emailid.id}`);
await db.ContactDetails.sync().then(function () {
db.ContactDetails.findOrCreate({
where: { contactnumber: phnum },
defaults: { EmailRegistrationId: emailid.id },
}).spread((contactdetails, created) => {
console.log(`contactdetails: ${contactdetails}`);
if (contactdetails !== null) {
resolve({ statuscode: indexController.statusCode.statusOK, contactdetails: contactdetails })
} else {
reject({ statuscode: indexController.statusCode.InternalServerError, message: 'phone number not created' });
}
});
});
};
});
}
I am trying to add a emailregistrationid of EmailRegistration table into ContactDetails table as a foreign key reference. I am using sequelize with mysql, nodejs to achieve the desired results. But, i am getting below error:
Unhandled rejection SequelizeForeignKeyConstraintError: Cannot add or update a child row: a foreign key constraint fails (inmeeydb.ContactDetails, CONSTRAINT ContactDetails_ibfk_1 FOREIGN KEY (EmailRegistrationId) REFERENCES EmailRegistration (id) ON DELETE CASCADE ON UPDATE CASCADE)
Below is my EmailRegistration models file:
const moment = require('moment');
module.exports = (sequelize, DataTypes) => {
const EmailRegistration = sequelize.define(
'EmailRegistration',
{
id: {
type: DataTypes.UUID,
primaryKey: true,
allowNull: false,
defaultValue: DataTypes.UUIDV4,
},
email: {
type: DataTypes.STRING(50),
allowNull: false,
},
password: {
type: DataTypes.STRING,
allowNull: false,
validate: { min: 6 },
},
createdAt: {
type: DataTypes.DATE,
get() {
return moment.utc(new Date(), 'DD/MM/YYYY h:mm a').format('DD/MM/YYYY h:mm a');
},
},
updatedAt: {
type: DataTypes.DATE,
defaultValue: null,
},
},
{
freezeTableName: true,
}
);
EmailRegistration.associate = function (models) {
EmailRegistration.hasOne(models.ContactDetails,
{ foreignKey: 'EmailRegistrationId' }
);
};
return EmailRegistration;
};
Below is my Contactdetails models file:
const moment = require('moment');
module.exports = (sequelize, DataTypes) => {
const ContactDetails = sequelize.define(
'ContactDetails',
{
id: {
type: DataTypes.UUID,
primaryKey: true,
allowNull: false,
defaultValue: DataTypes.UUIDV4,
},
contactnumber: { type: DataTypes.STRING(13), allowNull: false },
isverified: { type: DataTypes.BOOLEAN, defaultValue: false },
createdAt: {
type: DataTypes.DATE,
get() {
return moment.utc(new Date(), 'DD/MM/YYYY h:mm a').format('DD/MM/YYYY h:mm a');
},
},
updatedAt: {
type: DataTypes.DATE,
defaultValue: null,
},
},
{
indexes: [{ fields: ['contactnumber'], unique: true }],
},
{
freezeTableName: true,
}
);
ContactDetails.associate = function(models) {
ContactDetails.belongsTo(models.EmailRegistration, {
onDelete: 'CASCADE',
hooks: true,
foreignKey: { allowNull: false },
});
};
return ContactDetails;
};
I tried to change the code as below with reference in both tables, but nothing worked.
ContactDetails.associate = function(models) {
ContactDetails.belongsTo(models.EmailRegistration,
{ foreignKey: 'EmailRegistrationId' }
);
};
Not able to analyze how to overcome the issue. This worked fine when i used nodejs with expressjs and had no issues. It fails to identify the EmailRegistrationId(that is missing in the query) in ContactDetails table and shows the output as
INSERT INTO `ContactDetails` (`id`,`contactnumber`,`isverified`,`createdAt`,`updatedAt`) VALUES ('52974e07-8489-4101-ab71-6af874903290','+xxxxxxxxx',false,'2018-10-12 08:55:35','2018-10-12 08:55:35');
You need to update the configuration of your association. The ContactDetails model will now have a field called emailregistrationid
EmailRegistration.associate = function (models) {
EmailRegistration.hasMany(models.ContactDetails);
};
ContactDetails.associate = function(models) {
ContactDetails.belongsTo(models.EmailRegistration, {
onDelete: 'CASCADE',
hooks: true,
foreignKey: {
name: 'emailregistrationid'
allowNull: false
},
});
}
ContactDetails.create({
...
emailregistrationid: <some_valid_emailregistrationid>
})