我在express js中有一个函数可以更新我的项目,如下所示:
projectController.ts
export async function updateProjectStatus(req: Request, res: Response) {
try {
const projectCode = req.params.projectCode;
const { status } = req.body;
const updatedProject = await Project.findOneAndUpdate(
{ projectCode },
{ status },
{ new: true }
);
if (!updatedProject) {
return res.status(404).send('Project not found');
}
res.status(200).send(updatedProject);
} catch (error) {
let errorMessage = 'Failed to update project status';
if (error instanceof Error) {
errorMessage = error.message;
}
res.status(500).send({ message: errorMessage });
}
}
// PATCH: update project details
type ProjectKeys = keyof ProjectType;
const allowedUpdates: ProjectKeys[] = [
'name',
'budget',
'advance',
'clientName',
'clientPhone',
'clientEmail',
'clientAddress',
'clientDetails',
'endDate',
'demoLink',
'typeOfWeb',
'description',
];
export async function updateProjectDetails(req: Request, res: Response) {
const projectCode = req.params.projectCode;
const {
name,
budget,
advance,
clientName,
clientPhone,
clientEmail,
clientAddress,
clientDetails,
endDate,
demoLink,
typeOfWeb,
description,
} = req.body;
console.log(req.body);
console.log(projectCode);
// Extract valid updates from request body
const updates = Object.keys(req.body);
const isValidOperation = updates.every((update) => {
return allowedUpdates.includes(update as ProjectKeys);
});
if (!isValidOperation) {
return res.status(400).send({ error: 'Invalid updates!' });
}
try {
const project = await Project.findOne({ projectCode });
if (!project) {
return res.status(404).send({ error: 'Project not found' });
}
const updatedProject = await Project.findOneAndUpdate(
{ projectCode },
{
name,
budget,
advance,
clientName,
clientPhone,
clientEmail,
clientAddress,
clientDetails,
endDate,
demoLink,
typeOfWeb,
description,
},
{ new: true}
);
res.status(200).send(updatedProject);
} catch (error) {
res.status(500).send({
message:
error instanceof Error
? error.message
: 'Failed to update project details',
});
console.log(error);
}
}
在这里我获取更新的项目详细信息,然后找到该项目,然后更新它。在更新它时,我使用
runValidators: true
在我的项目模型中运行验证器。 我的 projectModel.ts
中有一些验证器,如下所示:
import mongoose from 'mongoose';
import { ProjectType } from '../types/projectDocumentType';
const projectSchema = new mongoose.Schema<ProjectType>(
{
projectCode: {
type: String,
required: true,
unique: true,
},
name: {
type: String,
required: true,
trim: true,
},
budget: {
type: Number,
required: true,
validate: {
validator: function (value: number) {
return value >= 0;
},
message: 'Budget must be a positive number',
},
},
advance: {
type: Number,
required: true,
validate: {
validator: function (value: number) {
return value >= 0 && value <= this.budget;
},
message:
'Advance must be a positive number and less than or equal to the budget',
},
},
due: {
type: Number,
validate: {
validator: function (value: number) {
return value >= 0 && value <= this.budget;
},
message:
'Due must be a positive number and less than or equal to the budget',
},
},
totalPaid: {
type: Number,
default: 0,
validate: {
validator: function (value: number) {
return value >= 0 && value <= this.budget;
},
message:
'Total Paid must be a positive number and less than or equal to the budget',
},
},
clientName: {
type: String,
required: true,
ref: 'Client',
},
clientPhone: {
type: String,
required: true,
},
clientEmail: {
type: String,
required: true,
},
clientAddress: {
type: String,
},
clientDetails: {
type: String,
},
startDate: {
type: String,
required: true,
default: new Date().toISOString().split('T')[0],
},
endDate: {
type: String,
required: true,
},
demoLink: {
type: String,
},
typeOfWeb: {
type: String,
},
description: {
type: String,
},
status: {
type: Boolean,
required: true,
default: false,
},
verifiedClientList: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Client',
},
],
projectManager: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true,
},
paymentList: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Payment',
},
],
},
{
timestamps: true,
}
);
projectSchema.pre('save', function (next) {
if (this.isNew) {
// Only calculate due when creating a new project
this.due = this.budget - this.advance;
}
next();
});
const Project = mongoose.model<ProjectType>('Project', projectSchema);
export default Project;
在
projectMode.ts
提前和到期部分我有验证器功能。每当我尝试添加新项目时它都工作得很好。但是当我尝试使用邮递员更新项目时,它给了我验证错误,尽管我的 json 是正确的。例如,我发送 json 的补丁请求为:
{
"name": "Project Alpha",
"budget": 10000,
"advance": 900,
"clientName": "Rezaul",
"clientPhone": "1234567890",
"clientEmail": "[email protected]",
"clientAddress": "123 Main St",
"clientDetails": "Long-term client",
"endDate": "2024-06-01",
"demoLink": "http://example.com/demo",
"typeOfWeb": "E-commerce",
"description": "A high-end e-commerce platform"
}
但是当我发送它时,它显示我错误:验证失败:预付款:预付款必须是正数并且小于或等于预算但这里提前(900)< budget (10000). so why my validator is not working with
runValidators: true
以及如何在不使用save()
的情况下解决这个问题
使用时我很期待
{
"name": "Project Alpha",
"budget": 10000,
"advance": 900,
"clientName": "Rezaul",
"clientPhone": "1234567890",
"clientEmail": "[email protected]",
"clientAddress": "123 Main St",
"clientDetails": "Long-term client",
"endDate": "2024-06-01",
"demoLink": "http://example.com/demo",
"typeOfWeb": "E-commerce",
"description": "A high-end e-commerce platform"
}
它将通过检查验证器来成功更新项目。
我通过使用后架构定义验证或使用path().validate():
advance
中的
projectModel.ts
,我使用:
projectSchema.path('advance').validate(function (value: number) {
console.log('this.budget', this.get('budget'));
return value >= 0 && value <= this.get('budget');
}, 'Advance must be a positive number and less than or equal to the budget');
这里我使用 this.get('budget')
获取更新的预算值。这给了我当前的预算值。根据猫鼬官方文档,在
validate()
或
validateSync()
中运行时,验证者可以使用
this
访问文档。当使用更新验证器运行时,
this
是查询,不是正在更新的文档!查询有一个
get()
方法,可让您获取更新的值。Link 因此,在更新我在 mongoose 的
this.get()
方法中传递的文档之前,我使用
findOneAndUpdate()
来获取验证中的更新值。
const updatedProject = await Project.findOneAndUpdate(
{ projectCode },
{
name,
budget,
advance,
clientName,
clientPhone,
clientEmail,
clientAddress,
clientDetails,
endDate,
demoLink,
typeOfWeb,
description,
},
{ new: true, runValidators: true }
);
此验证现在适用于猫鼬中的 save()
方法和
findOneAndUpdate()
。 如果您使用基于路径的验证,请确保删除基于架构的验证。我的意思是我还删除了
advance
部分中的验证和验证器功能。
validate: {
validator: function (value: number) {
return value >= 0 && value <= this.budget;
},
message:
'Advance must be a positive number and less than or equal to the budget',
},
并且还可以在 runValidators: true
内使用
findOneAndUpdate()
作为选项。