I have two models Doctor and Degree with many to many relationship.
Doctor model:
const Doctor = _sequelize.define('doctor', {
fullname: {
type: Sequelize.STRING,
allowNull: false
},
email: {
type: Sequelize.STRING,
allowNull: false
},
password: {
type: Sequelize.STRING,
allowNull: false
},
gender: {
type: Sequelize.STRING
},
address: {
type: Sequelize.STRING
},
phone: {
type: Sequelize.STRING
},
avatarurl: {
type: Sequelize.STRING
},
active: {
type: Sequelize.BOOLEAN,
defaultValue: true
},
license: {
type: Sequelize.STRING
}
},{
timestamps: false,
tableName: 'doctor'
})
Doctor.associate = (models) => {
Doctor.belongsToMany(model.degree, { through: 'doctor_degree', foreignKey: 'doctor_id',as: 'degree' })
}
Degree model:
const Degree = _sequelize.define('degree', {
name: {
type: Sequelize.STRING
}
},{
timestamps: false,
tableName: 'degree'
})
Degree.associate = (models) => {
Degree.belongsToMany(models.doctor, { through: 'doctor_degree', foreignKey: 'degree_id' })
};
Doctor_Degree model:
const Doctor_Degree = _sequelize.define('doctor_degree', {
doctor_id: {
type: Sequelize.STRING,
allowNull: false,
references: {
model: 'doctor',
key: 'id'
}
},
degree_id: {
type: Sequelize.STRING,
allowNull: false,
references: {
model: 'degree',
key: 'id'
}
}
},{
timestamps: false,
tableName: 'doctor_degree'
});
And I have a service to find all doctor with degree
var result;
try{
await doctorModel.findAll({
attributes: ['id','fullname', 'email','gender','address','phone','avatarurl','active','license'],
include: [{
model: degreeModel,
as: 'degree'
}]
}).then((doctors) => {
result = doctors
})
}
catch(err){
throw err
}
return result
But i got the following error:
[SequelizeEagerLoadingError]: degree is not associated to doctor!
Can anyone suggest what I am doing wrong?
Related
How can I belongsToMany two different columns in the same table with the ID in a different table?
User Model
id: {
primaryKey: true,
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4
},
firstName: {
type: DataTypes.STRING(255)
}
Message Model
id: {
primaryKey: true,
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4
},
userId1: {
type: DataTypes.UUID
},
userId2: {
type: DataTypes.UUID
}
belongsTo
thisModel.belongsTo(userModel, {
foreignKey: 'userId1',
foreignKey: 'userId2' // How can add this one here
})
Suppose your case is a message has a sender(userId1) and a receiver(userId2). Below code will work for this case:
const User = sequelize.define('user', {
id: {
primaryKey: true,
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4
},
firstName: {
type: DataTypes.STRING(255)
}
});
const Message = sequelize.define('message', {
id: {
primaryKey: true,
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4
},
text: {
type: DataTypes.STRING
},
userId1: {
type: DataTypes.UUID
},
userId2: {
type: DataTypes.UUID
}
});
// define the association
User.hasMany(Message, {
foreignKey: 'userId1',
as: 'sender'
})
User.hasMany(Message, {
foreignKey: 'userId2',
as: 'receiver'
})
Message.belongsTo(User, {
foreignKey: 'userId1',
as: 'sender'
});
Message.belongsTo(User, {
foreignKey: 'userId2',
as: 'receiver'
});
// Example using the association
sequelize.sync({
force: true
})
.then(async () => {
// create some users
await User.bulkCreate([
{ firstName: 'user1'},
{ firstName: 'user2'}
])
const users = await User.findAll()
const [user1, user2] = users
const message = await Message.create({
text: 'hello'
})
await message.setSender(user1)
await message.setReceiver(user2)
console.log(message)
})
I am trying to search user that not in the team yet to invite them but right now my function is searching user that in the team only. So now how can I implement the function to search user that not in the team yet.
Here is my following code:
exports.searchUserToInvite = async (req, res) => {
// Grab query
const query = req.params.q;
const publicTeamId = req.params.id;
const teamId = await getTeamId(publicTeamId);
// Get team data based on id
// Search for users
const usersFound = await models.User.findAll({
where: {
[Op.or]: [
{
fullname: {
[Op.iLike]: "%" + query + "%",
},
},
],
},
attributes: [
"fullname",
"public_user_id",
"institution",
"location",
"webpage",
"linkedin",
"major",
"picture",
"verifiedDT",
],
include: [
{
model: models.Rating,
attributes: ["skillset_rating", "team_member_rating"],
},
{
model: models.Skill,
attributes: ["skill"],
},
{
model: models.Team,
attributes: ["status"],
where: {
id: teamId,
},
},
],
});
// Run searches
const searchData = await Promise.all([usersFound]);
// Return results
res.status(200).json(searchData);
};
Update add following code model User:
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define(
"User",
{
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
allowNull: false,
},
fullname: {
type: DataTypes.STRING,
allowNull: false,
},
passwordhash: DataTypes.STRING,
institution: DataTypes.STRING,
bio: DataTypes.STRING,
creator_user_id: DataTypes.UUID,
public_user_id: DataTypes.STRING,
picture: DataTypes.STRING(300),
email: { type: DataTypes.STRING, unique: true },
service: DataTypes.STRING,
gender: DataTypes.STRING,
age: DataTypes.INTEGER ,
altId: DataTypes.STRING,
location: DataTypes.STRING,
mergedTo: DataTypes.UUID,
document: DataTypes.STRING,
webpage: DataTypes.STRING,
linkedin: DataTypes.STRING,
signupIP: DataTypes.STRING,
major: DataTypes.STRING,
verifiedDT: DataTypes.DATE,
couponsUsed: DataTypes.ARRAY(DataTypes.STRING),
teamCredits: DataTypes.INTEGER ,
resetToken: DataTypes.STRING,
resetTokenExpires: DataTypes.DATE,
uniqueToken: DataTypes.STRING,
expireToken: DataTypes.DATE,
},
{
tableName: "Users",
timestamps: true,
indexes: [
{
unique: false,
fields: ["email", "id", "fullname", "public_user_id"],
},
],
}
);
User.associate = function (models) {
User.belongsToMany(models.Skill, { through: models.UserSkills });
User.hasMany(models.Team, {
foreignKey: "creatorId",
});
User.hasMany(models.Membership, {
foreignKey: "memberId",
});
User.hasMany(models.Rating, {
foreignKey: "raterId",
});
User.hasMany(models.Rating, {
foreignKey: "rateeId",
});
User.hasMany(models.InvitesApplications, {
foreignKey: "senderId",
});
User.hasMany(models.Message, {
foreignKey: "userID"
});
};
return User;
};
How can I implement my function?
Updated add model Membership in question:
"use strict";
module.exports = (sequelize, DataTypes) => {
const Membership = sequelize.define(
"Membership",
{
interests: DataTypes.STRING,
contributions: DataTypes.STRING,
authorization: DataTypes.STRING,
status: DataTypes.STRING,
application_letter: DataTypes.STRING,
date_applied: DataTypes.DATE,
date_joined: DataTypes.DATE,
date_departed: DataTypes.DATE
},
{ tableName: "Memberships", timestamps: true }
);
Membership.associate = function(models) {
Membership.belongsTo(models.User, {
foreignKey: "memberId"
});
Membership.belongsTo(models.Team, {
foreignKey: "teamId"
});
Membership.belongsTo(models.Role, {
foreignKey: "roleId"
});
Membership.hasMany(models.Rating, {
foreignKey: "membershipId"
});
};
return Membership;
};
Updated add model User in question:
you need to apply not equal to in where clause.
where: {
id: {[Op.ne]: teamId},
},
I'm using nodejs and Sequelize
I have two models like
user-plan.model.js
class UserPlan extends Sequelize.Model {
}
UserPlan.init({
id: {
type: Sequelize.INTEGER,
allowNull: false,
primaryKey: true
},
user_id: {
type: Sequelize.INTEGER,
allowNull: false
},
plan_id: {
type: Sequelize.INTEGER,
allowNull: false
},
expire: {
type: Sequelize.DATE,
allowNull: true
},
active: {
type: Sequelize.BOOLEAN,
allowNull: true
}
}, {
sequelize,
modelName: 'user_plan',
tableName: 'plans_userplan'
});
quota.model.js
class Quota extends Model {
}
Quota.init({
id: {
type: Sequelize.INTEGER,
allowNull: false,
primaryKey: true
},
codename: {
type: Sequelize.STRING,
allowNull: false
}
}, {
sequelize,
modelName: 'quota',
tableName: 'plans_quota'
});
These two tables are joined through a third table
plan-quota.model.js
class PlanQuota extends Model {
}
PlanQuota.init({
id: {
type: Sequelize.INTEGER,
primaryKey: true,
allowNull: false
},
value: {
type: Sequelize.INTEGER,
allowNull: false,
},
plan_id: {
type: Sequelize.STRING,
allowNull: false
},
quota_id: {
type: Sequelize.STRING,
allowNull: false
}
}, {
sequelize,
modelName: 'plan_quota',
tableName: 'plans_planquota'
});
The PlanQuota table has link to the UserPlan using plan_id and Quota table using quota_id.
User.findOne({
where: {
'id': user_id
},
include: [
{
model: UserPlan,
include: [
{
model: PlanQuota
}
]
}
]
}).then(d => {
console.log('d: ', d);
});
The UserPlan is associated with User model, and I'm able to include the UserPlan using User.
But how Can I include PlanQuota and the Quota using the join?
I think you need to "include" the associated model, not the junction table:
User.findOne({
where: {
'id': user_id
},
include: [
{
model: UserPlan,
include: [
{
model: Qouta//This is the change
}
]
}
]
}).then(d => {
console.log('d: ', d);
});
Do you have your associations setup? like:
UserPlan.belongsToMany(Qouta, { through: PlanQuota });
Qouta.belongsToMany(UserPlan, { through: PlanQuota });
I have the following error:
Unhandled rejection Error: Cyclic dependency found. coupons is
dependent of itself. Dependency chain: coupons -> orders => coupons
My order.js model looks like as follows:
'use strict';
module.exports = (sequelize, DataTypes) =>
{
var Order = sequelize.define('orders',
{
id:
{
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER
},
userid:
{
type: DataTypes.INTEGER,
references:
{
model: 'users',
key: 'id'
}
},
coupon_id:
{
type: DataTypes.INTEGER,
allowNull: true,
references:
{
model: 'coupons',
key: 'id'
},
},
product:
{
type: DataTypes.INTEGER,
references:
{
model: 'products',
key: 'id'
}
},
address:
{
type: DataTypes.INTEGER,
references:
{
model: 'address',
key: 'id'
}
},
canceled:
{
type: DataTypes.INTEGER,
defaultValue: 0
},
quantity:
{
type: DataTypes.INTEGER,
},
note:
{
allowNull: true,
type: DataTypes.STRING
},
},
{
freezeTableName: true,
tableName: 'orders',
createdAt: 'createdat',
updatedAt: 'updatedat',
});
Order.associate = models => {
Order.hasMany(models.coupons, {
foreignKey: 'id',
onDelete: 'cascade',
onUpdate: 'cascade',
constrains: false
});
};
return Order;
};
and coupon.js looks like this:
'use strict';
module.exports = (sequelize, DataTypes) =>
{
var Coupon = sequelize.define('coupons',
{
id:
{
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER
},
name:
{
type: DataTypes.STRING
},
code:
{
type: DataTypes.STRING
},
discount:
{
type: DataTypes.FLOAT
},
expires:
{
type: 'TIMESTAMP',
},
created_by:
{
type: DataTypes.INTEGER,
references:
{
model: 'users',
key: 'id'
},
},
maxuse:
{
type: DataTypes.INTEGER,
},
},
{
freezeTableName: true,
tableName: 'coupons',
createdAt: 'createdat',
updatedAt: 'updatedat'
});
Coupon.associate = models => {
Coupon.belongsTo(models.orders,
{
foreignKey: 'id',
onDelete: 'cascade',
onUpdate: 'cascade',
});
};
return Coupon;
};
It seems that I am doing something wrong with the associations. Any help would be appreciated.
NOTE: Everytime I comment out coupon_id: on orders.js, the error goes out. Still, I need this functionality.
I am considering these 2 tables "exam_response" and "answer" for hasMany association.
Where both the tables contains "question_id". Using question_id I need the answers.
exam_response table
module.exports = (sequelize, DataTypes) => {
const exam_response = sequelize.define('exam_response', {
id: {
allowNull: false,
primaryKey: true,
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4
},
session_id: {
type: DataTypes.UUID,
allowNull: false
},
exam_id: {
type: DataTypes.UUID,
allowNull: false
},
user_id: {
type: DataTypes.UUID,
allowNull: false
},
question_id: {
type: DataTypes.UUID,
allowNull: false
},
answer_ids: {
type: DataTypes.ARRAY(DataTypes.UUID),
allowNull: false
},
is_correct: {
type: DataTypes.BOOLEAN,
allowNull: false
},
is_bookmarked: {
type: DataTypes.BOOLEAN,
allowNull: false
},
is_attempted: {
type: DataTypes.BOOLEAN,
allowNull: false
},
createdAt: {
type: DataTypes.DATE,
field: 'created_at'
},
updatedAt: {
type: DataTypes.DATE,
field: 'updated_at'
}
}, {});
exam_response.associate = function (models) {
// associations can be defined here
exam_response.hasMany(models.answer, {
foreignKey: 'question_id', sourceKey: 'question_id',as:'exam_answers'
});
};
answer table
'use strict';
module.exports = (sequelize, DataTypes) => {
const answer = sequelize.define('answer', {
//{
// "id":"",
// "question_id":"123",
// "position":0,
// "answer":"This is answer 1."
// }
id: {
allowNull: false,
primaryKey: true,
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4
},
question_id: {
allowNull: false,
type: DataTypes.UUID
},
position: {
allowNull: false,
type: DataTypes.INTEGER
},
answer: {
allowNull: false,
type: DataTypes.TEXT
},
publish_status: {
allowNull: false,
type: DataTypes.ENUM('published', 'unpublished', 'deleted')
},
language: {
type: DataTypes.ENUM('en', 'kn', 'hi')
},
createdAt: {
type: DataTypes.DATE,
field: 'created_at'
},
updatedAt: {
type: DataTypes.DATE,
field: 'updated_at'
}
}, {});
answer.associate = models => {
answer.belongsTo(models.question,{foreignKey:'question_id',as:'answers'});
answer.belongsTo(models.exam_response,{foreignKey:'question_id', targetKey: 'question_id',as:'exam_answers'});
};
return answer;
};
Query::
ExamResponse.findAll({
where: {
exam_id
},
include: [
{
model: Answer,as:'exam_answers'
}
],
}).then(resp => {
response.successGet(res, resp, 'Exam Response');
}).catch(next)
I am getting the output but associated part("exam_answers") is empty.
If I use raw query, i am able to get the output. But the Query is only fetching me the exam_response not the answer even though the value exists.