From 1487a592c13afb0e4b239fafe89cb388ab6413b0 Mon Sep 17 00:00:00 2001 From: Fabien Franzen Date: Sun, 27 Jul 2014 16:54:01 +0200 Subject: [PATCH] Added validation for embedded items (optional) --- lib/relation-definition.js | 23 +++++++++++++++++++++++ test/relations.test.js | 15 ++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/lib/relation-definition.js b/lib/relation-definition.js index 6062a7c8..3d795bcf 100644 --- a/lib/relation-definition.js +++ b/lib/relation-definition.js @@ -1422,6 +1422,29 @@ RelationDefinition.embedsMany = function hasMany(modelFrom, modelTo, params) { }, { code: 'uniqueness' }) } + // validate all embedded items + if (definition.options.validate) { + modelFrom.validate(relationName, function(err) { + var embeddedList = this[relationName] || []; + var hasErrors = false; + embeddedList.forEach(function(item) { + if (item instanceof modelTo) { + if (!item.isValid()) { + hasErrors = true; + var first = Object.keys(item.errors)[0]; + var msg = 'contains invalid item: `' + item[idName] + '`'; + msg += ' (' + first + ' ' + item.errors[first] + ')'; + this.errors.add(relationName, msg, 'invalid'); + } + } else { + hasErrors = true; + this.errors.add(relationName, 'Contains invalid item', 'invalid'); + } + }.bind(this)); + if (hasErrors) err(false); + }); + } + var scopeMethods = { findById: scopeMethod(definition, 'findById'), destroy: scopeMethod(definition, 'destroyById'), diff --git a/test/relations.test.js b/test/relations.test.js index a455b41a..5140dfbb 100644 --- a/test/relations.test.js +++ b/test/relations.test.js @@ -1380,7 +1380,7 @@ describe('relations', function () { }); it('can be declared', function (done) { - Person.embedsMany(Address, { options: { autoId: false } }); + Person.embedsMany(Address, { options: { autoId: false, validate: true } }); db.automigrate(done); }); @@ -1451,6 +1451,19 @@ describe('relations', function () { }); }); + it('should validate all embedded items', function(done) { + var addresses = []; + addresses.push({ id: 'home', street: 'Home Street' }); + addresses.push({ id: 'work', street: '' }); + Person.create({ name: 'Wilma', addresses: addresses }, function(err, p) { + err.name.should.equal('ValidationError'); + var expected = 'The `Person` instance is not valid. '; + expected += 'Details: `addresses` contains invalid item: `work` (street can\'t be blank).'; + err.message.should.equal(expected); + done(); + }); + }); + }); });