Introduce embedsMany persistent: true option
When set, instead of only embedding the model (on creation) it will be persisted first, and subsequently embedded.
This commit is contained in:
parent
ef816d490a
commit
95764232b9
|
@ -2199,24 +2199,34 @@ EmbedsMany.prototype.create = function (targetModelData, cb) {
|
||||||
|
|
||||||
var inst = this.build(targetModelData);
|
var inst = this.build(targetModelData);
|
||||||
|
|
||||||
var err = inst.isValid() ? null : new ValidationError(inst);
|
var updateEmbeddedList = function() {
|
||||||
|
modelInstance.updateAttribute(propertyName,
|
||||||
if (err) {
|
embeddedList, function(err, modelInst) {
|
||||||
return process.nextTick(function() {
|
cb(err, err ? null : inst);
|
||||||
cb(err);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
modelInstance.updateAttribute(propertyName,
|
if (this.definition.options.persistent) {
|
||||||
embeddedList, function(err, modelInst) {
|
inst.save(function(err) { // will validate
|
||||||
cb(err, err ? null : inst);
|
if (err) return cb(err, inst);
|
||||||
});
|
updateEmbeddedList();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
var err = inst.isValid() ? null : new ValidationError(inst);
|
||||||
|
if (err) {
|
||||||
|
return process.nextTick(function() {
|
||||||
|
cb(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
updateEmbeddedList();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
EmbedsMany.prototype.build = function(targetModelData) {
|
EmbedsMany.prototype.build = function(targetModelData) {
|
||||||
var modelTo = this.definition.modelTo;
|
var modelTo = this.definition.modelTo;
|
||||||
var modelInstance = this.modelInstance;
|
var modelInstance = this.modelInstance;
|
||||||
var forceId = this.definition.options.forceId;
|
var forceId = this.definition.options.forceId;
|
||||||
|
var persistent = this.definition.options.persistent;
|
||||||
var connector = modelTo.dataSource.connector;
|
var connector = modelTo.dataSource.connector;
|
||||||
|
|
||||||
var pk = this.definition.keyTo;
|
var pk = this.definition.keyTo;
|
||||||
|
@ -2228,6 +2238,7 @@ EmbedsMany.prototype.build = function(targetModelData) {
|
||||||
targetModelData = targetModelData || {};
|
targetModelData = targetModelData || {};
|
||||||
|
|
||||||
var assignId = (forceId || targetModelData[pk] === undefined);
|
var assignId = (forceId || targetModelData[pk] === undefined);
|
||||||
|
assignId = assignId && !persistent;
|
||||||
|
|
||||||
if (assignId && pkType === Number) {
|
if (assignId && pkType === Number) {
|
||||||
var ids = embeddedList.map(function(m) {
|
var ids = embeddedList.map(function(m) {
|
||||||
|
|
|
@ -13,6 +13,10 @@ var getTransientDataSource = function(settings) {
|
||||||
return new DataSource('transient', settings, db.modelBuilder);
|
return new DataSource('transient', settings, db.modelBuilder);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var getMemoryDataSource = function(settings) {
|
||||||
|
return new DataSource('memory', settings, db.modelBuilder);
|
||||||
|
};
|
||||||
|
|
||||||
describe('relations', function () {
|
describe('relations', function () {
|
||||||
|
|
||||||
describe('hasMany', function () {
|
describe('hasMany', function () {
|
||||||
|
@ -2188,8 +2192,12 @@ describe('relations', function () {
|
||||||
var address0, address1, address2;
|
var address0, address1, address2;
|
||||||
var person;
|
var person;
|
||||||
|
|
||||||
|
// This test spefically uses the Memory connector
|
||||||
|
// in order to test the use of the auto-generated
|
||||||
|
// id, in the sequence of the related model.
|
||||||
|
|
||||||
before(function (done) {
|
before(function (done) {
|
||||||
db = getSchema();
|
db = getMemoryDataSource();
|
||||||
Person = db.define('Person', {name: String});
|
Person = db.define('Person', {name: String});
|
||||||
Address = db.define('Address', {street: String});
|
Address = db.define('Address', {street: String});
|
||||||
Address.validatesPresenceOf('street');
|
Address.validatesPresenceOf('street');
|
||||||
|
@ -2200,12 +2208,18 @@ describe('relations', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be declared', function (done) {
|
it('can be declared', function (done) {
|
||||||
Person.embedsMany(Address, {scope: {order: 'street'}});
|
// to save related model itself, set
|
||||||
|
// persistent: true
|
||||||
|
Person.embedsMany(Address, {
|
||||||
|
scope: {order: 'street'},
|
||||||
|
options: {persistent: true}
|
||||||
|
});
|
||||||
db.automigrate(done);
|
db.automigrate(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create individual items (0)', function(done) {
|
it('should create individual items (0)', function(done) {
|
||||||
Address.create({ street: 'Street 0' }, function(err, inst) {
|
Address.create({ street: 'Street 0' }, function(err, inst) {
|
||||||
|
inst.id.should.equal(1); // offset sequence
|
||||||
address0 = inst;
|
address0 = inst;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
@ -2213,6 +2227,7 @@ describe('relations', function () {
|
||||||
|
|
||||||
it('should create individual items (1)', function(done) {
|
it('should create individual items (1)', function(done) {
|
||||||
Address.create({ street: 'Street 1' }, function(err, inst) {
|
Address.create({ street: 'Street 1' }, function(err, inst) {
|
||||||
|
inst.id.should.equal(2);
|
||||||
address1 = inst;
|
address1 = inst;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
@ -2220,21 +2235,29 @@ describe('relations', function () {
|
||||||
|
|
||||||
it('should create individual items (2)', function(done) {
|
it('should create individual items (2)', function(done) {
|
||||||
Address.create({ street: 'Street 2' }, function(err, inst) {
|
Address.create({ street: 'Street 2' }, function(err, inst) {
|
||||||
|
inst.id.should.equal(3);
|
||||||
address2 = inst;
|
address2 = inst;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should create individual items (3)', function(done) {
|
||||||
|
Address.create({ street: 'Street 3' }, function(err, inst) {
|
||||||
|
inst.id.should.equal(4); // offset sequence
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should add embedded items on scope', function(done) {
|
it('should add embedded items on scope', function(done) {
|
||||||
Person.create({ name: 'Fred' }, function(err, p) {
|
Person.create({ name: 'Fred' }, function(err, p) {
|
||||||
person = p;
|
person = p;
|
||||||
p.addressList.create(address1.toObject(), function(err, address) {
|
p.addressList.create(address1.toObject(), function(err, address) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
address.id.should.eql(address1.id);
|
address.id.should.eql(2);
|
||||||
address.street.should.equal('Street 1');
|
address.street.should.equal('Street 1');
|
||||||
p.addressList.create(address2.toObject(), function(err, address) {
|
p.addressList.create(address2.toObject(), function(err, address) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
address.id.should.eql(address2.id);
|
address.id.should.eql(3);
|
||||||
address.street.should.equal('Street 2');
|
address.street.should.equal('Street 2');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
@ -2244,10 +2267,10 @@ describe('relations', function () {
|
||||||
|
|
||||||
it('should create embedded items on scope', function(done) {
|
it('should create embedded items on scope', function(done) {
|
||||||
Person.findById(person.id, function(err, p) {
|
Person.findById(person.id, function(err, p) {
|
||||||
p.addressList.create({ street: 'Street 3' }, function(err, address) {
|
p.addressList.create({ street: 'Street 4' }, function(err, address) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
address.should.have.property('id'); // not within Address seq!
|
address.id.should.equal(5); // in Address sequence, correct offset
|
||||||
address.street.should.equal('Street 3');
|
address.street.should.equal('Street 4');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -2260,7 +2283,7 @@ describe('relations', function () {
|
||||||
addresses.should.have.length(3);
|
addresses.should.have.length(3);
|
||||||
addresses[0].street.should.equal('Street 1');
|
addresses[0].street.should.equal('Street 1');
|
||||||
addresses[1].street.should.equal('Street 2');
|
addresses[1].street.should.equal('Street 2');
|
||||||
addresses[2].street.should.equal('Street 3');
|
addresses[2].street.should.equal('Street 4');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -2269,12 +2292,8 @@ describe('relations', function () {
|
||||||
it('should validate embedded items on scope - id', function(done) {
|
it('should validate embedded items on scope - id', function(done) {
|
||||||
Person.create({ name: 'Wilma' }, function(err, p) {
|
Person.create({ name: 'Wilma' }, function(err, p) {
|
||||||
p.addressList.create({ id: null, street: 'Street 1' }, function(err, address) {
|
p.addressList.create({ id: null, street: 'Street 1' }, function(err, address) {
|
||||||
should.exist(err);
|
should.not.exist(err);
|
||||||
err.name.should.equal('ValidationError');
|
address.street.should.equal('Street 1');
|
||||||
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();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue