我有以下类型的设置:我有一个名为Person
的模型,它通过多对多关联与其他Person
s(例如邻居)相关。解释是一个人可以拥有许多邻居,一个人可以成为许多其他人的邻居。模型属性看起来像这样:
...
attributes: {
name: 'string',
neigh: {
collection: 'Person',
via: 'neighOf',
dominant: true
},
neighOf: {
collection: 'Person',
via: 'neigh'
}
}
...
现在想象我们有两个人,A人和B人.A是B的邻居,B是A的邻居.A离开了,所以他们不再是邻居。现在,当我从A的嘶声中移除B时, A将不会自动从B 的嘶声中移除。这是一个问题。
我尝试通过为afterUpdate
模型创建Person
函数来解决此问题,我会检查A的neighOf
字段中的每个人是否仍然拥有它们作为邻居,如果没有,将更新不再是A的邻居的Persons
。我也想做相反的事情,所以如果A再次成为B的邻居(例如neigh
B的字段已更新),A的neigh
字段也应自动更新。这就是我想出的:
afterUpdate: function(updatedPerson, cb) {
Person.findOne(updatedPerson.id)
.populate('neigh')
.populate('neighOf')
.then(function(person) {
updatedPerson = person;
var ids = _.pluck(updatedPerson.neigh, 'id');
return Person.find(ids).populate('neigh');
})
.then(function(people) {
neigh_of_updated = people;
var ids = _.pluck(updatedPerson.neighOf, 'id');
return Person.find(ids).populate('neigh');
})
.then(function(people) {
neighOf_of_updated = people;
var updates = [];
_.forEach(neighOf_of_updated, function(person) {
if (_.find(person.neigh, function(neigh) {return neigh.id === updatedPerson.id})
&& !_.find(updatedPerson.neigh, function(neigh) {return neigh.id === person.id})) {
var neighIds = _.pluck(person.neigh, 'id');
_.remove(neighIds, function(id) {
return id === updatedPerson.id;
});
updates.push(Person.update(person.id, {neigh: neighIds}));
}
})
return Promise.all(updates);
})
.then(function() {
var updates = [];
_.forEach(neighOfUpdated, function(person) {
if (!_.find(person.neigh, function(neigh) { return neigh.id === updatedPerson.id; })) {
var neighIds = _.pluck(person.neigh, 'id');
neighIds.push(updatedPerson.id);
updates.push(Person.update({id: Person.id}, {neigh: neighIds}))
}
})
return Promise.all(updates);
})
.then(function() {
cb();
})
.catch(function(error) {
cb(error);
})
}
到目前为止,我还没有能够兼得。我可以让它们分开工作,但是当它们组合在一起时,代码就会无休止地循环,因为在这一切中间发生了一些更新,导致调用新的和更新的afterUpdates。
我觉得这是一个非常常见的用例,所以我猜测应该有一个更简单的方法来完成所有这些 - 或者如果没有,至少有一些方法可以使这个工作。事实上,我觉得我的头撞在一堵砖墙上应该是一件容易的事。任何人都有类似关联的经验以及如何处理它们?