parent
9b3d432942
commit
53f39a046a
|
@ -67,6 +67,7 @@ function AbstractClass(data) {
|
||||||
enumerable: true
|
enumerable: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (data.hasOwnProperty(attr)) {
|
||||||
// Getter for initial property
|
// Getter for initial property
|
||||||
Object.defineProperty(this, attr_was, {
|
Object.defineProperty(this, attr_was, {
|
||||||
writable: true,
|
writable: true,
|
||||||
|
@ -74,6 +75,7 @@ function AbstractClass(data) {
|
||||||
configurable: true,
|
configurable: true,
|
||||||
enumerable: false
|
enumerable: false
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|
||||||
|
@ -130,6 +132,8 @@ AbstractClass.create = function (data, callback) {
|
||||||
if (data instanceof AbstractClass && !data.id) {
|
if (data instanceof AbstractClass && !data.id) {
|
||||||
obj = data;
|
obj = data;
|
||||||
data = obj.toObject(true);
|
data = obj.toObject(true);
|
||||||
|
// recall constructor to update _was property states (maybe bad idea)
|
||||||
|
this.call(obj, data);
|
||||||
create();
|
create();
|
||||||
} else {
|
} else {
|
||||||
obj = new this(data);
|
obj = new this(data);
|
||||||
|
@ -204,19 +208,15 @@ AbstractClass.all = function all(params, cb) {
|
||||||
if (data && data.map) {
|
if (data && data.map) {
|
||||||
collection = data.map(function (d) {
|
collection = data.map(function (d) {
|
||||||
var obj = null;
|
var obj = null;
|
||||||
// really questionable stuff
|
// do not create different instances for the same object
|
||||||
// goal is obvious: to not create different instances for the same object
|
if (d.id && constr.cache[d.id]) {
|
||||||
// but the way it implemented...
|
|
||||||
// we can lost some dirty state of object, for example
|
|
||||||
// TODO: think about better implementation, test keeping dirty state
|
|
||||||
if (constr.cache[d.id]) {
|
|
||||||
obj = constr.cache[d.id];
|
obj = constr.cache[d.id];
|
||||||
// keep dirty attributes untouthed (remove from dataset)
|
// keep dirty attributes untouthed (remove from dataset)
|
||||||
substractDirtyAttributes(obj, d);
|
substractDirtyAttributes(obj, d);
|
||||||
constr.call(obj, d);
|
constr.call(obj, d);
|
||||||
} else {
|
} else {
|
||||||
obj = new constr(d);
|
obj = new constr(d);
|
||||||
constr.cache[d.id] = obj;
|
if (d.id) constr.cache[d.id] = obj;
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
});
|
});
|
||||||
|
@ -227,7 +227,7 @@ AbstractClass.all = function all(params, cb) {
|
||||||
|
|
||||||
function substractDirtyAttributes(object, data) {
|
function substractDirtyAttributes(object, data) {
|
||||||
Object.keys(object.toObject()).forEach(function (attr) {
|
Object.keys(object.toObject()).forEach(function (attr) {
|
||||||
if (attr in data && object.propertyChanged(attr)) {
|
if (data.hasOwnProperty(attr) && object.propertyChanged(attr)) {
|
||||||
delete data[attr];
|
delete data[attr];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -370,30 +370,34 @@ AbstractClass.prototype.updateAttribute = function (name, value, cb) {
|
||||||
AbstractClass.prototype.updateAttributes = function updateAttributes(data, cb) {
|
AbstractClass.prototype.updateAttributes = function updateAttributes(data, cb) {
|
||||||
var inst = this;
|
var inst = this;
|
||||||
var model = this.constructor.modelName;
|
var model = this.constructor.modelName;
|
||||||
Object.keys(data).forEach(function (key) {
|
|
||||||
this[key] = data[key];
|
|
||||||
}.bind(this));
|
|
||||||
|
|
||||||
this.isValid(function (valid) {
|
// update instance's properties
|
||||||
|
Object.keys(data).forEach(function (key) {
|
||||||
|
inst[key] = data[key];
|
||||||
|
});
|
||||||
|
|
||||||
|
inst.isValid(function (valid) {
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
if (cb) {
|
if (cb) {
|
||||||
cb(new Error('Validation error'));
|
cb(new Error('Validation error'));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
update.call(this);
|
update();
|
||||||
}
|
}
|
||||||
}.bind(this));
|
});
|
||||||
|
|
||||||
function update() {
|
function update() {
|
||||||
this.trigger('save', function (saveDone) {
|
inst.trigger('save', function (saveDone) {
|
||||||
this.trigger('update', function (done) {
|
inst.trigger('update', function (done) {
|
||||||
|
|
||||||
Object.keys(data).forEach(function (key) {
|
Object.keys(data).forEach(function (key) {
|
||||||
data[key] = this[key];
|
data[key] = inst[key];
|
||||||
}.bind(this));
|
});
|
||||||
|
|
||||||
this._adapter().updateAttributes(model, this.id, data, function (err) {
|
inst._adapter().updateAttributes(model, inst.id, data, function (err) {
|
||||||
if (!err) {
|
if (!err) {
|
||||||
|
inst.constructor.call(inst, data);
|
||||||
|
/*
|
||||||
Object.keys(data).forEach(function (key) {
|
Object.keys(data).forEach(function (key) {
|
||||||
inst[key] = data[key];
|
inst[key] = data[key];
|
||||||
Object.defineProperty(inst, key + '_was', {
|
Object.defineProperty(inst, key + '_was', {
|
||||||
|
@ -403,13 +407,14 @@ AbstractClass.prototype.updateAttributes = function updateAttributes(data, cb) {
|
||||||
value: data[key]
|
value: data[key]
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
done.call(inst, function () {
|
done.call(inst, function () {
|
||||||
saveDone.call(inst, function () {
|
saveDone.call(inst, function () {
|
||||||
cb(err);
|
cb(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}.bind(this));
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,10 +188,23 @@ function testOrm(schema) {
|
||||||
obj.save(function (err, obj) {
|
obj.save(function (err, obj) {
|
||||||
test.equal(obj.title, title2);
|
test.equal(obj.title, title2);
|
||||||
test.ok(!obj.propertyChanged('title'));
|
test.ok(!obj.propertyChanged('title'));
|
||||||
|
|
||||||
|
var p = new Post({title: 1});
|
||||||
|
p.title = 2;
|
||||||
|
p.save(function (err, obj) {
|
||||||
|
test.ok(!p.propertyChanged('title'));
|
||||||
|
p.title = 3;
|
||||||
|
test.ok(p.propertyChanged('title'));
|
||||||
|
test.equal(p.title_was, 2);
|
||||||
|
p.save(function () {
|
||||||
|
test.equal(p.title_was, 3);
|
||||||
|
test.ok(!p.propertyChanged('title'));
|
||||||
test.done();
|
test.done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should create object with initial data', function (test) {
|
it('should create object with initial data', function (test) {
|
||||||
var title = 'Initial title',
|
var title = 'Initial title',
|
||||||
|
|
|
@ -16,6 +16,7 @@ User = schema.define 'User',
|
||||||
domain: String
|
domain: String
|
||||||
pendingPeriod: Number
|
pendingPeriod: Number
|
||||||
createdByAdmin: Boolean
|
createdByAdmin: Boolean
|
||||||
|
updatedAt: Date
|
||||||
|
|
||||||
validAttributes =
|
validAttributes =
|
||||||
name: 'Anatoliy'
|
name: 'Anatoliy'
|
||||||
|
@ -247,7 +248,7 @@ it 'should validate asynchronously', (test) ->
|
||||||
setTimeout =>
|
setTimeout =>
|
||||||
err 'async' if @name == 'bad name'
|
err 'async' if @name == 'bad name'
|
||||||
done()
|
done()
|
||||||
, 100
|
, 10
|
||||||
|
|
||||||
User.validateAsync 'name', validator, message: async: 'hello'
|
User.validateAsync 'name', validator, message: async: 'hello'
|
||||||
|
|
||||||
|
@ -272,14 +273,21 @@ it 'should validate uniqueness', (test) ->
|
||||||
user.email = 'unique@email.tld'
|
user.email = 'unique@email.tld'
|
||||||
user.isValid (valid) ->
|
user.isValid (valid) ->
|
||||||
test.ok valid, 'valid with unique email'
|
test.ok valid, 'valid with unique email'
|
||||||
user.save ->
|
user.save (err) ->
|
||||||
|
test.ok not user.propertyChanged('email'), 'Email changed'
|
||||||
|
user.updateAttributes { updatedAt: new Date, createdByAdmin: false }, (err) ->
|
||||||
|
User.all where: email: 'unique@email.tld', (err, users) ->
|
||||||
|
test.ok users[0]
|
||||||
|
test.ok users[0].email == 'unique@email.tld'
|
||||||
|
test.ok !err, 'Updated'
|
||||||
test.done()
|
test.done()
|
||||||
|
|
||||||
it 'should save dirty state when validating uniqueness', (test) ->
|
it 'should save dirty state when validating uniqueness', (test) ->
|
||||||
User.all where: email: 'unique@email.tld' , (err, users) ->
|
User.all where: email: 'unique@email.tld', (err, users) ->
|
||||||
u = users[0]
|
u = users[0]
|
||||||
u.name = 'Hulk'
|
u.name = 'Hulk'
|
||||||
u.isValid (valid) ->
|
u.isValid (valid) ->
|
||||||
test.ok valid
|
test.ok valid, 'Invalid user'
|
||||||
test.equal u.name, 'Hulk'
|
test.equal u.name, 'Hulk'
|
||||||
test.done()
|
test.done()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue