【问题标题】:Push and Pull elements in Array in NodeJS API call在 NodeJS API 调用中推送和拉取数组中的元素
【发布时间】:2015-04-08 04:06:11
【问题描述】:

在我的应用程序中,我使用 Mongoose 创建模式。我有一个用户架构和一个 Tikit 架构。每次用户创建一个 tickit 时,我都想将 tickit 的 id 添加到我的用户架构上的 'tickits' 数组中,如下所示。代码的一半有效 - 当我创建一个 tickit 时,该 id 进入用户 tickits 数组 - 但是当我删除该 tickit 时,该 id 不会从数组中删除。

Ticket.js

var mongoose    = require('mongoose');
var Schema      = mongoose.Schema;
var tickitSchema = new Schema({
    title: String,
    description: String,
    author : { type: Schema.Types.ObjectId, ref: 'User' },
    comments: [{body:"string", by: Schema.Types.ObjectId}]
});

module.exports = mongoose.model('Tickit', tickitSchema);

用户.js

var mongoose = require('mongoose');
var bcrypt   = require('bcrypt-nodejs');
var Schema   = mongoose.Schema;
var Tickit   = require('../models/Tickit');

var userSchema = new Schema({
    email        : String,
    password     : String,
    tickits      : [Tickit.tickitSchema]

});

userSchema.methods.generateHash = function(password) {
    return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};

userSchema.methods.validPassword = function(password) {
    return bcrypt.compareSync(password, this.password);
};

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

我创建和删除票的功能如下:

exports.create = function(req, res) {
    var tickit    = new Tickit(req.body);
    var user      = req.user;
    tickit.author = user._id;
    user.update({tickits : {id : tickit._id}}, {$push: {tickits: { id: tickit._id}}},function (err) {
        if (err) 
            return res.send(err);
    }); 
    user.save();
    tickit.save(function(err, tickits) {
        if (err) {
          res.send(err);
        } else {
          res.json(tickits);
        }
    });
};

exports.destroy = function(req, res) {
    var tickit_id = req.params.tickit_id;
    req.user.update({tickits : {id : tickit_id}}, {$pull: {tickits: { id: tickit_id}}},function (err) {
        if (err) 
            return res.send(err);
    });
    req.user.save();

    Tickit.remove({_id : req.params.tickit_id}, function(err, tickit) {
        if (err)
            res.send(err);

        Tickit.find(function(err, tickits) {
            if (err)
                res.send(err)
            res.json(tickits);
        });
    });   
}

也许我做错了,但我已经尝试了几个小时,任何帮助都会非常棒。

【问题讨论】:

  • req.user.update如果你把回调改成function (err, numAffected)然后输出numAffected,是不是返回1?
  • 嗨 Duane,numAffected 确实为我返回了 1。创建 tickit 后,用户 tickit 数组如下所示:"tickits" : { "id" : ObjectId("5523f40bd19fe9354af08a81") } 但是当我删除 tickit 时,然后检查用户上的 tickit 对象,它看起来像这样:"tickits" : [ { "id" : ObjectId("5523f40bd19fe9354af08a81") } ]
  • 尝试将update 的选项设置为{new: true} 以确保修改后的文档是返回的文档。我还提交了一个答案,以展示一种略有不同的方法。

标签: javascript arrays node.js mongodb mongoose


【解决方案1】:

这似乎是 save 的异步性质的问题。此外,稍微清理一下架构以帮助澄清。

var Schema = mongoose.Schema;
var tickitSchema = Schema({
  title: String,
  description: String,
  author : {
    type: Schema.Types.ObjectId,
    ref: 'User'
  },
  comments: [{
    body: String,
    by: {
      type: Schema.Types.ObjectId,
      ref: 'User'
    }
  }]
});

var userSchema = Schema({
  email: String,
  password: String,
  tickits: [{
    type: Schema.Types.ObjectId,
    ref: 'Tickit'
  }]
});

module.export.create = function createTickit(req, res) {
  var tickit = Tickit(req.body);
  tickit.author = req.user;
  // Save the ticket first to ensure it exists
  tickit.save(function (err, tickit) {
    if (err || tickit === null) { return res.send(err || new Error('Ticket was not saved but there was no error...odd')); }

    User.findByIdAndUpdate(req.user.id, {$push: {tickits: tickit}}, {new: true}, function (err, user) {
      if (err) { return res.send(err) };

      res.json(ticket); // or whatever else you want to send
    });
  });
};

module.export.destroy = function destroyTickit(req, res) {
  // Remove the ticket first to ensure it is removed
  Tickit.findByIdAndRemove(req.params.tickit_id, function (err, tickit) {
    if (err || tickit === null) { return res.send(err || new Error('Ticket was not removed but there was no error...odd')); }

    User.findByIdAndUpdate(req.user.id, {$pull: {tickits: tickit.id}}, {new: true}, function (err, user) {
      if (err) { return res.send(err) };

      res.json(ticket); // or whatever else you want to send
    });
  });
};

这将完成基本的创建/销毁,但没有任何安全控制(确保谁有权销毁票证等)。

【讨论】:

  • 感谢 Jason 抽出宝贵时间提供出色的答案。您提供的代码完全符合我的需要。这似乎比我以前使用的方法更好。干杯!
猜你喜欢
  • 2021-08-29
  • 2018-05-10
  • 1970-01-01
  • 2020-06-03
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多