Merge pull request #650 from PradnyaBaviskar/issue-649

Fix 'persist' hook for updateAttributes()
This commit is contained in:
Raymond Feng 2015-07-23 08:27:07 -07:00
commit b08b6dd954
2 changed files with 63 additions and 9 deletions

View File

@ -2380,14 +2380,16 @@ DataAccessObject.prototype.updateAttributes = function updateAttributes(data, op
}
}
context.data = typedData;
function updateAttributesCallback(err) {
var context = {
var ctx = {
Model: Model,
data: data,
data: context.data,
hookState: hookState,
options: options
};
Model.notifyObserversOf('loaded', context, function(err) {
Model.notifyObserversOf('loaded', ctx, function(err) {
if (!err) inst.__persisted = true;
// By default, the instance passed to updateAttributes callback is NOT updated
@ -2395,7 +2397,7 @@ DataAccessObject.prototype.updateAttributes = function updateAttributes(data, op
// backwards compatibility, we introduced a new setting updateOnLoad,
// which if set, will apply these changes to the model instance too.
if(Model.settings.updateOnLoad) {
inst.setAttributes(context.data);
inst.setAttributes(ctx.data);
}
done.call(inst, function () {
saveDone.call(inst, function () {
@ -2417,21 +2419,21 @@ DataAccessObject.prototype.updateAttributes = function updateAttributes(data, op
});
}
context = {
var ctx = {
Model: Model,
where: byIdQuery(Model, getIdValue(Model, inst)).where,
data: data,
data: context.data,
currentInstance: inst,
hookState: hookState,
options: options
};
Model.notifyObserversOf('persist', context, function(err) {
Model.notifyObserversOf('persist', ctx, function(err) {
if (connector.updateAttributes.length === 5) {
connector.updateAttributes(model, getIdValue(inst.constructor, inst),
inst.constructor._forDB(typedData), options, updateAttributesCallback);
inst.constructor._forDB(context.data), options, updateAttributesCallback);
} else {
connector.updateAttributes(model, getIdValue(inst.constructor, inst),
inst.constructor._forDB(typedData), updateAttributesCallback);
inst.constructor._forDB(context.data), updateAttributesCallback);
}
});
}, data, cb);

View File

@ -1154,6 +1154,58 @@ module.exports = function(dataSource, should) {
});
});
it('applies updates from `persist` hook - for nested model instance', function(done) {
var Address = dataSource.createModel('Address', {
id: { type: String, id: true, default: 1 },
city: { type: String, required: true },
country: { type: String, required: true }
});
var User = dataSource.createModel('User', {
id: { type: String, id: true, default: uid() },
name: { type: String, required: true },
address: {type: Address, required: false}
});
User.create({name: 'Joe'}, function(err, instance) {
if (err) return done(err);
var existingUser = instance;
User.observe('persist', pushContextAndNext(function(ctx){
should.exist(ctx.data.address)
ctx.data.address.should.be.type('object');
ctx.data.address.should.not.be.instanceOf(Address);
ctx.data.extra = 'hook data';
}));
// By default, the instance passed to updateAttributes callback is NOT updated
// with the changes made through persist/loaded hooks. To preserve
// backwards compatibility, we introduced a new setting updateOnLoad,
// which if set, will apply these changes to the model instance too.
User.settings.updateOnLoad = true;
existingUser.updateAttributes(
{ address: new Address({city: 'Springfield', country: 'USA'}) },
function(err, inst) {
if (err) return done(err);
inst.should.have.property('extra', 'hook data');
User.findById(existingUser.id, function(err, dbInstance) {
if (err) return done(err);
dbInstance.toObject(true).should.eql({
id: existingUser.id,
name: existingUser.name,
address: {id: '1', city: 'Springfield', country: 'USA'},
extra: 'hook data'
});
done();
});
});
});
});
it('triggers `loaded` hook', function(done) {
TestModel.observe('loaded', pushContextAndNext());
existingInstance.updateAttributes({ name: 'changed' }, function(err) {