How to do 3 joins with sequelize? - node.js

I'm trying to do 3 joins, basically antispam_domain join left domain join left company join left territory
my code is:
'use strict';
module.exports = (sequelize, DataTypes) => {
const Domain = sequelize.define('Domain', {});
const Company = sequelize.define('Company', {});
const Territory = sequelize.define('Territory', {});
const Antispam_domain = sequelize.define('Antispam_domain', {
domain_id: DataTypes.INTEGER,
created_by_user_id: DataTypes.INTEGER,
filter_id: DataTypes.INTEGER,
domain: DataTypes.STRING,
status: DataTypes.STRING
}, {});
Antispam_domain.associate = function(models) {
Antispam_domain.belongsTo(models.Domain, {through : 'relation'});
Domain.belongsTo(models.Company, {through : 'relation'});
Company.belongsTo(Territory, {through: 'relation'});
};
return Antispam_domain;
};
`
and `
Antispam_domain
.findAll({
where: {
id: req.body.id
},
include: ['relation']
})
.then((result) => {
if (!result) {
return res.status(401).send({
message: 'Domain not found.',
});
}
res.json({ success: true, result: result});
})
.catch((error) => res.status(400).send(error));
`
but show the response status 400 bad request...

There is :
'use strict';
module.exports = (sequelize, DataTypes) => {
const Antispam_domain = sequelize.define('Antispam_domain', {
domain_id: DataTypes.INTEGER,
created_by_user_id: DataTypes.INTEGER,
filter_id: DataTypes.INTEGER,
domain: DataTypes.STRING,
status: DataTypes.STRING
}, {});
Antispam_domain.associate = function(models) {
Antispam_domain.belongsTo(models.Domain, {foreignKey: 'domain_id'});
models.Domain.belongsTo(models.Company, {foreignKey: 'company_id'});
};
return Antispam_domain;
};
and :
Antispam_domain
.findAll({
where: {
id: req.body.id
},
include: [{
model : Domain,
include: [{
model: Company
}]
}]
})

Related

Error: Include unexpected. Element has to be either a Model, an Association or an object. in sequelize

enter image description here this is my database with three tables
1.users (user has one account).
2.Account (account has many transactions).
3.Transactions.
my Account table
module.exports = (sequelize, DataTypes) => {
const Account = sequelize.define("Account", {
UserId: {
type: DataTypes.INTEGER,
primaryKey: true,
allowNull: true,
},
UUID: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
},
amount: {
type: DataTypes.FLOAT,
defaultValue: 0,
allowNull: false,
},
});
Account.associate = function(models) {
Account.hasMany(models.Transaction, {
foreignKey: 'UserId',
targetKey: 'UUID'
});
};
Account.associate = function (models) {
Account.belongsTo(models.Users,{
foreignKey: "UserId",
})
}
return Account;
};
my transaction table
module.exports = (sequelize, DataTypes) => {
const Transaction = sequelize.define("Transaction", {
UUID: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
},
mode: {
type: DataTypes.ENUM("debit", "credit"),
defaultValue: "debit",
},
balance: {
type: DataTypes.BIGINT,
allowNull: false,
},
day: {
type: DataTypes.INTEGER,
allowNull: false,
unique: false,
},
});
// Transaction.associate = function (models) {
// Transaction.belongsTo(models.Account);
// };
Transaction.associate = function(models) {
Transaction.belongsTo(models.Account, {
foreignKey: 'UserId',
});
};
return Transaction;
};
my route to select accounts associated to transactions
const express = require("express");
const router = express.Router();
const { Account } = require("../models");
const {Transactions} = require("../models")
router.get("/", async (req, res) => {
try {
const users = await Account.findAll({
include:[
{
modal : Transactions,
}
]
});
res.json(users);
} catch (error) {
console.error(error);
res.status(500).send({ err: "Error fetching users",error: error });
}
});
i am facing this error
Error: Include unexpected. Element has to be either a Model, an Association or an object.
at Account._conformInclude (S:\test\server\node_modules\sequelize\lib\model.js:323:11)
at S:\test\server\node_modules\sequelize\lib\model.js:270:61
at Array.map (<anonymous>)
at Account._conformIncludes (S:\test\server\node_modules\sequelize\lib\model.js:270:39)
at Account._baseMerge (S:\test\server\node_modules\sequelize\lib\model.js:622:10)
at Account._defaultsOptions (S:\test\server\node_modules\sequelize\lib\model.js:656:17)
at Account._injectScope (S:\test\server\node_modules\sequelize\lib\model.js:2001:10)
at Account.findAll (S:\test\server\node_modules\sequelize\lib\model.js:1105:10)
at S:\test\server\routes\Transactions.js:8:33 at Layer.handle [as handle_request] (S:\test\server\node_modules\express\lib\router\layer.js:95:5)
i want i have tried to get users and accounts it works but account and their transactions failed please help
this is working
const { Op } = require('sequelize');
const express = require("express");
const router = express.Router();
const { Account, Users } = require("../models");
router.get("/", async (req, res) => {
try {
const accounts = await Users.findAll({
attributes: ["fullName", "status"],
include: [
{
model: Account,
where: {
UserId: {
[Op.not]: null
}
}
},
],
});
res.json(accounts);
} catch (error) {
console.log(error);
res.status(500).send({ error: error });
}
});
Thanks you so much

NodeJs Join two tables using sequalize and retrieve the data in Controller

I have two model classes in separate files as below,
module.exports = (sequelize, Sequelize) => {
return sequelize.define(
"course",
{
id: {
type: Sequelize.STRING,
primaryKey: true,
field: 'ID',
},
title: {
type: Sequelize.STRING,
field: 'TITLE'
}
},
{
timestamps: false,
freezeTableName: true,
underscored: true
},
);
};
module.exports = (sequelize, Sequelize) => {
return sequelize.define(
"student",
{
id: {
type: Sequelize.STRING,
primaryKey: true,
field: 'ID',
},
courseId: {
type: Sequelize.STRING,
field: 'COURSE_ID'
}
},
{
timestamps: false,
freezeTableName: true,
underscored: true
},
);
};
And in the controller I have written like this.
const db = require("../config/sequelize.config");
const course = db.course;
const student= db.student;
student.belongsTo(course, {foreignKey: 'courseId', targetKey: 'id'});
exports.findStudentData = (req, res) => {
return student.findOne({ limit: 1 },
{
include : [{
model: course
}]}).then(data => {
res.send(data);
}).
catch(err => {
res.status(500).send({
message:
err.message || "Some error occurred."
});
});
};
Here I need to get course data along with student data. When I ran the code it only gives me the student data without course details. I'm not sure If I have added the following statement correct
student.belongsTo(course, {foreignKey: 'courseId', targetKey: 'id'});

Sequelize: Error creating a post and associating it with the current user

I get an error creating a post and trying to associate it with the current user:
SequelizeDatabaseError: Field 'userId' doesn't have a default value
this is my method
exports.createPost = async (req, res) => {
const {title, content, userEmail} = req.body;
const user = await User.findOne({
where: {
email: userEmail
}
})
if (user) {
const post = await Post.create({
title, content, image: req.file.originalname, userId: user.id
})
res.json(post)
}
}
Tried with user: user as well.
This is my user model
'use strict';
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define('User', {
username: DataTypes.STRING,
email: DataTypes.STRING,
password: DataTypes.STRING
}, {});
User.associate = function(models) {
User.hasMany(models.Post)
};
return User;
};
This is the post model, where the belongsTo relation is declared
'use strict';
module.exports = (sequelize, DataTypes) => {
const Post = sequelize.define('Post', {
title: DataTypes.STRING,
content: DataTypes.STRING,
image: DataTypes.STRING
}, {});
Post.associate = function(models) {
Post.belongsTo(models.User, {
onDelete: 'CASCADE'
})
};
return Post;
};
you have not define association in right way . you can do like this .
User Model
'use strict';
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define('User', {
id: {
type: DataTypes.INT,
autoIncrement: true,
primaryKey: true,
},
username: DataTypes.STRING,
email: DataTypes.STRING,
password: DataTypes.STRING
}, {});
User.associate = function (models) {
User.hasMany(models.Post, {
foreignKey: 'userId',
onDelete: 'CASCADE'
})
};
return User;
};
Post Model
'use strict';
module.exports = (sequelize, DataTypes) => {
const Post = sequelize.define('Post', {
id: {
type: DataTypes.INT,
autoIncrement: true,
primaryKey: true,
},
userId: DataTypes.INT,
title: DataTypes.STRING,
content: DataTypes.STRING,
image: DataTypes.STRING
}, {});
Post.associate = function (models) {
Post.belongsTo(models.User, {
foreignKey: 'userId',
onDelete: 'CASCADE'
})
};
return Post;
};
Query be Like :
const { title, content, userEmail } = req.body;
const user = await User.findOne({
where: {
email: userEmail
},
raw: true
})
if (user) {
const post = await Post.create({
title, content, image: req.file.originalname, userId: user.id
})
res.json(post)
}

How to build model with sequelize for belong to many association

This is what I wrote in Country.js (exactly the same as User.js except datatypes) :
module.exports = function(sequelize, DataTypes) {
const Country = sequelize.define('country',
{
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
code: {
type: DataTypes.INTEGER
},
alpha2: {
type: DataTypes.STRING
},
alpha3: {
type: DataTypes.STRING
},
name_en: {
type: DataTypes.STRING
},
name_fr: {
type: DataTypes.STRING
}
},
{
freezeTableName: true,
timestamps: false
});
Country.associate = ( models ) => {
models.Country.belongsToMany(models.User, {
through: 'country_user',
as: 'user',
foreignKey: 'id_country'
});
};
return Country;
}
This is my query :
router.get('/thisuserCountries', function(req, res, next){
User(db, Sequelize.DataTypes).findOne({
include: [{
model: Country(db, Sequelize.DataTypes),
as: 'countries',
required: false,
attributes: ['id'],
}],
where: {
email: 'jerome.charlat#gmail.com'
}
})
.then(user => {
if(user) {
res.json(user)
}
else {
res.send('User does not exist')
}
})
.catch(err => {
res.send('error: ' + err)
})
})
This is my db.js :
const Sequelize = require('sequelize')
const db = new Sequelize('travel_memories', 'root', '', {
host: 'localhost',
dialect: 'mysql',
port: 3306
})
db
.authenticate()
.then(() => {
console.log('Connection has been established successfully.');
})
.catch(err => {
console.error('Unable to connect to the database:', err);
});
const models = {
Country: db.import('../models/Country'),
User: db.import('../models/User'),
CountryUserJoin: db.import('../models/Country_user')
};
Object.keys(models).forEach((modelName) => {
if('associate' in models[modelName]){
models[modelName].associate(models);
}
});
module.exports = db
Postman says : error SequelizeEagerLoadingError: country is not associated to user!
But, I think I should write in the through parameter the model User_country when I associate tables in each model. So i tried to write something like :
Country.associate = ( models ) => {
models.Country.belongsToMany(models.User, {
through: models.Country_user,
as: 'user',
foreignKey: 'id_country'
});
};
And console says when I launch server, before querying anything :
SequelizeAssociationError: country.belongsToMany(user) requires through option, pass either a string or a model.
So I am blocked. I used the example in documentation to write the assocation with models.foo. But in fact models comes from nowhere..
Thanks again for your help !
There's not a lot of documentation about this, but here it says that you should use a through option when querying or selecting belongs-to-many attributes, just like this:
...
User(db, Sequelize.DataTypes).findOne({
include: [{
model: Country(db, Sequelize.DataTypes),
as: 'countries',
required: false,
through: {
attributes: ['id']
}
}],
where: {
email: 'jerome.charlat#gmail.com'
}
})
...

Sequelize null value in column violates not-null constraint

I'm getting this error when trying to associate a like to a post.
Unhandled rejection SequelizeDatabaseError: null value in column
"userId" violates not-null constraint
Now the following code gets the post id and user id ok, i did a console log. What could i be doing wrong ?
routes/posts.js
router.post('/:userId/like/:postId', (req, res)=> {
models.Post.findOne({
where:{
id: req.params.postId
}
})
.then( (like) => {
if(like){
models.Likes.create({
where:{
userId: req.params.userId,
postId: req.params.postId
},
like:true
}).then( (result) => {
res.status(200).send({
message: 'You have like this post',
like: result
})
})
}
}).catch( (err) => {
res.status(401).send({
message: "Something went wrong",
err: err
})
})
})
here is the likes migration
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('Likes', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
like: {
type: Sequelize.BOOLEAN
},
userId: {
allowNull: false,
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('Likes');
}
};
Posts migration
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('Posts', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
title: {
type: Sequelize.STRING
},
post_content: {
type: Sequelize.STRING
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
},
userId: {
type: Sequelize.INTEGER,
references: {
model: 'Users',
key: 'id'
}
},
username: {
type: Sequelize.STRING
},
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('Posts');
}
};
Like model
'use strict';
module.exports = function(sequelize, DataTypes) {
const Like = sequelize.define('Likes', {
like:{
type:DataTypes.BOOLEAN,
allowNull:true
}
}, {});
Like.associate = function(models) {
Like.belongsTo(models.User, {
onDelete: "CASCADE",
sourceKey: 'userId'
})
Like.belongsTo(models.Post, {
onDelete: "CASCADE",
sourceKey: 'likeId'
})
}
return Like;
}
Post.model
module.exports = (sequelize, DataTypes) => {
const Post = sequelize.define('Post', {
title: DataTypes.STRING,
post_content: DataTypes.STRING,
username: DataTypes.STRING
}, {});
Post.associate = function(models) {
Post.belongsTo(models.User, { foreignKey: 'userId', targetKey: 'id' });
Post.hasMany(models.Likes, { foreignKey: 'postId', sourceKey: 'id' });
};
return Post;
};
extra
add_postId_to_likes
'use strict';
module.exports = {
up: function (queryInterface, Sequelize) {
return queryInterface.addColumn(
'Likes',
'postId',
{
type: Sequelize.INTEGER,
allowNull: true,
references: {
model: 'Posts',
key: 'id',
}
}
)
},
down: function (queryInterface, Sequelize) {
return queryInterface.removeColumn(
'Likes',
'postId'
)
}
};
In your create call in resolver you are not giving it the necessary values, you have a where clause but not actually giving it the value for required userId.. looks like the only value in your model is the Boolean you are setting
I figured it out.
I just used body instead of params for the postId.
router.post('/like', (req, res)=> {
models.Likes.create({
postId: req.body.postId,
userId: req.user.id,
like:true
}).then( (result) => {
res.status(200).send({
message: 'You have like this post',
like: result
});
}).catch( (err) => {
res.status(401).send({
message: "Something went wrong",
err: err
})
})
})
change my like model to this, i was using sourceKey instead of foreign keys
module.exports = function(sequelize, DataTypes) {
const Like = sequelize.define('Likes', {
like:{
type:DataTypes.BOOLEAN,
allowNull:true
},
// userId: {
// type: sequelize.INTEGER,
// references: {
// model: 'Users',
// key: 'id'
// }
// },
}, {});
Like.associate = function(models) {
Like.belongsTo(models.User, {
onDelete: "CASCADE",
foreignKey: 'userId'
})
Like.belongsTo(models.Post, {
onDelete: "CASCADE",
foreignKey: 'likeId'
})
}
return Like;
}
So now i can like a post, and it will attach the postId along with the usersId on the likes table.
like this

Resources