【问题标题】:CastError: Cast to ObjectId failed for value "customers" at path "_id" for model "customer"CastError:模型“customer”的路径“_id”中的值“customers”转换为 ObjectId 失败
【发布时间】:2021-01-17 19:37:27
【问题描述】:

我希望有人能帮我弄清楚我在这里做错了什么。我一直在寻找,我可以找到很多类似的问题,但没有什么我足够聪明来解决我的问题。我收到以下错误:

CastError:模型“customer”的路径“_id”中的值“customers”转换为 ObjectId 失败

它以前可以工作,但我设法破坏了它,我撤消了我认为我改变的所有东西,但我仍然收到错误。

这是我的架构:

const Schema = mongoose.Schema;

const CustomerSchema = new Schema({

  custName: {
    type: String,
    required: true
  },
  custStreet: {
    type: String
  },
  custCity: {
    type: String
  },
  custState: {
    type: String
  },
  custZip: {
    type: String
  }
});

module.exports = Customer = mongoose.model('customer', CustomerSchema); 

我的路线:

const router = express.Router();

const customerController = require('../../controllers/customer')

const Customer = require('../../models/Customer');

router.route('/')
  .get(customerController.index)
  .post(customerController.newCustomer);

router.route('/:customerID')
  .get(customerController.getCustomer)

module.exports = router;

还有我的控制器:


module.exports = {

  index: async (req, res, next) => {
    try {
    const customers = await Customer.find({})
    res.status(200).json(customers);
  } catch(err) {
      next(err);
    }
  },

  newCustomer: async (req, res, next) => {
    try {
    const newCustomer = await Customer(req.body);
    const customer = await newCustomer.save();
    res.status(201).json(customer);
      } catch(err) {
          next(err);
      }
  }, 

  getCustomer: async(req, res, next) => {
    try {
    const { customerID } = req.params;
    const customer= await Customer.findById(customerID);
    res.status(200).json(customer);  
    } catch(err) {
        next(err);
    }
  }
};

另外,这是我得到的全部信息:

CastError:模型“customer”的路径“_id”中的值“customers”转换为 ObjectId 失败 在 model.Query.exec (C:\Users\natha\Desktop\Coding\HAMMER\node_modules\mongoose\lib\query.js:4371:21) 在 model.Query.Query.then (C:\Users\natha\Desktop\Coding\HAMMER\node_modules\mongoose\lib\query.js:4463:15) 在 processTicksAndRejections (internal/process/task_queues.js:93:5)

还有一些让我感到困惑的事情,我的数据库中有另一个路由文件和控制器用于另一个集合。它基本上是相同的代码,除了路由到'/:Customers'而不是路由到'/:Tickets'并且它工作得很好。我看不出这段代码是如何工作的,Customers 代码不是。

路线:

const router = express.Router();

const ticketController = require('../../controllers/ticket');

router.route('/')
  .get(ticketController.index)
  .post(ticketController.newTicket);

router.route('/:ticketID')
  .get(ticketController.getTicket)
  .put(ticketController.replaceTicket)
  .patch(ticketController.updateTicket);

module.exports = router;

控制器:


module.exports = {

 index: async(req, res, next) => {
   try {
     const tickets = await Ticket.find({})
     res.status(200).json(tickets);
   } catch(err) {
     next(err);
   }
 },

 newTicket: async (req, res, next) => {
   try {
     const newTicket = await Ticket(req.body);
     const ticket = await newTicket.save();
     res.status(201).json(ticket);
   } catch(err) {
      next(err);
   }
 },

 getTicket: async(req, res, next) => {
  try {
  const { ticketID } = req.params;
  const ticket = await Ticket.findById(ticketID);
  res.status(200).json(ticket);
  } catch(err) {
      next(err);
  }
 }, 

 replaceTicket: async(req, res, next) =>{
   try {
     const { ticketID } = req.params;
     const newTicket = req.body;
     const result = await Ticket.findByIdAndUpdate(ticketID, newTicket);
     res.status(200).json({ Success: true });
   } catch(err) {
      next(err);
   }
 },

 updateTicket: async(req, res, next) =>{
   try {
     const { ticketID } = req.params;
     const newTicket = req.body;
     const result = await Ticket.findByIdAndUpdate(ticketID, newTicket);
     res.status(200).json({ Success: true });
   } catch(err) {
      next(err);
   }
 } 
};

如果有任何帮助,我将不胜感激!

谢谢

-N8

【问题讨论】:

    标签: javascript node.js mongodb express mongoose


    【解决方案1】:

    我发现了问题。我的 server.js 文件中有这个:

    app.use('/', customers);
    app.use('/customers', customers);
    app.use('/materials', materials)
    app.use('/tickets', tickets)
    

    一旦我摆脱了app.use('/', customers);,一切都很好。

    【讨论】:

      【解决方案2】:

      getCustomer 处理程序中有错误。

      您不应该使用字符串 id 来查找客户,而必须先使用 mongoose.Types.ObjectId(STRING_ID)

      getCustomer: async(req, res, next) => {
          try {
          const { customerID } = req.params;
          const customer= await Customer.findById(mongoose.Types.ObjectId(customerID));
          res.status(200).json(customer);  
          } catch(err) {
              next(err);
          }
        }
      

      【讨论】:

      • 感谢您的回复!所以,我的getCustomer 似乎可以正常工作,我根据您的建议进行了编辑,getCustomer 仍然有效。运行index 时出现错误。奇怪的是,如果我在路由文件'.get(customerController.getCustomer)` 中注释掉以下行,那么index 工作正常。但是当我取消注释'index'停止工作并且'getCustomer'工作正常。
      • @Nate 在index handler中,可以去掉{}空对象条件,然后再试试。
      • 删除空的{} 的结果相同。如果.get(customerController.getCustomer) 被注释掉,则索引处理程序起作用。如果它没有被注释掉,getCustomer 处理程序就可以工作。
      【解决方案3】:

      我赞成 OP 的解决方案。为了节省大量时间,我只想解释为什么这是一个问题以及其他人可以像我一样注意什么。所以在 OP server.js 中,'/' 出现在其他违反规则以列出特定路由的路由之前第一的。意思是,如果在解决其他路由问题后移动了“/”。 更重要的是,这个错误来自哪里?当您调用任何其他路由时,您的应用首先调用“/”并使用客户的路由,同时将路由路径(即“/customers”、“/materials”、“/tickets”)作为 id 参数传递,然后是 mongo正在尝试将客户、材料和票证作为客户集合中的 id。

      app.use('/customers', customers);
      app.use('/materials', materials)
      app.use('/tickets', tickets)
      app.use('/', customers);
      

      这将解决 OP 的问题。

      就我而言,这就是问题所在:

      router.get('/', getAllUser);
      router.get('/:id', getUserById)
      router.get('/facebook', facebookPassport)
      router.get('/google', customersPassport);
      

      所以在这里我得到了这个错误模型用户路径“_id”处值“facebook”/“google”的转换错误因为字符串“facebook”和最后两个路由中的“google”是特定的,但永远不会到达,因为 '/:id' 路由将接受 '/' 之后的任何值作为 id。当我像这样重新排列时:

      router.get('/', getAllUser);
      router.get('/facebook', facebookPassport)
      router.get('/google', customersPassport);
      router.get('/:id', getUserById)
      

      Take away:在应用级别和路由文件中将特定路由移动到动态路由(带有参数的路由)的顶部。

      【讨论】:

      • 为了让你的答案更清晰、更容易理解,我建议你也为你的建议添加一个代码范例。
      • 感谢@EvanP,我添加了一些代码上下文。我希望它会非常有帮助,并且可以避免有人因为模型错误而疯狂追逐。
      猜你喜欢
      • 2020-11-19
      • 2021-07-04
      • 2017-08-18
      • 2014-06-20
      • 2019-05-25
      • 2020-12-10
      • 2021-02-21
      • 2016-11-11
      • 2017-03-26
      相关资源
      最近更新 更多