Convenience embedsMany accessors: at(idx), get(id), set(id, data)

This commit is contained in:
Fabien Franzen 2014-07-29 10:51:33 +02:00
parent cb43114ab7
commit 6ed7a0a5f2
3 changed files with 80 additions and 1 deletions

View File

@ -18,6 +18,7 @@ var RelationTypes = {
hasMany: 'hasMany',
hasOne: 'hasOne',
hasAndBelongsToMany: 'hasAndBelongsToMany',
referencesMany: 'referencesMany',
embedsMany: 'embedsMany'
};
@ -27,6 +28,7 @@ exports.HasManyThrough = HasManyThrough;
exports.HasOne = HasOne;
exports.HasAndBelongsToMany = HasAndBelongsToMany;
exports.BelongsTo = BelongsTo;
exports.ReferencesMany = ReferencesMany;
exports.EmbedsMany = EmbedsMany;
var RelationClasses = {
@ -35,6 +37,7 @@ var RelationClasses = {
hasManyThrough: HasManyThrough,
hasOne: HasOne,
hasAndBelongsToMany: HasAndBelongsToMany,
referencesMany: ReferencesMany,
embedsMany: EmbedsMany
};
@ -314,6 +317,24 @@ function EmbedsMany(definition, modelInstance) {
util.inherits(EmbedsMany, Relation);
/**
* ReferencesMany subclass
* @param {RelationDefinition|Object} definition
* @param {Object} modelInstance
* @returns {HasMany}
* @constructor
* @class HasMany
*/
function ReferencesMany(definition, modelInstance) {
if (!(this instanceof HasMany)) {
return new HasMany(definition, modelInstance);
}
assert(definition.type === RelationTypes.hasMany);
Relation.apply(this, arguments);
}
util.inherits(ReferencesMany, Relation);
/*!
* Find the relation by foreign key
* @param {*} foreignKey The foreign key
@ -1477,7 +1498,10 @@ RelationDefinition.embedsMany = function hasMany(modelFrom, modelTo, params) {
findById: scopeMethod(definition, 'findById'),
destroy: scopeMethod(definition, 'destroyById'),
updateById: scopeMethod(definition, 'updateById'),
exists: scopeMethod(definition, 'exists')
exists: scopeMethod(definition, 'exists'),
get: scopeMethod(definition, 'get'),
set: scopeMethod(definition, 'set'),
at: scopeMethod(definition, 'at')
};
var findByIdFunc = scopeMethods.findById;
@ -1634,6 +1658,28 @@ EmbedsMany.prototype.destroyById = function (fkId, cb) {
return inst; // sync
};
EmbedsMany.prototype.get = EmbedsMany.prototype.findById;
EmbedsMany.prototype.set = EmbedsMany.prototype.updateById;
EmbedsMany.prototype.at = function (index, cb) {
var modelTo = this.definition.modelTo;
var relationName = this.definition.name;
var modelInstance = this.modelInstance;
var embeddedList = modelInstance[relationName] || [];
var item = embeddedList[parseInt(index)];
item = (item instanceof modelTo) ? item : null;
if (typeof cb === 'function') {
process.nextTick(function() {
cb(null, item);
});
};
return item; // sync
};
EmbedsMany.prototype.create = function (targetModelData, cb) {
var pk = this.definition.keyFrom;
var modelTo = this.definition.modelTo;

View File

@ -162,6 +162,10 @@ RelationMixin.hasOne = function hasMany(modelTo, params) {
RelationDefinition.hasOne(this, modelTo, params);
};
RelationMixin.referencesMany = function hasMany(modelTo, params) {
RelationDefinition.referencesMany(this, modelTo, params);
};
RelationMixin.embedsMany = function hasMany(modelTo, params) {
RelationDefinition.embedsMany(this, modelTo, params);
};

View File

@ -5,6 +5,7 @@ var db, Book, Chapter, Author, Reader;
var Category, Product;
var Picture, PictureLink;
var Person, Address;
var Link;
describe('relations', function () {
@ -1370,6 +1371,20 @@ describe('relations', function () {
});
});
it('should have accessors: at, get, set', function(done) {
Person.findOne(function(err, p) {
p.addressList.at(0).id.should.equal(address1.id);
p.addressList.get(address1.id).id.should.equal(address1.id);
p.addressList.set(address1.id, { street: 'Changed 1' });
p.addresses[0].street.should.equal('Changed 1');
p.addressList.at(1).id.should.equal(address2.id);
p.addressList.get(address2.id).id.should.equal(address2.id);
p.addressList.set(address2.id, { street: 'Changed 2' });
p.addresses[1].street.should.equal('Changed 2');
done();
});
});
it('should remove embedded items by id', function(done) {
Person.findOne(function(err, p) {
p.addresses.should.have.length(2);
@ -1510,6 +1525,20 @@ describe('relations', function () {
});
});
it('should have accessors: at, get, set', function(done) {
Person.findOne({ where: { name: 'Wilma' } }, function(err, p) {
p.name.should.equal('Wilma');
p.addresses.should.have.length(2);
p.addressList.at(0).id.should.equal('home');
p.addressList.get('home').id.should.equal('home');
p.addressList.set('home', { id: 'den' }).id.should.equal('den');
p.addressList.at(1).id.should.equal('work');
p.addressList.get('work').id.should.equal('work');
p.addressList.set('work', { id: 'factory' }).id.should.equal('factory');
done();
});
});
});
});