Implemented belongsTo update/destroy on scope

This commit is contained in:
Fabien Franzen 2014-08-20 16:46:54 +02:00
parent 12ebaf77f2
commit af99a8d344
2 changed files with 109 additions and 13 deletions

View File

@ -1084,9 +1084,11 @@ RelationDefinition.belongsTo = function (modelFrom, modelTo, params) {
get: function() { get: function() {
var relation = new BelongsTo(definition, this); var relation = new BelongsTo(definition, this);
var relationMethod = relation.related.bind(relation); var relationMethod = relation.related.bind(relation);
relationMethod.create = relation.create.bind(relation); relationMethod.update = relation.update.bind(relation);
relationMethod.build = relation.build.bind(relation); relationMethod.destroy = relation.destroy.bind(relation);
if (definition.modelTo) { if (!polymorphic) {
relationMethod.create = relation.create.bind(relation);
relationMethod.build = relation.build.bind(relation);
relationMethod._targetClass = definition.modelTo.modelName; relationMethod._targetClass = definition.modelTo.modelName;
} }
return relationMethod; return relationMethod;
@ -1139,6 +1141,36 @@ BelongsTo.prototype.build = function(targetModelData) {
return new modelTo(targetModelData); return new modelTo(targetModelData);
}; };
BelongsTo.prototype.update = function (targetModelData, cb) {
var definition = this.definition;
this.fetch(function(err, inst) {
if (inst instanceof ModelBaseClass) {
inst.updateAttributes(targetModelData, cb);
} else {
cb(new Error('BelongsTo relation ' + definition.name
+ ' is empty'));
}
});
};
BelongsTo.prototype.destroy = function (cb) {
var modelTo = this.definition.modelTo;
var modelInstance = this.modelInstance;
var fk = this.definition.keyFrom;
this.fetch(function(err, targetModel) {
if (targetModel instanceof ModelBaseClass) {
modelInstance[fk] = null;
modelInstance.save(function(err, targetModel) {
if (cb && err) return cb && cb(err);
cb && cb(err, targetModel);
});
} else {
cb(new Error('BelongsTo relation ' + definition.name
+ ' is empty'));
}
});
};
/** /**
* Define the method for the belongsTo relation itself * Define the method for the belongsTo relation itself
* It will support one of the following styles: * It will support one of the following styles:
@ -1204,7 +1236,8 @@ BelongsTo.prototype.related = function (refresh, params) {
var query = {where: {}}; var query = {where: {}};
query.where[pk] = modelInstance[fk]; query.where[pk] = modelInstance[fk];
if (query.where[pk] === undefined) { if (query.where[pk] === undefined
|| query.where[pk] === null) {
// Foreign key is undefined // Foreign key is undefined
return process.nextTick(cb); return process.nextTick(cb);
} }
@ -1420,9 +1453,9 @@ HasOne.prototype.create = function (targetModelData, cb) {
HasOne.prototype.update = function (targetModelData, cb) { HasOne.prototype.update = function (targetModelData, cb) {
var definition = this.definition; var definition = this.definition;
this.fetch(function(err, inst) { this.fetch(function(err, targetModel) {
if (inst instanceof ModelBaseClass) { if (targetModel instanceof ModelBaseClass) {
inst.updateAttributes(targetModelData, cb); targetModel.updateAttributes(targetModelData, cb);
} else { } else {
cb(new Error('HasOne relation ' + definition.name cb(new Error('HasOne relation ' + definition.name
+ ' is empty')); + ' is empty'));
@ -1431,9 +1464,9 @@ HasOne.prototype.update = function (targetModelData, cb) {
}; };
HasOne.prototype.destroy = function (cb) { HasOne.prototype.destroy = function (cb) {
this.fetch(function(err, inst) { this.fetch(function(err, targetModel) {
if (inst instanceof ModelBaseClass) { if (targetModel instanceof ModelBaseClass) {
inst.destroy(cb); targetModel.destroy(cb);
} else { } else {
cb(new Error('HasOne relation ' + definition.name cb(new Error('HasOne relation ' + definition.name
+ ' is empty')); + ' is empty'));

View File

@ -1110,6 +1110,8 @@ describe('relations', function () {
describe('belongsTo', function () { describe('belongsTo', function () {
var List, Item, Fear, Mind; var List, Item, Fear, Mind;
var listId, itemId;
it('can be declared in different ways', function () { it('can be declared in different ways', function () {
List = db.define('List', {name: String}); List = db.define('List', {name: String});
@ -1132,15 +1134,18 @@ describe('relations', function () {
it('can be used to query data', function (done) { it('can be used to query data', function (done) {
List.hasMany('todos', {model: Item}); List.hasMany('todos', {model: Item});
db.automigrate(function () { db.automigrate(function () {
List.create(function (e, list) { List.create({name: 'List 1'}, function (e, list) {
listId = list.id;
should.not.exist(e); should.not.exist(e);
should.exist(list); should.exist(list);
list.todos.create(function (err, todo) { list.todos.create({name: 'Item 1'},function (err, todo) {
itemId = todo.id;
todo.list(function (e, l) { todo.list(function (e, l) {
should.not.exist(e); should.not.exist(e);
should.exist(l); should.exist(l);
l.should.be.an.instanceOf(List); l.should.be.an.instanceOf(List);
todo.list().id.should.equal(l.id); todo.list().id.should.equal(l.id);
todo.list().name.should.equal('List 1');
done(); done();
}); });
}); });
@ -1162,6 +1167,55 @@ describe('relations', function () {
}); });
}); });
}); });
it('should update related item on scope', function(done) {
Item.findById(itemId, function (e, todo) {
todo.list.update({name: 'List A'}, function(err, list) {
should.not.exist(err);
should.exist(list);
list.name.should.equal('List A');
done();
});
});
});
it('should get related item on scope', function(done) {
Item.findById(itemId, function (e, todo) {
todo.list(function(err, list) {
should.not.exist(err);
should.exist(list);
list.name.should.equal('List A');
done();
});
});
});
it('should destroy related item on scope', function(done) {
Item.findById(itemId, function (e, todo) {
todo.list.destroy(function(err) {
should.not.exist(err);
done();
});
});
});
it('should get related item on scope - verify', function(done) {
Item.findById(itemId, function (e, todo) {
todo.list(function(err, list) {
should.not.exist(err);
should.not.exist(list);
done();
});
});
});
it('should not have deleted related item', function(done) {
List.findById(listId, function (e, list) {
should.not.exist(e);
should.exist(list);
done();
});
});
}); });
@ -1206,7 +1260,7 @@ describe('relations', function () {
describe('hasOne', function () { describe('hasOne', function () {
var Supplier, Account; var Supplier, Account;
var supplierId; var supplierId, accountId;
before(function () { before(function () {
db = getSchema(); db = getSchema();
@ -1228,6 +1282,7 @@ describe('relations', function () {
should.exist(supplier); should.exist(supplier);
supplier.account.create({accountNo: 'a01'}, function (err, account) { supplier.account.create({accountNo: 'a01'}, function (err, account) {
supplier.account(function (e, act) { supplier.account(function (e, act) {
accountId = act.id;
should.not.exist(e); should.not.exist(e);
should.exist(act); should.exist(act);
act.should.be.an.instanceOf(Account); act.should.be.an.instanceOf(Account);
@ -1292,6 +1347,14 @@ describe('relations', function () {
}); });
}); });
it('should have deleted related item', function(done) {
Supplier.findById(supplierId, function (e, supplier) {
should.not.exist(e);
should.exist(supplier);
done();
});
});
}); });
describe('hasAndBelongsToMany', function () { describe('hasAndBelongsToMany', function () {