You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mongoose中.save()方法无法更新MongoDB数据库求助

问题描述

我在其他Schema里已经实现了数据更新功能(需要的话可以提供对应代码),但在User Schema里复现的时候,没办法更新MongoDB数据库。这个功能在其他Schema里运行正常,现在卡壳了,求帮忙!


相关代码

POST控制器

console.log("post");
const userId = req.body.userId;
const updatedName = req.body.name;
const updatedPassword = req.body.password;
const updatedEmail = req.body.email;
const updatedSkype = req.body.skype;
const updatedDepartment = req.body.department;
const updatedJobtitle = req.body.jobtitle;
const updatedLinemanager = req.body.linemanager;
const updatedNinumber = req.body.ninumber;
// const updatedJoinDate = req.body.joindate;
// console.log(req.body);

User.findById(userId)
  .then((user) => {
    isadmin = user.isadmin;
    name = updatedName;
    password = updatedPassword;
    email = updatedEmail;
    skype = updatedSkype;
    department = updatedDepartment;
    jobtitle = updatedJobtitle;
    linemanager = updatedLinemanager;
    ninumber = updatedNinumber;
    joindate = user.joindate;
    return user.save();
  })
  .then((result) => {
    console.log("User EDITED!");
    res.redirect("/staffdir");
  })
  .catch((err) => console.log(err));
};

User模型

const mongoose = require("mongoose");

const Schema = mongoose.Schema;

const userSchema = new Schema({
  isadmin: {
    type: Boolean,
    required: true,
  },
  name: {
    type: String,
    required: true,
  },
  password: {
    type: String,
    required: true,
  },
  email: {
    type: String,
    required: true,
  },
  skype: {
    type: String,
    required: true,
  },
  department: {
    type: String,
    required: true,
  },
  jobtitle: {
    type: String,
    required: true,
  },
  linemanager: {
    type: String,
    required: true,
  },
  ninumber: {
    type: String,
    required: true,
  },
  joindate: {
    type: Date,
    required: true,
  },
});

module.exports = mongoose.model("User", userSchema);

路由

router.get("/add-user", adminController.getAddUser);

router.get("/edit-user/:userId", adminController.getEditUser);

router.get("/edit-user-list", adminController.getEditUserList);

//POST USER
router.post("/add-user", adminController.postAddUser);

router.post("/edit-user/edit-user", adminController.postEditUser);
router.post("/edit-user", adminController.postEditUser);

router.post("/destroy-user", adminController.postDeleteUser);

HTML/EJS模板

<%- include('../includes/head.ejs') %>
<link rel="stylesheet" href="/css/admin.css" />
<link rel="stylesheet" href="/css/add-user.css" />
  <body>
    <img src="pozzani.png" alt="pozzani logo" class="pozzanilogo" />
    <div class="mainbackground">
      <div class="leftcolumn">
        <%- include('../includes/signout.ejs') %>
        <%- include('../includes/nav.ejs') %>
        <%- include('../includes/useful.ejs') %>
      </div>
      <div class="admin-column">
        <h2 class="importanttitle">EDIT USER</h2>
        <div class="update-container">
          <h3 class="admin-title">Welcome to the USER edit tool</h3>
          <p class="admin-content">Please edit forms below to make change. <b>ALL EDITS ARE FINAL!</b></p>
          <form class="user-form" action="edit-user" method="POST">
            <div class="form-section">
              <label for="isadmin">Is Admin?</label>
              <select id="isadmin" name="isadmin">
                <% if (!user.isadmin) { %>
                <option value="false" selected>False</option>
                
                <option value="false">False</option>
                <option value="false">False</option>
                <option value="false">False</option>
                <option value="false">False</option>
                <option value="false">False</option>
                <option value="true">True - ARE YOU SURE? USER WILL BE ABLE TO EDIT USERS AND UPDATES</option>
                <% } else { %>
                <option value="true" selected>True - ARE YOU SURE? USER WILL BE ABLE TO EDIT USERS AND UPDATES</option>
                <% } %>
              </select>
            </div>
            <div class="form-section">
              <label for="name">Name</label>
              <input type="text" name="name" id="name" value="<%= user.name %>" >
            </div>
            <div class="form-section">
              <label for="password">Password</label>
              <input type="text" name="password" id="password" value="<%= user.password %>">
            </div>
            <div class="form-section">
              <label for="email">Email</label>
              <input type="email" name="email" id="email" value="<%= user.email %>">
            </div>
            <div class="form-section">
              <label for="skype">Skype</label>
              <input type="text" name="skype" id="skype" value="<%= user.skype %>">
            </div>
            <div class="form-section">
              <label for="department">Department</label>
              <input type="text" name="department" id="department" value="<%= user.department %>">
            </div>
            <div class="form-section">
              <label for="jobtitle">Job Title</label>
              <input type="text" name="jobtitle" id="jobtitle" value="<%= user.jobtitle %>">
            </div>
            <div class="form-section">
              <label for="linemanager">Line Manager</label>
              <input type="text" name="linemanager" id="linemanager" value="<%= user.linemanager %>">
            </div>
            <div class="form-section">
              <label for="ninumber">National Insurance Number</label>
              <input type="text" name="ninumber" id="ninumber" value="<%= user.ninumber %>">
            </div>
            <!-- <div class="form-section">
              <label for="joindate">Join Date</label>
              <input type="date" name="joindate" id="joindate" value="<%= user.joindate %>">
            </div> -->
            <input type="hidden" value="<%= user._id %>" name="userId">
            <button class="admin-btn" type="submit"><% userId = user._id %>Edit User</button>
          </form>
        </div>
      </div>
    </div>
    </body>
    </html>

