Mongoose Subdocument不会更新

时间:2016-11-03 16:03:22

标签: node.js mongodb mongoose mongoose-schema

我无法弄清楚我是否正确设计了架构,因为我在尝试从配置文件中修改角色属性时收到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);
   }
}

我确保身份和身体正确发送,我正在达到终点。

这是请求正文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;
      });
    };
}

1 个答案:

答案 0 :(得分:0)

获得的经验:正确阅读文档。

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

解决方案:

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()感到好奇:http://bluebirdjs.com/docs/api/spread.html