简体   繁体   中英

Removing Objects in one-to-many relationships using Node.js REST API, Mongoose, Express, Angular,

I have a one to many relationship between Tickets(many) and Events(one). I am able to add a Ticket to an Event but when I delete that Ticket I want it to be removed from the Event as well. So far I have not been able to accomplish this with the code below. I am able to delete the ticket but it's still referenced in the Event object.

ticket controller (Delete function) OLD

    exports.delete = function (req, res) {
  // Find Ticket using ID from URL
  var ticket = Ticket.findById(req.params.ticketId, function (err, data) {
    if (err) {
      res.status(500).send({
        message: "Could not retrieve event with id " + req.params.ticketId
      });
    } else {
      return data;
    }
  });

  //Use ticket linkedEvent Id to find and update Event
  Event.update( {"_id": ticket.linkedEvent}, { "$pullAll": {"tickets": [req.params.ticketId] } } );

  //Delete Ticket and send back success message
  Ticket.remove({
    _id: req.params.ticketId
  }, function (err, data) {
    if (err) {
      res.status(500).send({
        message: "Could not delete ticket with id " + req.params.id
      });
    } else {
      res.send({
        message: "Ticket deleted successfully!"
      });
    }
  });
};

Ticket Schema

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var TicketSchema = mongoose.Schema({
  type: String,
  name: String,
  expirationDate: String,
  reward: String,
  image: String,

  rewardUnlocked: Boolean,
  redeemed: Boolean,
  linkedEvent: String,
  scannedCodes: [],
  unlockCodes: []
}, {
    timestamps: true
});

module.exports = mongoose.model('Ticket', TicketSchema);

Event Schema

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var EventSchema = mongoose.Schema({
  promoter: String,
  name: String,
  location: String,
  date: String,
  image: String,

  attendees: Array,
  tickets: [{
    type: Schema.Types.ObjectId, 
    ref: 'Ticket'
  }],
}, {
    timestamps: true
});

module.exports = mongoose.model('Event', EventSchema);

Async Waterfall Delete Function NEW

exports.delete = function (req, res, next) {

async.waterfall([
getTicket,
updateEvent,
deleteTicket,
], function (err, result) {
res.send(result);
});
//Get Ticket by Id
function getTicket(req, res, callback) {
Ticket.findById(req.params.ticketId, function (err, data) {
  if (err) {
    res.status(500).send({
      message: "Could not retrieve event with id " + req.params.ticketId
    });
  } else {
    callback(null, data);
  }
});
}
//Delete Ticket ref from Event
function updateEvent(callback) {
Event.update({
  "_id": callback.linkedEvent
}, {
  "$pullAll": {
    "tickets": [req.params.ticketId]
  }
});
next();
}
//Delete Ticket
function deleteTicket(callback) {
Ticket.remove({
  _id: req.params.ticketId
}, function (err, data) {
  if (err) {
    res.status(500).send({
      message: "Could not delete ticket with id " + req.params.id
    });
  } else {
    callback(null, {
      message: "Ticket deleted successfully and removed from Event!"
    });
  }
});
}
};`

I ran in the same issue like you, so the only you need is to update the parent document when you delete the child:

// remove child document and pick its id and parent_id
await Event.findByIdAndUpdate(event_id, {
    $pull: { tikets: tiket_id },
});

by the way you need in the child schema a reference to the parent, something like this:

  var TicketSchema = mongoose.Schema({
    // ...other properties
    event: {
      type: Schema.Types.ObjectId, 
      ref: 'Event'
    }
  }, {
    timestamps: true
  });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM