diff --git a/lib/include.js b/lib/include.js index b989f5b1..2e685bb1 100644 --- a/lib/include.js +++ b/lib/include.js @@ -1,5 +1,6 @@ var async = require('async'); var utils = require('./utils'); +var List = require('./list'); var isPlainObject = utils.isPlainObject; var defineCachedRelations = utils.defineCachedRelations; @@ -734,6 +735,9 @@ Inclusion.include = function (objects, include, options, cb) { */ function setIncludeData(result, cb) { if (obj === inst) { + if (Array.isArray(result) && !(result instanceof List)) { + result = new List(result, relation.modelTo); + } obj.__data[relationName] = result; obj.setStrict(false); } else { diff --git a/test/include.test.js b/test/include.test.js index d513e215..073eb3b5 100644 --- a/test/include.test.js +++ b/test/include.test.js @@ -1,6 +1,9 @@ // This test written in mocha+should.js var should = require('./init.js'); var async = require('async'); +var assert = require('assert'); + +var DataSource = require('../').DataSource; var db, User, Profile, AccessToken, Post, Passport, City, Street, Building, Assembly, Part; @@ -690,3 +693,95 @@ function clearAndCreate(model, data, callback) { itemIndex++; } } + +describe('Model instance with included relation .toJSON()', function() { + var db, ChallengerModel, GameParticipationModel, ResultModel; + + before(function(done) { + db = new DataSource({connector: 'memory'}); + ChallengerModel = db.createModel('Challenger', + { + name: String + }, + { + relations: { + gameParticipations: { + type: 'hasMany', + model: 'GameParticipation', + foreignKey: '' + } + } + } + ); + GameParticipationModel = db.createModel('GameParticipation', + { + date: Date + }, + { + relations: { + challenger: { + type: 'belongsTo', + model: 'Challenger', + foreignKey: '' + }, + results: { + type: 'hasMany', + model: 'Result', + foreignKey: '' + } + } + } + ); + ResultModel = db.createModel('Result', { + points: Number, + }, { + relations: { + gameParticipation: { + type: 'belongsTo', + model: 'GameParticipation', + foreignKey: '' + } + } + }); + + async.waterfall([ + createChallengers, + createGameParticipations, + createResults], + function(err) { + done(err); + }); + + }); + + function createChallengers(callback) { + ChallengerModel.create([{name: 'challenger1'}, {name: 'challenger2'}], callback); + } + + function createGameParticipations(challengers, callback) { + GameParticipationModel.create([ + {challengerId: challengers[0].id, date: Date.now()}, + {challengerId: challengers[0].id, date: Date.now()} + ], callback); + } + + function createResults(gameParticipations, callback) { + ResultModel.create([ + {gameParticipationId: gameParticipations[0].id, points: 10}, + {gameParticipationId: gameParticipations[0].id, points: 20} + ], callback); + } + + it('should recursively serialize objects', function(done) { + var filter = {include: {gameParticipations: 'results'}}; + ChallengerModel.find(filter, function(err, challengers) { + + var levelOneInclusion = challengers[0].toJSON().gameParticipations[0]; + assert(levelOneInclusion.__data === undefined, '.__data of a level 1 inclusion is undefined.'); + + var levelTwoInclusion = challengers[0].toJSON().gameParticipations[0].results[0]; + assert(levelTwoInclusion.__data === undefined, '__data of a level 2 inclusion is undefined.'); + done(); + }); + }); +});