Only check id as part of embedsMany relation

This commit is contained in:
Fabien Franzen 2014-09-07 12:17:42 +02:00
parent f9ce6c248d
commit 4c6f35d23d
2 changed files with 111 additions and 6 deletions

View File

@ -1865,12 +1865,26 @@ RelationDefinition.embedsMany = function embedsMany(modelFrom, modelTo, params)
embed: true
});
modelFrom.dataSource.defineProperty(modelFrom.modelName, propertyName, {
modelFrom.dataSource.defineProperty(modelFrom.modelName, propertyName, {
type: [modelTo], default: function() { return []; }
});
if (typeof modelTo.dataSource.connector.generateId !== 'function') {
modelTo.validatesPresenceOf(idName); // unique id is required
if (typeof modelTo.dataSource.connector.generateId !== 'function'
|| !modelFrom.definition.settings.idInjection) {
modelFrom.validate(propertyName, function(err) {
var self = this;
var embeddedList = this[propertyName] || [];
var hasErrors = false;
embeddedList.forEach(function(item, idx) {
if (item instanceof modelTo && item[idName] == undefined) {
hasErrors = true;
var msg = 'contains invalid item at index `' + idx + '`:';
msg += ' `' + idName + '` is blank';
self.errors.add(propertyName, msg, 'invalid');
}
});
if (hasErrors) err(false);
});
}
if (!params.polymorphic) {
@ -1893,13 +1907,17 @@ RelationDefinition.embedsMany = function embedsMany(modelFrom, modelTo, params)
var self = this;
var embeddedList = this[propertyName] || [];
var hasErrors = false;
embeddedList.forEach(function(item) {
embeddedList.forEach(function(item, idx) {
if (item instanceof modelTo) {
if (!item.isValid()) {
hasErrors = true;
var id = item[idName] || '(blank)';
var id = item[idName];
var first = Object.keys(item.errors)[0];
var msg = 'contains invalid item: `' + id + '`';
if (id) {
var msg = 'contains invalid item: `' + id + '`';
} else {
var msg = 'contains invalid item at index `' + idx + '`';
}
msg += ' (`' + first + '` ' + item.errors[first] + ')';
self.errors.add(propertyName, msg, 'invalid');
}

View File

@ -2183,6 +2183,93 @@ describe('relations', function () {
});
describe('embedsMany - persisted model', function () {
var address0, address1, address2;
before(function (done) {
db = getSchema();
Person = db.define('Person', {name: String});
Address = db.define('Address', {street: String});
Address.validatesPresenceOf('street');
db.automigrate(function () {
Person.destroyAll(done);
});
});
it('can be declared', function (done) {
Person.embedsMany(Address);
db.automigrate(done);
});
it('should create individual items (0)', function(done) {
Address.create({ street: 'Street 0' }, function(err, inst) {
address0 = inst;
done();
});
});
it('should create individual items (1)', function(done) {
Address.create({ street: 'Street 1' }, function(err, inst) {
address1 = inst;
done();
});
});
it('should create individual items (2)', function(done) {
Address.create({ street: 'Street 2' }, function(err, inst) {
address2 = inst;
done();
});
});
it('should create embedded items on scope', function(done) {
Person.create({ name: 'Fred' }, function(err, p) {
p.addressList.create(address1.toObject(), function(err, address) {
should.not.exist(err);
address.id.should.eql(address1.id);
address1.street.should.equal('Street 1');
p.addressList.create(address2.toObject(), function(err, address) {
should.not.exist(err);
address.id.should.eql(address2.id);
address2.street.should.equal('Street 2');
done();
});
});
});
});
it('should validate embedded items on scope - id', function(done) {
Person.create({ name: 'Wilma' }, function(err, p) {
p.addressList.create({ id: null, street: 'Street 1' }, function(err, address) {
should.exist(err);
err.name.should.equal('ValidationError');
err.details.codes.addresses.should.eql(['invalid']);
var expected = 'The `Person` instance is not valid. ';
expected += 'Details: `addresses` contains invalid item at index `0`: `id` is blank.';
err.message.should.equal(expected);
done();
});
});
});
it('should validate embedded items on scope - street', function(done) {
Person.create({ name: 'Wilma' }, function(err, p) {
p.addressList.create({ id: 1234 }, function(err, address) {
should.exist(err);
err.name.should.equal('ValidationError');
err.details.codes.street.should.eql(['presence']);
var expected = 'The `Address` instance is not valid. ';
expected += 'Details: `street` can\'t be blank.';
err.message.should.equal(expected);
done();
});
});
});
});
describe('embedsMany - relations, scope and properties', function () {
var category, job1, job2, job3;