"loaded" hook in DAO.find: ctx.data, not instance

Fix the implementation od DAO.find to provide "ctx.data" to the
"loaded" hook.
This commit is contained in:
Miroslav Bajtoš 2015-12-18 15:43:20 +01:00
parent 89e4555bc0
commit 3028329126
2 changed files with 57 additions and 48 deletions

View File

@ -266,7 +266,7 @@ DataAccessObject.create = function (data, options, cb) {
if (options.validate === undefined && Model.settings.automaticValidation === false) { if (options.validate === undefined && Model.settings.automaticValidation === false) {
return create(); return create();
} }
// validation required // validation required
obj.isValid(function (valid) { obj.isValid(function (valid) {
if (valid) { if (valid) {
@ -1455,56 +1455,64 @@ DataAccessObject.find = function find(query, options, cb) {
async.each(data, function(item, callback) { async.each(data, function(item, callback) {
var d = item;//data[i]; var d = item;//data[i];
var Model = self.lookupModel(d); var Model = self.lookupModel(d);
var obj = new Model(d, {fields: query.fields, applySetters: false, persisted: true});
if (query && query.include) { context = {
if (query.collect) { Model: Model,
// The collect property indicates that the query is to return the data: d,
// standalone items for a related model, not as child of the parent object isNewInstance: false,
// For example, article.tags hookState: hookState,
obj = obj.__cachedRelations[query.collect]; options: options
if (obj === null) { };
obj = undefined;
}
} else {
// This handles the case to return parent items including the related
// models. For example, Article.find({include: 'tags'}, ...);
// Try to normalize the include
var includes = Inclusion.normalizeInclude(query.include || []);
includes.forEach(function(inc) {
var relationName = inc;
if (utils.isPlainObject(inc)) {
relationName = Object.keys(inc)[0];
}
// Promote the included model as a direct property Model.notifyObserversOf('loaded', context, function(err) {
var included = obj.__cachedRelations[relationName]; if (err) return callback(err);
if (Array.isArray(included)) { d = context.data;
included = new List(included, null, obj);
} var ctorOpts = {
if (included) obj.__data[relationName] = included; fields: query.fields,
}); applySetters: false,
delete obj.__data.__cachedRelations; persisted: true
}
}
if (obj !== undefined) {
context = {
Model: Model,
instance: obj,
isNewInstance: false,
hookState: hookState,
options: options
}; };
var obj = new Model(d, ctorOpts);
Model.notifyObserversOf('loaded', context, function(err) { if (query && query.include) {
if (err) return callback(err); if (query.collect) {
// The collect property indicates that the query is to return the
// standalone items for a related model, not as child of the parent object
// For example, article.tags
obj = obj.__cachedRelations[query.collect];
if (obj === null) {
obj = undefined;
}
} else {
// This handles the case to return parent items including the related
// models. For example, Article.find({include: 'tags'}, ...);
// Try to normalize the include
var includes = Inclusion.normalizeInclude(query.include || []);
includes.forEach(function(inc) {
var relationName = inc;
if (utils.isPlainObject(inc)) {
relationName = Object.keys(inc)[0];
}
// Promote the included model as a direct property
var included = obj.__cachedRelations[relationName];
if (Array.isArray(included)) {
included = new List(included, null, obj);
}
if (included) obj.__data[relationName] = included;
});
delete obj.__data.__cachedRelations;
}
}
if (obj !== undefined) {
results.push(obj); results.push(obj);
callback(); callback();
}); } else {
} else { callback();
callback(); }
} });
}, },
function(err) { function(err) {
if (err) return cb(err); if (err) return cb(err);

View File

@ -129,7 +129,7 @@ module.exports = function(dataSource, should) {
it('applies updates from `loaded` hook', function(done) { it('applies updates from `loaded` hook', function(done) {
TestModel.observe('loaded', pushContextAndNext(function(ctx) { TestModel.observe('loaded', pushContextAndNext(function(ctx) {
ctx.instance.extra = 'hook data'; ctx.data.extra = 'hook data';
})); }));
TestModel.find( TestModel.find(
@ -138,7 +138,7 @@ module.exports = function(dataSource, should) {
if (err) return done(err); if (err) return done(err);
observedContexts.should.eql(aTestModelCtx({ observedContexts.should.eql(aTestModelCtx({
instance: { data: {
id: "1", id: "1",
name: "first", name: "first",
extra: "hook data" extra: "hook data"
@ -147,6 +147,8 @@ module.exports = function(dataSource, should) {
hookState: { test: true }, hookState: { test: true },
options: {} options: {}
})); }));
list[0].should.have.property('extra', 'hook data');
done(); done();
}); });
}) })
@ -1747,10 +1749,9 @@ module.exports = function(dataSource, should) {
// returns an array and NOT a single instance. // returns an array and NOT a single instance.
observedContexts.should.eql([ observedContexts.should.eql([
aTestModelCtx({ aTestModelCtx({
instance: { data: {
id: existingInstance.id, id: existingInstance.id,
name: 'first', name: 'first',
extra: null
}, },
isNewInstance: false, isNewInstance: false,
options: { notify: false } options: { notify: false }