I have a customer table which consist few columns along with password column in sequelize mysql
When I edit/update the customer if the user doesn't provide the password in the request it should not update the password column at all (should remain untouched).
How can I accomplish such program inside the customer schema page?
I am using following method to update the table:
db.customers.findOne({
where: {
id: req.body.id
}
}).then(data => {
data.update({
cash_credit: req.body.cash_credit,
name: req.body.name,
address: req.body.address,
state_id: req.body.state_id,
gstin: req.body.gstin,
mobile: req.body.mobile,
phone: req.body.phone,
email: req.body.email,
form_type: req.body.form_type,
pincode: req.body.pincode,
password: req.body.password, // omit
city_id: req.body.city_id,
country: req.body.country || 0,
id: req.body.id
}).then(data2 => {
console.log(data2);
});
});
Here is my customer schema:
const bcrypt = require("bcrypt");
module.exports = function (sequelize, DataTypes) {
const customers = sequelize.define("customers", {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
field: "SupplierCode"
},
customer_type: {
type: DataTypes.INTEGER,
},
cash_credit: {
type: DataTypes.STRING,
},
...
}, {
hooks: {
// eslint-disable-next-line no-unused-vars
beforeValidate: function (value, option) {
value.zip = parseInt(value.dataValues.zip);
},
beforeCreate: async (schema) => {
let hashedPassword = await bcrypt.hash(schema.password, saltRounds);
schema.password = hashedPassword;
console.log(schema.password);
},
beforeUpdate: async (schema) => {
if (schema.password) {
let hashedPassword = await bcrypt.hash(schema.password, saltRounds);
schema.password = hashedPassword;
}
}
},
timestamps: false,
defaultScope: {
attributes: {
exclude: ["password"]
}
},
scopes: {
withPassword: {
attributes: {
include: ["password"]
}
}
}
});
}
As far as I remember Sequelize won't update a field that you have not provided. So if the password is not defined, just don't pass it to the update call.
const updateData = {
cash_credit: req.body.cash_credit,
name: req.body.name,
address: req.body.address,
state_id: req.body.state_id,
gstin: req.body.gstin,
mobile: req.body.mobile,
phone: req.body.phone,
email: req.body.email,
form_type: req.body.form_type,
pincode: req.body.pincode,
city_id: req.body.city_id,
country: req.body.country || 0,
id: req.body.id
}
if (req.body.password) {
updateData.password = req.body.password;
}
data.update(updateData).then(console.log);
Related
I would like to increment points by 1000 when visits of user become 1. I am incrementing visits by 1 whenever loginUser() function gets called.
this is my async loginUser function
async function loginUser(event) {
event.preventDefault()
const response = await fetch('http://localhost:1337/api/login', {
method: 'POST',
headers:{
'Content-Type': 'application/json',
},
body: JSON.stringify({
email,
password,
}),
})
server.js
app.post('/api/login', async (req, res) => {
await User.findOneAndUpdate(
{email: req.body.email},
{$inc :{visits : 1}},
)
const isPasswordValid = await bcrypt.compare(
req.body.password,
user.password
)
if (isPasswordValid) {
const token = jwt.sign(
{
name: user.name,
email: user.email,
},
'secret123'
)
return res.json({ status: 'ok', user: token })
} else {
return res.json({ status: 'error', user: false })
}
})
user.model.js
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/poker')
const User = new mongoose.Schema(
{
name: { type: String, required: true },
email: { type: String, required: true, unique: true},
password: { type: String, required: true },
points: { type: Number, required: true, default: 0},
visits: { type: Number, required: true, default: 0}
},
{ collectiopn: 'user-data' }
)
const model = mongoose.model('UserData', User)
module.exports = model
I've tried to put
if (req.body.visits == 1){
await User.findOneAndUpdate(
{email: req.body.email},
{$inc :{points: 1000}},
)
}
and it returns undefined for req.body.visits
Can anyone help?
Thank you
I am trying to fetch data from DB with sequelize. The many to many relationships between users and roles. When i fetch the users does not include the roles.
The code look like:
user model
// model defines the user objects
const userModel = (sequelize, Sequelize) => {
const users = sequelize.define("user", {
id: {
type: Sequelize.STRING,
allowNull: false,
primaryKey: true,
},
firstname: {
allowNull: false,
type: Sequelize.STRING,
},
lastname: {
allowNull: false,
type: Sequelize.STRING,
},
password: {
allowNull: false,
type: Sequelize.STRING,
},
email: {
allowNull: false,
type: Sequelize.STRING,
},
image: {
allowNull: true,
type: Sequelize.STRING,
},
});
//don not show password and id
users.prototype.toJSON = function () {
let values = Object.assign({}, this.get());
delete values.password;
delete values.id;
return values;
};
return users;
};
export default userModel;
Roles model
// model defines the events objects
const rolesModel = (sequelize, Sequelize) => {
const roles = sequelize.define("roles", {
id: {
type: Sequelize.STRING,
allowNull: false,
primaryKey: true,
},
name: {
allowNull: false,
type: Sequelize.STRING,
},
description: {
allowNull: true,
type: Sequelize.STRING,
},
});
return roles;
};
export default rolesModel;
The associations:
db.users.associate = (db) => {
db.users.belongsToMany(db.roles, {
through: "userroles",
constraints: false,
foreignKey: "rolesId",
});
};
db.roles.associate = (db) => {
db.roles.belongsToMany(db.users, {
through: "userroles",
constraints: false,
foreignKey: "userId",
});
};
There are two controller functions that are adding and fetching the user data
Controller
User.create(userDetails)
.then(() => {
let roles = req.body.roles;
roles.forEach(async (element) => {
let role = await Roles.findByPk(element);
if (role) {
await Userroles.create({
id: uniqid(),
rolesId: element,
userId: userId,
});
} else {
logger.warn(`tried adding to ${userId} a none existent role`);
}
});
})
// get user
let user = await User.findOne({
where: { email: username },
include: { model: db.roles },
});
So the roles are only a empty array when I try getting user details:
"firstname": "Mathew",
"lastname": "Murimi",
"email": "******#gmail.com",
"image": null,
"createdAt": "2022-02-12T22:56:40.000Z",
"updatedAt": "2022-02-12T22:56:40.000Z",
"roles": []
Receive the user created in the then, add the id of "newUser" in "userId"
User.create(userDetails)
.then((**newUser**) => {
let roles = req.body.roles;
roles.forEach(async (element) => {
let role = await Roles.findByPk(element);
if (role) {
await Userroles.create({
id: uniqid(),
rolesId: element,
userId: **newUser.id**,
});
} else {
logger.warn(`tried adding to ${**newUser.id**} a none existent role`);
}
});
})
I was trying to create HRM project using Node and Mongodb (Mongoose) with leave management so for the leave I have created two documents 1. for leavetypes i.e anualLeave, maternityLeave and so on and the other one of taking care of the leave requests taken by the employees.
So here is my schemas and api requests.
// leave schema embedded in leaveTypeSchema
const mongoose = require("mongoose");
const Joi = require("joi-browser");
Joi.objectId = require("joi-objectid")(Joi);
const { branchSchema } = require("./branch");
const { employeeSchema } = require("./employee");
const { leaveTypesSchema } = require("./leaveType");
const leaveSchema = mongoose.Schema({
branch: {
type: branchSchema,
required: true,
},
employee: {
type: employeeSchema,
required: true,
},
leaveType: {
type: [leaveTypesSchema],
required: true,
},
daysRequested: {
type: Number,
required: true,
},
fromDate: {
type: Date,
required: true,
},
endDate: {
type: Date,
required: true,
},
availableDays: {
type: Number,
},
});
const Leave = mongoose.model("leave", leaveSchema);
//validation
function validateLeave(leave) {
const schema = {
branchId: Joi.objectId().required(),
employeeId: Joi.objectId().required(),
leaveType: Joi.object()
.keys({
anualLeave: Joi.object()
.keys({
id: Joi.objectId().required(),
})
.required(),
})
.required(),
daysRequested: Joi.number().required(),
fromDate: Joi.date().required(),
endDate: Joi.date().required(),
};
return Joi.validate(leave, schema);
}
module.exports.Leave = Leave;
module.exports.Validate = validateLeave;
//route to post leave requests from employees
router.post("/", async (req, res) => {
// validate
const { error } = Validate(req.body);
if (error) return res.status(400).send(error.details[0].message);
// check if branch is valid
let branch = await Branch.findById(req.body.branchId);
if (!branch) return res.status(400).send("Invalid Branch");
// check if employee is valid
let employee = await Employee.findById(req.body.employeeId);
if (!employee) return res.status(400).send("Invalid employee");
// check if leaveType is valid
let leaveType = await LeaveType.findById({
id: ObjectID(req.body.leaveType.anualLeave.id),
});
if (!leaveType) return res.status(400).send("invalid leave Type");
// post the leave request
const leave = new Leave({
branch: {
_id: branch._id,
name: branch.name,
},
employee: {
_id: employee._id,
fullName: employee.fullName,
phoneNumber: employee.phoneNumber,
branch: {
_id: branch._id,
name: branch.name,
},
jobTitle: employee.jobTitle,
salary: employee.salary,
},
leaveType: [
{
anualLeave: {
id: leaveType.anualLeave.id,
},
},
],
daysRequested: req.body.daysRequested,
fromDate: req.body.fromDate,
endDate: req.body.endDate,
});
await leave.save();
res.send(leave);
Your document doesn't abide by the way you have created your schema.
When you are passing data to model, you have made leavetype nested inside employee
const leave = new Leave({
/**/
employee: {
_id: employee._id,
fullName: employee.fullName,
phoneNumber: employee.phoneNumber,
branch: {
_id: branch._id,
name: branch.name,
}, <- here
leaveType: [
{
anualLeave: {
id: leaveType.anualLeave.id,
},
},
],
});
whereas in the schema your leaveType is a diff. object property.
employee: {
type: employeeSchema,
required: true,
},
leaveType: {
type: [leaveTypesSchema],
required: true,
},
I am new to backend development And I am facing some issues with connecting User model with Profile model. And I also want to auto-generate username in profile model when user sets them in User model. I am not sure how to do this. Here is my code
Resolver.js
Mutation: {
signUpUser: async (parent, { userInput }) => {
const { email, username, password } = userInput;
const errors = [];
if (!validator.isEmail(email)) {
errors.push({
message: "Invalid Email",
});
}
const existingUser = await User.findOne({ email: email });
if (existingUser) {
const error = new Error("User exists already");
throw error;
}
if (errors.length > 0) {
const error = new Error("Invalid Input");
error.data = errors;
error.code = 402;
throw error;
}
const hashedPassword = await bcrypt.hash(password, 12);
const user = new User({
email: email,
password: hashedPassword,
username: username,
});
const createdUser = await user.save();
return {
...createdUser._doc,
_id: createdUser._id.toString(),
};
},
UserModel
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const userSchema = new mongoose.Schema(
{
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
username: {
type: String,
required: true,
},
status: {
type: String,
default: "I am new!",
},
posts: [
{
type: Schema.Types.ObjectId,
ref: "Post",
},
],
profile: {
type: Schema.Types.ObjectId,
ref: "Profile",
},
},
{ timestamps: true }
);
module.exports = mongoose.model("User", userSchema);
ProfileModel
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const profileSchema = new mongoose.Schema(
{
firstName: {
type: String,
default: null,
},
lastName: {
type: String,
default: null,
},
bio: {
type: String,
default: null,
},
profilePic: {
type: String,
default: null,
},
username: {
type: String,
default: null,
},
url: {
type: String,
default: null,
},
user: {
type: Schema.Types.ObjectId,
ref: "User",
}
},
{ timestamps: true }
);
module.exports = mongoose.model("Profile", profileSchema);
Here is the complete code if you like to give it a look
https://github.com/adityakmr7/medium-clone
Any help would be great. Thank you.
I am using Graphql here and apollo.
Newbie in sequelize.js
I have two models: User and Organization and I am trying to simulate A user can be admin of one organization, organization can have only one admin (one-to-one) association using belongsTo().
Here is how models are defined:
const User = sequelize.define(
"User",
{
firstName: Sequelize.STRING,
lastName: Sequelize.STRING
},
{ underscored: true }
);
const Organization = sequelize.define(
"Organization",
{
name: Sequelize.STRING
},
{ underscored: true }
);
Organization.belongsTo(User, {
as: "admin",
foreignKey: {
allowNull: false
}
});
Here is what I want to do in sequence:
Create a User.
Create an Organization and then set the created User as the admin.
The issue:
It does not let me specify an already existing user as admin.
Here is what I tried: (By looking at documentation and other examples)
1.
// step 1
await User.create({
firstName: "John",
lastName: "Doe"
});
// step 2
const adminToSet = await User.findOne({ where: { firstName: "John" } });
await Organization.create(
{
name: "my-awesome-organization",
User: adminToSet
},
{
include: [{ model: User, as: "admin" }]
}
);
It gives me error saying 'Organization.admin_id cannot be null'
2.
// step 1
await User.create({
firstName: "John",
lastName: "Doe"
});
// step 2
const adminToSet = await User.findOne({ where: { firstName: "John" } });
const org = Organization.build({
name: "my-awesome-organization"
});
org.setAdmin(adminToSet);
It gives me error saying id = id || results && results[0][this.getInsertIdField()]; (which seems to be of the mssql -> the dialect I am using)
Please help!
Here is the complete code snippet:
const Sequelize = require("sequelize");
const connectionOptions = {
username: "sa",
password: "Test#123",
dialect: "mssql",
host: "localhost",
port: 1433,
operatorsAliases: false,
benchmark: true,
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
},
// Dialect specific options. These will be passed to the db driver
dialectOptions: {
encrypt: false
}
};
const sequelize = new Sequelize(connectionOptions);
const User = sequelize.define(
"User",
{
firstName: Sequelize.STRING,
lastName: Sequelize.STRING
},
{ underscored: true }
);
const Organization = sequelize.define(
"Organization",
{
name: Sequelize.STRING
},
{ underscored: true }
);
Organization.belongsTo(User, {
as: "admin",
foreignKey: {
allowNull: false
}
});
const createUserAndOrganization = async () => {
// step 1
await User.create({
firstName: "John",
lastName: "Doe"
});
// step 2
const adminToSet = await User.findOne({ where: { firstName: "John" } });
const org = Organization.build({
name: "my-awesome-organization"
});
org.setAdmin(adminToSet);
};
const authenticated = async () => {
try {
await sequelize.sync({ force: true });
await createUserAndOrganization();
} catch (e) {
console.error(e);
}
};
sequelize
.authenticate()
.then(authenticated)
.catch(err => {
console.log(`[${err.name}]`, `[${err.original.code}]`, `${err.original.message}`);
});