mongoose 如何在MEVN堆栈中结合合并创建和更新表单和流程?

bq8i3lrv  于 2024-01-08  发布在  Go
关注(0)|答案(2)|浏览(251)

有没有人在MEVN堆栈中组合了他们的编辑和创建表单?例如,Moongoose的保存方法可以创建或更新,但我不确定如果ID存在或不存在,您将如何处理传入ID。下面是我目前的创建过程和更新过程。将两个不同的组件组合成一个完成两项工作的组件会很好。
CreateStudent.vue

  1. handleSubmitForm() {
  2. console.log("handleSubmitForm")
  3. this.isSubmitted = true;
  4. let apiURL = "http://localhost:4000/api/create-student";
  5. axios
  6. .post(apiURL, this.student)
  7. .then(() => {
  8. this.$router.push("/list");
  9. this.student = {
  10. firstName: "",
  11. lastName: "",
  12. email: "",
  13. phone: "",
  14. password: "",
  15. confirmPassword: "",
  16. };
  17. //alert("SUCCESS! " + JSON.stringify(this.userForm));
  18. })
  19. .catch((error) => {
  20. console.log(error);
  21. })
  22. .finally((next) => {
  23. // console.log('is Submiited);
  24. })
  25. },
  26. studentRoute.route("/create-student").post((req, res, next) => {
  27. StudentModel.create(req.body, (error, data) => {
  28. if (error) {
  29. return next(error);
  30. } else {
  31. res.json(data);
  32. }
  33. })
  34. })

字符串
EditStudent.vue

  1. handleUpdateForm() {
  2. let apiURL = `http://localhost:4000/api/update-student/${this.$route.params.id}`;
  3. axios.post(apiURL, this.student).then((res) => {
  4. console.log(res)
  5. this.$router.push('/list')
  6. }).catch(error => {
  7. console.log(error)
  8. });
  9. }
  10. studentRoute.route('/update-student/:id').post((req, res, next) => {
  11. StudentModel.findByIdAndUpdate(req.params.id, {
  12. $set: req.body
  13. }, (error, data) => {
  14. if (error) {
  15. return next(error);
  16. } else {
  17. res.json(data)
  18. console.log('Student successfully updated!')
  19. }
  20. })
  21. })

4szc88ey

4szc88ey1#

根据文档,你可以简单地发送一个选项来findByIdAndUpdate,其中一个是upsert
[options.upsert=false]如果为true,且未找到文档,则插入新文档
https://mongoosejs.com/docs/api/model.html#Model.findByIdAndUpdate()
比如说

  1. StudentModel.findOneAndUpdate(
  2. { _id: req.params.id },
  3. { $set: req.body },
  4. { upsert: true } // Make this update into an upsert
  5. );

字符串
应该既作为更新又作为插入

pprl5pva

pprl5pva2#

最好是分别处理更新和创建。@Bergur是正确的,因为findOneAndUpdatefindByIdAndUpdate有一个upsert选项,允许您在没有匹配文档的情况下更新或插入。但是,根据我的经验,这通常在最初工作,然后问题开始。
关键的症结是验证。对于findOneAndUpdatefindByIdAndUpdate,您还可以传递runValidators: true选项来告诉mongoose运行验证器,但这只对包含在更新文档和only for some operations中的字段有效。因此,如果您对某个字段有约束,但您没有在更新文档中传递该字段,则mongoose将不执行任何验证。这可能会产生一些负面影响后果
为了说明一个简单的模式,它将如下所示:

  1. const studentSchema = new mongoose.Schema({
  2. firstName: {
  3. type: String,
  4. required: true
  5. },
  6. lastName: {
  7. type: String,
  8. required: true
  9. },
  10. veryImportantProperty: {
  11. type: String,
  12. required: true
  13. },
  14. });

字符串
现在,如果您像这样执行findOneAndUpdatefindByIdAndUpdate

  1. req.body = {
  2. firstName: 'Bruce'
  3. lastName: 'Wayne'
  4. //< Whoops, veryImportantProperty wasn't included in the post request
  5. }
  6. const student = await Student.findByIdAndUpdate(
  7. req.params.id,
  8. req.body,
  9. {
  10. upsert: true,
  11. runValidators: true,
  12. new: true
  13. }
  14. );


然后,即使使用runValidators选项,也不会在veryImportantProperty上进行验证,因为它不包含在req.body中,所以mongoose将在没有它的情况下创建文档。
即使您像这样使用$set运算符:

  1. const student = await Student.findByIdAndUpdate(
  2. req.params.id,
  3. { $set: req.body },
  4. {
  5. upsert: true,
  6. runValidators: true,
  7. new: true
  8. }
  9. );


如果没有veryImportantProperty,它仍然会保存新文档。使用Model.create(),您给予更好的数据完整性,更容易调试,并且在创建操作失败时,您可以向用户发送更好的错误响应。
这是一个简单的例子,但是对于更复杂的验证,事情可能会很快变得混乱,调试起来也会很困难,特别是在离开一段时间后重新访问代码库的时候。

展开查看全部

相关问题