support embeds data for belongsTo relation
Signed-off-by: Clark Wang <clark.wangs@gmail.com>
This commit is contained in:
parent
0019501a8b
commit
83c3a17f87
11
lib/model.js
11
lib/model.js
|
@ -13,6 +13,8 @@ var List = require('./list');
|
|||
var Hookable = require('./hooks');
|
||||
var validations = require('./validations');
|
||||
var _extend = util._extend;
|
||||
var utils = require('./utils');
|
||||
var fieldsToArray = utils.fieldsToArray;
|
||||
|
||||
// Set up an object for quick lookup
|
||||
var BASE_TYPES = {
|
||||
|
@ -170,7 +172,16 @@ ModelBaseClass.prototype._initProperties = function (data, options) {
|
|||
if (relationType === 'belongsTo' && propVal != null) {
|
||||
// If the related model is populated
|
||||
self.__data[ctor.relations[p].keyFrom] = propVal[ctor.relations[p].keyTo];
|
||||
|
||||
if (ctor.relations[p].options.embedsProperties) {
|
||||
var fields = fieldsToArray(ctor.relations[p].properties, modelTo.definition.properties);
|
||||
if (!~fields.indexOf(ctor.relations[p].keyTo)) {
|
||||
fields.push(ctor.relations[p].keyTo);
|
||||
}
|
||||
self.__data[p] = new modelTo(propVal, { fields: fields, applySetters: false, persisted: options.persisted });
|
||||
}
|
||||
}
|
||||
|
||||
self.__cachedRelations[p] = propVal;
|
||||
} else {
|
||||
// Un-managed property
|
||||
|
|
|
@ -208,11 +208,20 @@ RelationDefinition.prototype.applyProperties = function(modelInstance, obj) {
|
|||
if (this.options.invertProperties) {
|
||||
source = obj, target = modelInstance;
|
||||
}
|
||||
if (this.options.embedsProperties) {
|
||||
target = target.__data[this.name] = {};
|
||||
target[this.keyTo] = source[this.keyTo];
|
||||
}
|
||||
if (typeof this.properties === 'function') {
|
||||
var data = this.properties.call(this, source);
|
||||
for(var k in data) {
|
||||
target[k] = data[k];
|
||||
}
|
||||
} else if (Array.isArray(this.properties)) {
|
||||
for(var k = 0; k < this.properties.length; k++) {
|
||||
var key = this.properties[k];
|
||||
target[key] = source[key];
|
||||
}
|
||||
} else if (typeof this.properties === 'object') {
|
||||
for(var k in this.properties) {
|
||||
var key = this.properties[k];
|
||||
|
@ -1309,7 +1318,7 @@ BelongsTo.prototype.related = function (refresh, params) {
|
|||
}
|
||||
|
||||
var cb = params;
|
||||
if (cachedValue === undefined) {
|
||||
if (cachedValue === undefined || !(cachedValue instanceof ModelBaseClass)) {
|
||||
var query = {where: {}};
|
||||
query.where[pk] = modelInstance[fk];
|
||||
|
||||
|
|
|
@ -1718,6 +1718,45 @@ describe('relations', function () {
|
|||
|
||||
});
|
||||
|
||||
describe('belongsTo with embed', function () {
|
||||
var Person, Passport;
|
||||
|
||||
it('can be declared with embed and properties', function (done) {
|
||||
Person = db.define('Person', {name: String, age: Number});
|
||||
Passport = db.define('Passport', {name: String, notes: String});
|
||||
Passport.belongsTo(Person, {
|
||||
properties: ['name'],
|
||||
options: { embedsProperties: true, invertProperties: true }
|
||||
});
|
||||
db.automigrate(done);
|
||||
});
|
||||
|
||||
it('should create record with embedded data', function (done) {
|
||||
Person.create({name: 'Fred', age: 36 }, function(err, person) {
|
||||
var p = new Passport({ name: 'Passport', notes: 'Some notes...' });
|
||||
p.person(person);
|
||||
p.personId.should.equal(person.id);
|
||||
var data = p.toObject(true);
|
||||
data.person.id.should.equal(person.id);
|
||||
data.person.name.should.equal('Fred');
|
||||
p.save(function (err) {
|
||||
should.not.exists(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should find record with embedded data', function (done) {
|
||||
Passport.findOne(function (err, p) {
|
||||
should.not.exists(err);
|
||||
var data = p.toObject(true);
|
||||
data.person.id.should.equal(p.personId);
|
||||
data.person.name.should.equal('Fred');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('hasOne', function () {
|
||||
var Supplier, Account;
|
||||
var supplierId, accountId;
|
||||
|
|
Loading…
Reference in New Issue