Allow `attributes` as an alias for `properties` (for LDL)

This commit is contained in:
Fabien Franzen 2014-09-07 14:31:06 +02:00
parent ec05d0b5a8
commit 0e49dc94ec
2 changed files with 50 additions and 10 deletions

View File

@ -95,6 +95,7 @@ DataAccessObject.applyScope = function(query, inst) {
DataAccessObject.applyProperties = function(data, inst) {
var properties = this.definition.settings.properties;
properties = properties || this.definition.settings.attributes;
if (typeof properties === 'object') {
util._extend(data, properties);
} else if (typeof properties === 'function') {
@ -107,6 +108,10 @@ DataAccessObject.applyProperties = function(data, inst) {
}
};
DataAccessObject.lookupModel = function(data) {
return this;
};
/**
* Create an instance of Model with given data and save to the attached data source. Callback is optional.
* Example:
@ -127,8 +132,8 @@ DataAccessObject.create = function (data, callback) {
if (stillConnecting(this.getDataSource(), this, arguments)) return;
var Model = this;
var modelName = Model.modelName;
var self = this;
if (typeof data === 'function') {
callback = data;
data = {};
@ -154,6 +159,7 @@ DataAccessObject.create = function (data, callback) {
for (var i = 0; i < data.length; i += 1) {
(function (d, i) {
Model = self.lookupModel(d); // data-specific
instances.push(Model.create(d, function (err, inst) {
if (err) {
errors[i] = err;
@ -169,11 +175,15 @@ DataAccessObject.create = function (data, callback) {
function modelCreated() {
if (--wait === 0) {
callback(gotError ? errors : null, instances);
if(!gotError) instances.forEach(Model.emit.bind('changed'));
if(!gotError) {
instances.forEach(function(inst) {
inst.constructor.emit('changed');
});
}
}
}
}
var enforced = {};
var obj;
var idValue = getIdValue(this, data);
@ -188,6 +198,9 @@ DataAccessObject.create = function (data, callback) {
this.applyProperties(enforced, obj);
obj.setAttributes(enforced);
Model = this.lookupModel(data); // data-specific
if (Model !== obj.constructor) obj = new Model(data);
data = obj.toObject(true);
// validation required
@ -198,12 +211,13 @@ DataAccessObject.create = function (data, callback) {
callback(new ValidationError(obj), obj);
}
}, data);
function create() {
obj.trigger('create', function (createDone) {
obj.trigger('save', function (saveDone) {
var _idName = idName(Model);
var modelName = Model.modelName;
this._adapter().create(modelName, this.constructor._forDB(obj.toObject(true)), function (err, id, rev) {
if (id) {
obj.__data[_idName] = id;
@ -251,7 +265,7 @@ DataAccessObject.updateOrCreate = DataAccessObject.upsert = function upsert(data
if (stillConnecting(this.getDataSource(), this, arguments)) {
return;
}
var self = this;
var Model = this;
if (!getIdValue(this, data)) {
return this.create(data, callback);
@ -265,6 +279,7 @@ DataAccessObject.updateOrCreate = DataAccessObject.upsert = function upsert(data
update = inst.toObject(false);
this.applyProperties(update, inst);
update = removeUndefined(update);
Model = this.lookupModel(update);
this.getDataSource().connector.updateOrCreate(Model.modelName, update, function (err, data) {
var obj;
if (data && !(data instanceof Model)) {
@ -286,6 +301,7 @@ DataAccessObject.updateOrCreate = DataAccessObject.upsert = function upsert(data
if (inst) {
inst.updateAttributes(data, callback);
} else {
Model = self.lookupModel(data);
var obj = new Model(data);
obj.save(data, callback);
}
@ -774,8 +790,9 @@ DataAccessObject.find = function find(query, cb) {
this.getDataSource().connector.all(this.modelName, query, function (err, data) {
if (data && data.forEach) {
data.forEach(function (d, i) {
var obj = new self(d, {fields: query.fields, applySetters: false, persisted: true});
var Model = self.lookupModel(d);
var obj = new Model(d, {fields: query.fields, applySetters: false, persisted: true});
if (query && query.include) {
if (query.collect) {
// The collect property indicates that the query is to return the

View File

@ -64,6 +64,12 @@ describe('default scope', function () {
scopes: { active: { where: { active: true } } }
});
Product.lookupModel = function(data) {
var m = this.dataSource.models[data.kind];
if (m.base === this) return m;
return this;
};
Tool = db.define('Tool', Product.definition.properties, {
base: 'Product',
scope: { where: { kind: 'Tool' }, order: 'name' },
@ -94,7 +100,7 @@ describe('default scope', function () {
Thing = db.define('Thing', Product.definition.properties, {
base: 'Product',
properties: propertiesFn,
attributes: propertiesFn,
scope: scopeFn,
mongodb: { collection: 'Product' },
memory: { collection: 'Product' }
@ -206,6 +212,7 @@ describe('default scope', function () {
Product.findById(ids.toolA, function(err, inst) {
should.not.exist(err);
inst.name.should.equal('Tool A');
inst.should.be.instanceof(Tool);
done();
});
});
@ -245,6 +252,13 @@ describe('default scope', function () {
products[2].name.should.equal('Widget A');
products[3].name.should.equal('Widget B');
products[4].name.should.equal('Widget Z');
products[0].should.be.instanceof(Product);
products[0].should.be.instanceof(Tool);
products[2].should.be.instanceof(Product);
products[2].should.be.instanceof(Widget);
done();
});
});
@ -702,11 +716,20 @@ describe('default scope', function () {
cat.products(function(err, products) {
should.not.exist(err);
products.should.have.length(4);
products[0].should.be.instanceof(Product);
products[0].name.should.equal('Thing A');
products[1].name.should.equal('Tool A');
products[2].name.should.equal('Widget A');
products[3].name.should.equal('Widget B');
products[0].should.be.instanceof(Product);
products[0].should.be.instanceof(Thing);
products[1].should.be.instanceof(Product);
products[1].should.be.instanceof(Tool);
products[2].should.be.instanceof(Product);
products[2].should.be.instanceof(Widget);
done();
});
});