Merge pull request #78 from mitsos1os/issue-42
Support retrieved related models from remote loopback service
This commit is contained in:
commit
d622ce5ed8
|
@ -49,7 +49,6 @@ module.exports = function(grunt) {
|
|||
|
||||
// These plugins provide necessary tasks.
|
||||
grunt.loadNpmTasks('grunt-mocha-test');
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
|
||||
// Default task.
|
||||
grunt.registerTask('default', ['unit', 'integration']);
|
||||
|
|
|
@ -211,10 +211,23 @@ RelationMixin.embedsMany = function embedsMany(modelTo, params) {
|
|||
function defineRelationProperty(modelClass, def) {
|
||||
Object.defineProperty(modelClass.prototype, def.name, {
|
||||
get: function() {
|
||||
var that = this;
|
||||
var scope = function() {
|
||||
return that['__get__' + def.name].apply(that, arguments);
|
||||
const that = this;
|
||||
const scope = function() {
|
||||
const cachedEntities = that.__cachedRelations &&
|
||||
that.__cachedRelations[def.name];
|
||||
|
||||
if (arguments.length || !cachedEntities) {
|
||||
return that['__get__' + def.name].apply(that, arguments);
|
||||
}
|
||||
|
||||
// return the cached data
|
||||
if (Array.isArray(cachedEntities)) {
|
||||
return cachedEntities.map(data => new def.modelTo(data));
|
||||
} else {
|
||||
return new def.modelTo(cachedEntities);
|
||||
}
|
||||
};
|
||||
|
||||
scope.count = function() {
|
||||
return that['__count__' + def.name].apply(that, arguments);
|
||||
};
|
||||
|
|
|
@ -87,7 +87,17 @@ RemoteConnector.prototype.resolve = function(Model) {
|
|||
|
||||
// setup a remoting type converter for this model
|
||||
remotes.defineObjectType(Model.modelName, function(data) {
|
||||
return new Model(data);
|
||||
const model = new Model(data);
|
||||
|
||||
// process cached relations
|
||||
if (model.__cachedRelations) {
|
||||
for (const relation in model.__cachedRelations) {
|
||||
const relatedModel = model.__cachedRelations[relation];
|
||||
model.__data[relation] = relatedModel;
|
||||
}
|
||||
}
|
||||
|
||||
return model;
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -11,7 +11,8 @@ const loopback = require('loopback');
|
|||
const TaskEmitter = require('strong-task-emitter');
|
||||
|
||||
describe('Remote model tests', function() {
|
||||
let serverApp, ServerModel, clientApp, ClientModel;
|
||||
let serverApp, ServerModel, ServerRelatedModel, ServerModelWithSingleChild,
|
||||
clientApp, ClientModel, ClientRelatedModel, ClientModelWithSingleChild;
|
||||
|
||||
beforeEach(function setupServer(done) {
|
||||
const app = serverApp = helper.createRestAppAndListen();
|
||||
|
@ -19,10 +20,46 @@ describe('Remote model tests', function() {
|
|||
|
||||
ServerModel = app.registry.createModel({
|
||||
name: 'TestModel',
|
||||
properties: helper.userProperties,
|
||||
properties: helper.getUserProperties(),
|
||||
options: {
|
||||
forceId: false,
|
||||
relations: {
|
||||
children: {
|
||||
type: 'hasMany',
|
||||
model: 'ChildModel',
|
||||
foreignKey: 'parentId',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
ServerModelWithSingleChild = app.registry.createModel({
|
||||
name: 'TestModelWithSingleChild',
|
||||
properties: helper.getUserProperties(),
|
||||
options: {
|
||||
forceId: false,
|
||||
relations: {
|
||||
child: {
|
||||
type: 'hasOne',
|
||||
model: 'ChildModel',
|
||||
foreignKey: 'parentId',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
ServerRelatedModel = app.registry.createModel({
|
||||
name: 'ChildModel',
|
||||
properties: {
|
||||
note: {type: 'text'},
|
||||
parentId: {type: 'number'},
|
||||
},
|
||||
options: {forceId: false},
|
||||
});
|
||||
|
||||
app.model(ServerModel, {dataSource: db});
|
||||
app.model(ServerRelatedModel, {dataSource: db});
|
||||
app.model(ServerModelWithSingleChild, {dataSource: db});
|
||||
|
||||
serverApp.locals.handler.on('listening', function() { done(); });
|
||||
});
|
||||
|
@ -31,15 +68,56 @@ describe('Remote model tests', function() {
|
|||
const app = clientApp = loopback({localRegistry: true});
|
||||
const remoteDs = helper.createRemoteDataSource(clientApp, serverApp);
|
||||
|
||||
ClientRelatedModel = app.registry.createModel({
|
||||
name: 'ChildModel',
|
||||
properties: {
|
||||
note: {type: 'text'},
|
||||
parentId: {type: 'number'},
|
||||
},
|
||||
options: {
|
||||
strict: true,
|
||||
},
|
||||
});
|
||||
|
||||
ClientModel = app.registry.createModel({
|
||||
name: 'TestModel',
|
||||
properties: helper.getUserProperties(),
|
||||
options: {
|
||||
relations: {
|
||||
children: {
|
||||
type: 'hasMany',
|
||||
model: 'ChildModel',
|
||||
foreignKey: 'parentId',
|
||||
},
|
||||
},
|
||||
strict: true,
|
||||
},
|
||||
});
|
||||
|
||||
ClientModelWithSingleChild = app.registry.createModel({
|
||||
name: 'TestModelWithSingleChild',
|
||||
properties: helper.getUserProperties(),
|
||||
options: {
|
||||
relations: {
|
||||
child: {
|
||||
type: 'hasOne',
|
||||
model: 'ChildModel',
|
||||
foreignKey: 'parentId',
|
||||
},
|
||||
},
|
||||
strict: true,
|
||||
},
|
||||
});
|
||||
|
||||
app.model(ClientModel, {dataSource: remoteDs});
|
||||
app.model(ClientRelatedModel, {dataSource: remoteDs});
|
||||
app.model(ClientModelWithSingleChild, {dataSource: remoteDs});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
serverApp.locals.handler.close();
|
||||
ServerModel = null;
|
||||
ServerRelatedModel = null;
|
||||
ClientModel = null;
|
||||
});
|
||||
|
||||
|
@ -160,4 +238,82 @@ describe('Remote model tests', function() {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Model find with include filter', function() {
|
||||
let hasManyParent, hasManyChild, hasOneParent, hasOneChild;
|
||||
beforeEach(givenSampleData);
|
||||
|
||||
it('should return also the included requested models', function() {
|
||||
const parentId = hasManyParent.id;
|
||||
return ClientModel.findById(hasManyParent.id, {include: 'children'})
|
||||
.then(returnedUser => {
|
||||
assert(returnedUser instanceof ClientModel);
|
||||
const user = returnedUser.toJSON();
|
||||
assert.equal(user.id, parentId);
|
||||
assert.equal(user.first, hasManyParent.first);
|
||||
assert(Array.isArray(user.children));
|
||||
assert.equal(user.children.length, 1);
|
||||
assert.deepEqual(user.children[0], hasManyChild.toJSON());
|
||||
});
|
||||
});
|
||||
|
||||
it('should return cachedRelated entity without call', function() {
|
||||
const parentId = hasManyParent.id;
|
||||
return ClientModel.findById(parentId, {include: 'children'})
|
||||
.then(returnedUser => {
|
||||
assert(returnedUser instanceof ClientModel);
|
||||
const children = returnedUser.children();
|
||||
assert.equal(returnedUser.id, parentId);
|
||||
assert.equal(returnedUser.first, hasManyParent.first);
|
||||
assert(Array.isArray(children));
|
||||
assert.equal(children.length, 1);
|
||||
assert(children[0] instanceof ClientRelatedModel);
|
||||
assert.deepEqual(children[0].toJSON(), hasManyChild.toJSON());
|
||||
});
|
||||
});
|
||||
|
||||
it('should also work for single (non array) relations', function() {
|
||||
const parentId = hasOneParent.id;
|
||||
return ClientModelWithSingleChild.findById(parentId, {include: 'child'})
|
||||
.then(returnedUser => {
|
||||
assert(returnedUser instanceof ClientModelWithSingleChild);
|
||||
const child = returnedUser.child();
|
||||
assert.equal(returnedUser.id, parentId);
|
||||
assert.equal(returnedUser.first, hasOneParent.first);
|
||||
assert(child instanceof ClientRelatedModel);
|
||||
assert.deepEqual(child.toJSON(), hasOneChild.toJSON());
|
||||
});
|
||||
});
|
||||
|
||||
function givenSampleData() {
|
||||
return ServerModel.create({first: 'eiste', last: 'kopries'})
|
||||
.then(parent => {
|
||||
hasManyParent = parent;
|
||||
return ServerRelatedModel.create({
|
||||
note: 'mitsos',
|
||||
parentId: parent.id,
|
||||
id: 11,
|
||||
});
|
||||
})
|
||||
.then(child => {
|
||||
hasManyChild = child;
|
||||
return ServerModelWithSingleChild.create({
|
||||
first: 'mipos',
|
||||
last: 'tora',
|
||||
id: 12,
|
||||
});
|
||||
})
|
||||
.then(parent => {
|
||||
hasOneParent = parent;
|
||||
return ServerRelatedModel.create({
|
||||
note: 'mitsos3',
|
||||
parentId: parent.id,
|
||||
id: 13,
|
||||
});
|
||||
})
|
||||
.then(child => {
|
||||
hasOneChild = child;
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue