我需要提一下,我完全清楚MongoDB首先不是关系数据库。但是它支持引用其他文档,因此支持 一些功能,imo。无论如何,我有这样的关系:公司has many
部门和一个部门belongs to
一个公司。
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var CompanySchema = new Schema({
name: {
type: String,
unique: true,
required: true
},
departments: [{
type: Schema.Types.ObjectId,
ref: 'Department'
}],
dateCreated: {
type: Date,
default: Date.now
},
dateUpdated: {
type: Date,
default: Date.now
}
});
module.exports = mongoose.model('Company', CompanySchema);
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var DepartmentSchema = new Schema({
name: {
type: String,
required: true
},
company: {
type: Schema.Types.ObjectId,
ref: 'Company'
},
dateCreated: {
type: Date,
default: Date.now
},
dateUpdated: {
type: Date,
default: Date.now
}
});
module.exports = mongoose.model('Department', DepartmentSchema);
现在,我正在编写Node.js逻辑来使用API来操作这些数据。我知道,如果我创建一个新的部门,我应该添加对公司的引用,我应该在这个公司的部门数组中创建它的引用。简单。但是如果用户更改了部门的公司财产呢?比如说,人力资源部门曾经属于A公司,但是用户现在将其转移到公司B?我们需要从公司A的阵列中删除对该部门的引用,并将其推送到公司B.同样,当我们要删除部门时。我们需要找到它所属的公司并将其关联起来。我的解决方案是使用ATM,但看起来很笨拙。
var Department = require('../../models/department'),
Company = require('../../models/company');
module.exports = function(express) {
var router = express.Router();
router.route('/')
.get(function(req, res) {
// ...
})
.post(function(req, res) {
// ...
});
router.route('/:id')
.get(function(req, res) {
// ...
})
.put(function(req, res) {
// First we need to find the department with the request parameter id
Department.findOne({ _id: req.params.id }, function(err, data) {
if (err) return res.send(err);
var department = data;
// department.name = req.body.name || department.name; Not relevant
// If the company to which the department belongs is changed
if (department.company != req.body.company._id) {
// We should find the previous company
Company.findOne({ _id: department.company }, function(err, data) {
if (err) return res.send(err);
var company = data;
// Loop through its departments
for (var i = 0; i < company.departments.length; i++) {
if (company.departments[i].equals(department._id)) {
// And splice this array to remove the outdated reference
company.departments.splice(i, 1);
break;
}
}
company.save(function(err) {
if (err) return res.send(err);
});
});
// Now we find this new company which now holds the department in question
// and add our department as a reference
Company.findOne({ _id: req.body.company._id }, function(err, data) {
if (err) return res.send(err);
var company = data;
company.departments.push(department._id);
company.save(function(err) {
if (err) return res.send(err);
});
});
}
// department.company = req.body.company._id || department.company; Not relevant
// department.dateUpdated = undefined; Not relevant
// And finally save the department
department.save(function(err) {
if (err) return res.send(err);
return res.json({ success: true, message: 'Department updated successfully.' });
});
});
})
.delete(function(req, res) {
// Since we only have id of the department being deleted, we need to find it first
Department.findOne({ _id: req.params.id}, function(err, data) {
if (err) return res.send(err);
var department = data;
// Now we know the company it belongs to and should dis-associate them
// by removing the company's reference to this department
Company.findOne({ _id: department.company }, function(err, data) {
if (err) return res.send(err);
var company = data;
// Again we loop through the company's departments array to remove the ref
for (var i = 0; i < company.departments.length; i++) {
if (company.departments[i].equals(department._id)) {
company.departments.splice(i, 1);
break;
}
}
company.save(function(err) {
if (err) return res.send(err);
});
// I guess it should be synchronously AFTER everything is done,
// since if it is done in parallel with Department.findOne(..)
// piece, the remove part can happen BEFORE the dep is found
Department.remove({ _id: req.params.id }, function(err, data) {
if (err) return res.send(err);
return res.json({ success: true, message: 'Department deleted successfully.' });
});
});
});
});
return router;
};
对于这种情况有没有优雅的解决方案,或者它应该是它应该是什么?
答案 0 :(得分:0)
我看到你还没有捕捉到node.js异步性质的本质...例如你在department.save之前有一个评论说:最后......好了早期的逻辑可能会非常那个时候还在执行...我还强烈建议你避免使用回调方法来学习如何使用promises