1

I'm trying to do the following in SailsJS (v0.10):

var idToUseInBothCollections = req.body.docId;
var subscriber = req.user.subscriber;

db.development.find({
  _id: ObjectId(idToUseInBothCollections),
  subscriberId: subscriber
}).forEach(function(doc) {
  doc.status = 'published';
  db.development.update({
    _id: ObjectId(idToUseInBothCollections),
    subscriberId: subscriber
  }, {
    $inc: {
      version: 1
    }
  });
  db.published.update({
    _id: ObjectId(idToUseInBothCollections),
    subscriberId: subscriber
  }, doc, {
    upsert: true
  });
})

So essentially what I'm doing is copying a document from the 'development' collection into the 'published' collection, and keeping the '_id'. Having the same '_id' is important as it allows for simpler future actions where I can sort of treat the 'development' document and the 'published' document as one (so a 'delete' call would only need one '_id' value to be passed to it).

I just seem unable to get this to work, no matter what I do. I've tried using 'native()' and "require('mongodb').ObjectID" but the '_id' in the 'published' collection is always re-generated - so I end up with multiple copies of the document in the 'published' collection if I run the query several times. Each with a different '_id' and a different 'version' value. This isn't very helpful. I've even set 'autoPK' to false in my 'published' model, just in case.

I've ended up adding a value - 'developmentId' - in the document to store the original 'development._id' and used that as follows as a workaround for now:

db.development.find({
  _id: ObjectId(idToUseInBothCollections),
  subscriberId: subscriber
}).forEach(function(doc) {
  doc.status = 'published';
  db.development.update({
    _id: ObjectId(idToUseInBothCollections),
    subscriberId: subscriber
  }, {
    $inc: {
      version: 1
    }
  });
  db.published.update({
    developmentId: idToUseInBothCollections,
    subscriberId: subscriber
  }, doc, {
    upsert: true
  });
})

This is the actual code I've now cobbled together in my controller:

var ObjectId = require('mongodb').ObjectID;
var toPublish = req.body.toPublish;
var subscriber = req.user.subscriber;

Development.findOne({
  id: ObjectId(toPublish),
  subscriberId: subscriber
}).exec(function(err, found) {
  if (err) {
    return res.json({
      msg: 'Failed.'
    });
  }
  found.status = 'published';
  publish(found);
});

var publish = function(found) {
  Development.native(function(err, development) {
    development.update({
      _id: ObjectId(toPublish),
      subscriberId: subscriber
    }, {
      $inc: {
        version: 1
      }
    }, function(err, updated) {
      if (err) {
        return res.json({
          msg: 'Failed.'
        });
      } else {
        //success
      }
    });
  });
  Published.native(function(err, published) {
    published.update({
      developmentId: toPublish,
      subscriberId: subscriber
    }, found, {
      upsert: true
    }, function(err, updatedpublished) {
      if (err) {
        return res.json({
          msg: 'Failed.'
        });
      } else {
        return res.json({
           msg: 'Success'
        });
      }
    });
  });
};

Yes it works, but I honestly don't see why this should be necessary. I'm wondering, is there a way to perform my first choice query in SailsJS in a less cluttered way?

4

0 回答 0