【问题标题】:Mongoose Subdocument will not updateMongoose 子文档不会更新
【发布时间】:2017-03-17 07:35:20
【问题描述】:

我无法确定我是否正确设计了架构,因为我在尝试从配置文件中修补角色属性的更改时收到 500 错误。 (注意:500 错误只是以空 {} 响应,因此它并不能提供真正的信息)

以下是配置文件架构:

var ProfileSchema = new Schema({
  name: {
    type: String,
    required: true
  },
  roles: [{
    application: {
      type: Schema.Types.ObjectId,
      required: true,
      ref: 'Application'
    },
    role: {
      type: String,
      required: true,
      enum: [ 'admin', 'author', 'publisher' ]
    }
  }]
});

每个配置文件都有一个应用程序的角色,当我将请求发送到控制器操作“更新”时,它失败了:

配置文件更新控制器:

// Updates an existing Profile in the DB
export function update(req, res) {
  try {
    if (req.body._id) {
      delete req.body._id;
    }

   console.log('ENDPOINT HIT...');
   console.log(`REQUEST PARAM ID: ${req.params.id}`);
   console.log('REQUEST BODY:');
   console.log(req.body);
   console.log('ENTIRE REQUEST: ');

   return Profile.findByIdAsync(req.params.id)
    .then(handleEntityNotFound(res))
    .then(saveUpdates(req.body))
    .then(respondWithResult(res))
    .catch(handleError(res));

 } catch(ex) {
     console.error('FAILED TO UPDATE PROFILE');
     return handleError(res);
   }
}

我确保 id 和 body 被正确发送,并且我正在到达终点。

这是请求正文 JSON 的示例:

{ 
  _id: 57e58ad2781fd340563e29ff,
  __updated: Thu Oct 27 2016 15:41:12 GMT-0400 (EDT),
  __created: Fri Sep 23 2016 16:04:34 GMT-0400 (EDT),
  name: 'test',
  __v: 11,
  roles:[ 

   { application: 57b70937c4b9fe460a235375,
     role: 'admin',
     _id: 58125858a36bd76d8111ba16 },

   { application: 581b299f0145b48adf8f57bd,
     role: 'publisher',
     _id: 581b481898eefb19ed8a73ee } 
   ]

 }

当我尝试通过 Id 查找 Profile 时,promise 链直接进入 catch(handleError(res));部分代码并在我的控制台中显示一个空对象。

我的句柄错误函数:

 function handleError(res, statusCode) {
   console.error('HANDLE PROFILE ERROR: ', statusCode);
   statusCode = statusCode || 500;
   return function(err) {
     console.error('PROFILE ERROR:');
     console.error(JSON.stringify(err, null, 2));
     res.status(statusCode).send(err);
   };
  }

更新

我意识到代码在遇到我的 saveUpdates 函数时会中断(注意:我正在使用 lodash):

function saveUpdates(updates) {
  /// the code is fine here ///
  return function(entity) {
    /// once it enters in here, is where it begins to break ///
    var updated = _.merge(entity, updates);

    if(updated.roles.length != updates.roles.length) {
      updated.roles = updates.roles;
    }

    for(var i in updates.roles) {
      updated.roles.set(i, updates.roles[i]);
    }
    return updated.saveAsync()
     .then(updated => {
        return updated;
      });
    };
}

【问题讨论】:

  • 查看错误findByIdAsync(...).catch((err) => { console.log(err); handleError(res); })
  • 您能告诉我们,req.params.id 上到底有什么内容吗? console.log(`REQUEST PARAM ID: ${req.params.id}`); 向您展示了什么
  • @GrégoryNEUT,当我控制台记录 params.id 时——这是我检索到的内容:`REQUEST PARAM ID: 57bd9db4f33dcd03c3fd9990`
  • ok 试试 findOne({ _id: req.params.id }) (我找不到 findByIdAsync() mongoose 文档)
  • @GrégoryNEUT,所以我意识到如果我从我的承诺链中删除 saveUpdates 函数调用——并将模型的方法切换到Profile.findOneAndUpdate——那么错误就会消失。我确信我的 saveUpdates 功能现在坏了。

标签: node.js mongodb mongoose mongoose-schema


【解决方案1】:

经验教训:正确阅读文档。

由于我在此应用程序中使用了 bluebird Promise,因此我忘记在我的 saveUpdates() 回调函数中使用 .spread()

解决方案:

function saveUpdates(updates) {
  return function(entity) {
    var updated = _.merge(entity, updates);
    if(updated.roles.length != updates.roles.length) {
       updated.roles = updates.roles;
    }

    for(var i in updates.roles) {
      updated.roles.set(i, updates.roles[i]);
    }

    return updated.saveAsync()
      // use `.spread()` and not `.then()` //
      .spread(updated => {
        return updated;
      });
   };
 }

我要感谢导致此结论的以下 SOA:https://stackoverflow.com/a/25799076/5994486

此外,如果有人对 .spread() 感兴趣,这里是 bluebird 文档的链接:http://bluebirdjs.com/docs/api/spread.html

【讨论】:

    猜你喜欢
    • 2015-07-12
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 2014-11-27
    • 2012-10-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多