问题根源与修复方案

核心问题

你的POST控制器犯了关键错误:没有把更新值赋值给从数据库查询到的user对象,而是直接给未声明的全局变量赋值。这样user对象根本没被修改,调用user.save()自然不会更新数据库。此外还有几个潜在问题:

  • 表单提交的isadmin字段完全没被处理
  • 变量未用let/const声明,污染全局作用域
  • 查询后再保存的操作冗余,可直接用更高效的更新方法

修复后的POST控制器代码

console.log("post");
const userId = req.body.userId;
// 处理布尔值:表单提交的是字符串,需转成布尔类型
const updatedIsAdmin = req.body.isadmin === 'true';
const updatedName = req.body.name;
const updatedPassword = req.body.password;
const updatedEmail = req.body.email;
const updatedSkype = req.body.skype;
const updatedDepartment = req.body.department;
const updatedJobtitle = req.body.jobtitle;
const updatedLinemanager = req.body.linemanager;
const updatedNinumber = req.body.ninumber;

// 方法1:修正原逻辑,正确修改user对象
User.findById(userId)
  .then((user) => {
    // 直接修改查询到的user对象属性
    user.isadmin = updatedIsAdmin;
    user.name = updatedName;
    user.password = updatedPassword;
    user.email = updatedEmail;
    user.skype = updatedSkype;
    user.department = updatedDepartment;
    user.jobtitle = updatedJobtitle;
    user.linemanager = updatedLinemanager;
    user.ninumber = updatedNinumber;
    // joindate保持原数值,无需修改
    return user.save();
  })
  .then((result) => {
    console.log("User EDITED!");
    res.redirect("/staffdir");
  })
  .catch((err) => {
    console.error(err);
    res.status(500).send('更新失败'); // 增加错误反馈,方便调试
  });

// 方法2:更高效的findByIdAndUpdate(推荐)
// User.findByIdAndUpdate(
//   userId,
//   {
//     isadmin: updatedIsAdmin,
//     name: updatedName,
//     password: updatedPassword,
//     email: updatedEmail,
//     skype: updatedSkype,
//     department: updatedDepartment,
//     jobtitle: updatedJobtitle,
//     linemanager: updatedLinemanager,
//     ninumber: updatedNinumber
//   },
//   { new: true, runValidators: true } // 返回更新后的文档,运行Schema验证规则
// )
// .then((result) => {
//   console.log("User EDITED!");
//   res.redirect("/staffdir");
// })
// .catch((err) => {
//   console.error(err);
//   res.status(500).send('更新失败');
// });

额外优化点

  1. 清理表单中重复的isadmin选项:
<select id="isadmin" name="isadmin">
  <% if (!user.isadmin) { %>
    <option value="false" selected>False</option>
    <option value="true">True - 确认操作?该用户将拥有编辑用户和数据的权限</option>
  <% } else { %>
    <option value="true" selected>True - 确认操作?该用户将拥有编辑用户和数据的权限</option>
    <option value="false">False</option>
  <% } %>
</select>
  1. 密码字段改用type="password",避免明文显示
  2. 控制器中所有变量用const声明,避免全局作用域污染

内容的提问来源于stack exchange,提问作者bfrith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 01:36:25