Fix hasOne remoting

This commit is contained in:
Raymond Feng 2015-01-29 23:26:11 -08:00
parent ce39f8ab01
commit e46bd0cdb5
4 changed files with 72 additions and 5 deletions

View File

@ -1434,6 +1434,12 @@ DataAccessObject.prototype.updateAttributes = function updateAttributes(data, cb
cb = function() {}; cb = function() {};
} }
// Convert the data to be plain object so that update won't be confused
if (data instanceof Model) {
data = data.toObject(false);
}
data = removeUndefined(data);
var context = { var context = {
Model: Model, Model: Model,
where: byIdQuery(Model, getIdValue(Model, inst)).where, where: byIdQuery(Model, getIdValue(Model, inst)).where,

View File

@ -1490,12 +1490,26 @@ RelationDefinition.hasOne = function (modelFrom, modelTo, params) {
// FIXME: [rfeng] Wrap the property into a function for remoting // FIXME: [rfeng] Wrap the property into a function for remoting
// so that it can be accessed as /api/<model>/<id>/<hasOneRelationName> // so that it can be accessed as /api/<model>/<id>/<hasOneRelationName>
// For example, /api/orders/1/customer // For example, /api/orders/1/customer
var fn = function() { modelFrom.prototype['__get__' + relationName] = function() {
var f = this[relationName]; var f = this[relationName];
f.apply(this, arguments); f.apply(this, arguments);
}; };
modelFrom.prototype['__get__' + relationName] = fn;
modelFrom.prototype['__create__' + relationName] = function() {
var f = this[relationName].create;
f.apply(this, arguments);
};
modelFrom.prototype['__update__' + relationName] = function() {
var f = this[relationName].update;
f.apply(this, arguments);
};
modelFrom.prototype['__destroy__' + relationName] = function() {
var f = this[relationName].destroy;
f.apply(this, arguments);
};
return definition; return definition;
}; };
@ -1545,10 +1559,12 @@ 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;
var fk = this.definition.keyTo;
this.fetch(function(err, targetModel) { this.fetch(function(err, targetModel) {
if (targetModel instanceof ModelBaseClass) { if (targetModel instanceof ModelBaseClass) {
delete targetModelData[fk];
targetModel.updateAttributes(targetModelData, cb); targetModel.updateAttributes(targetModelData, cb);
} else { } else {
cb(new Error('HasOne relation ' + definition.name cb(new Error('HasOne relation ' + definition.name

View File

@ -221,7 +221,7 @@ describe('manipulation', function () {
before(function (done) { before(function (done) {
Person.destroyAll(function () { Person.destroyAll(function () {
person = Person.create(done); person = Person.create({name: 'Mary', age: 15}, done);
}); });
}); });
@ -236,6 +236,33 @@ describe('manipulation', function () {
}); });
}); });
}); });
it('should ignore undefined values on updateAttributes', function(done) {
person.updateAttributes({'name': 'John', age: undefined},
function(err, p) {
should.not.exist(err);
Person.findById(p.id, function(e, p) {
should.not.exist(err);
p.name.should.equal('John');
p.age.should.equal(15);
done();
});
});
});
it('should allows model instance on updateAttributes', function(done) {
person.updateAttributes(new Person({'name': 'John', age: undefined}),
function(err, p) {
should.not.exist(err);
Person.findById(p.id, function(e, p) {
should.not.exist(err);
p.name.should.equal('John');
p.age.should.equal(15);
done();
});
});
});
}); });
describe('destroy', function () { describe('destroy', function () {

View File

@ -1809,6 +1809,24 @@ describe('relations', function () {
}); });
}); });
}); });
it('should ignore the foreign key in the update', function(done) {
Supplier.create({name: 'Supplier 2'}, function (e, supplier) {
var sid = supplier.id;
Supplier.findById(supplierId, function(e, supplier) {
should.not.exist(e);
should.exist(supplier);
supplier.account.update({supplierName: 'Supplier A',
supplierId: sid},
function(err, act) {
should.not.exist(e);
act.supplierName.should.equal('Supplier A');
act.supplierId.should.equal(supplierId);
done();
});
});
});
});
it('should get the related item on scope', function(done) { it('should get the related item on scope', function(done) {
Supplier.findById(supplierId, function(e, supplier) { Supplier.findById(supplierId, function(e, supplier) {