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?