Clarified tests, fixed BelongsTo.prototype.create
Added clarified test-case based on previous documentation example. Fixed BelongsTo.prototype.create - although the foreignKey was set on the model instance, it was never actually persisted, unless you'd issue a separate call to save the 'parent' model.
This commit is contained in:
parent
d7900a8a21
commit
78e2c9c9d4
|
@ -181,16 +181,20 @@ RelationDefinition.prototype.applyScope = function(modelInstance, filter) {
|
||||||
* @param {Object} modelInstance
|
* @param {Object} modelInstance
|
||||||
* @param {Object} target
|
* @param {Object} target
|
||||||
*/
|
*/
|
||||||
RelationDefinition.prototype.applyProperties = function(modelInstance, target) {
|
RelationDefinition.prototype.applyProperties = function(modelInstance, obj) {
|
||||||
|
var source = modelInstance, target = obj;
|
||||||
|
if (this.options.invertProperties) {
|
||||||
|
source = obj, target = modelInstance;
|
||||||
|
}
|
||||||
if (typeof this.properties === 'function') {
|
if (typeof this.properties === 'function') {
|
||||||
var data = this.properties.call(this, modelInstance);
|
var data = this.properties.call(this, source);
|
||||||
for(var k in data) {
|
for(var k in data) {
|
||||||
target[k] = data[k];
|
target[k] = data[k];
|
||||||
}
|
}
|
||||||
} else if (typeof this.properties === 'object') {
|
} else if (typeof this.properties === 'object') {
|
||||||
for(var k in this.properties) {
|
for(var k in this.properties) {
|
||||||
var key = this.properties[k];
|
var key = this.properties[k];
|
||||||
target[key] = modelInstance[k];
|
target[key] = source[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((this.type !== 'belongsTo' || this.type === 'hasOne')
|
if ((this.type !== 'belongsTo' || this.type === 'hasOne')
|
||||||
|
@ -1082,14 +1086,17 @@ BelongsTo.prototype.create = function(targetModelData, cb) {
|
||||||
cb = targetModelData;
|
cb = targetModelData;
|
||||||
targetModelData = {};
|
targetModelData = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
this.definition.applyProperties(modelInstance, targetModelData || {});
|
this.definition.applyProperties(modelInstance, targetModelData || {});
|
||||||
|
|
||||||
modelTo.create(targetModelData, function(err, targetModel) {
|
modelTo.create(targetModelData, function(err, targetModel) {
|
||||||
if(!err) {
|
if(!err) {
|
||||||
modelInstance[fk] = targetModel[pk];
|
modelInstance[fk] = targetModel[pk];
|
||||||
self.resetCache(targetModel);
|
modelInstance.save(function(err, inst) {
|
||||||
cb && cb(err, targetModel);
|
if (cb && err) return cb && cb(err);
|
||||||
|
self.resetCache(targetModel);
|
||||||
|
cb && cb(err, targetModel);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
cb && cb(err);
|
cb && cb(err);
|
||||||
}
|
}
|
||||||
|
@ -1138,9 +1145,7 @@ BelongsTo.prototype.related = function (refresh, params) {
|
||||||
modelInstance[fk] = params[pk];
|
modelInstance[fk] = params[pk];
|
||||||
if (discriminator) modelInstance[discriminator] = params.constructor.modelName;
|
if (discriminator) modelInstance[discriminator] = params.constructor.modelName;
|
||||||
|
|
||||||
var data = {};
|
this.definition.applyProperties(modelInstance, params);
|
||||||
this.definition.applyProperties(params, data);
|
|
||||||
modelInstance.setAttributes(data);
|
|
||||||
|
|
||||||
self.resetCache(params);
|
self.resetCache(params);
|
||||||
} else if (typeof params === 'function') { // acts as async getter
|
} else if (typeof params === 'function') { // acts as async getter
|
||||||
|
@ -1652,7 +1657,7 @@ EmbedsMany.prototype.related = function(receiver, scopeParams, condOrRefresh, cb
|
||||||
|
|
||||||
var params = mergeQuery(actualCond, scopeParams);
|
var params = mergeQuery(actualCond, scopeParams);
|
||||||
|
|
||||||
if (params.where) {
|
if (params.where) { // TODO [fabien] Support order/sorting
|
||||||
embeddedList = embeddedList ? embeddedList.filter(applyFilter(params)) : embeddedList;
|
embeddedList = embeddedList ? embeddedList.filter(applyFilter(params)) : embeddedList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1109,11 +1109,9 @@ describe('relations', function () {
|
||||||
p.person.create({name: 'Fred', age: 36 }, function(err, person) {
|
p.person.create({name: 'Fred', age: 36 }, function(err, person) {
|
||||||
personCreated = person;
|
personCreated = person;
|
||||||
p.personId.should.equal(person.id);
|
p.personId.should.equal(person.id);
|
||||||
p.save(function (err, p) {
|
person.name.should.equal('Fred');
|
||||||
person.name.should.equal('Fred');
|
person.passportNotes.should.equal('Some notes...');
|
||||||
person.passportNotes.should.equal('Some notes...');
|
done();
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1191,7 +1189,6 @@ describe('relations', function () {
|
||||||
Article.create(function (e, article) {
|
Article.create(function (e, article) {
|
||||||
article.tags.create({name: 'popular'}, function (e, t) {
|
article.tags.create({name: 'popular'}, function (e, t) {
|
||||||
t.should.be.an.instanceOf(Tag);
|
t.should.be.an.instanceOf(Tag);
|
||||||
// console.log(t);
|
|
||||||
ArticleTag.findOne(function (e, at) {
|
ArticleTag.findOne(function (e, at) {
|
||||||
should.exist(at);
|
should.exist(at);
|
||||||
at.tagId.toString().should.equal(t.id.toString());
|
at.tagId.toString().should.equal(t.id.toString());
|
||||||
|
@ -1566,19 +1563,15 @@ describe('relations', function () {
|
||||||
|
|
||||||
describe('embedsMany - relations, scope and properties', function () {
|
describe('embedsMany - relations, scope and properties', function () {
|
||||||
|
|
||||||
var product1, product2, product3;
|
var category, product1, product2, product3;
|
||||||
|
|
||||||
before(function (done) {
|
before(function () {
|
||||||
db = getSchema();
|
db = getSchema();
|
||||||
Category = db.define('Category', {name: String});
|
Category = db.define('Category', {name: String});
|
||||||
Product = db.define('Product', {name: String});
|
Product = db.define('Product', {name: String});
|
||||||
Link = db.define('Link', {name: String});
|
Link = db.define('Link', {name: String});
|
||||||
|
|
||||||
db.automigrate(function () {
|
|
||||||
Person.destroyAll(done);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be declared', function (done) {
|
it('can be declared', function (done) {
|
||||||
Category.embedsMany(Link, {
|
Category.embedsMany(Link, {
|
||||||
as: 'items', // rename
|
as: 'items', // rename
|
||||||
|
@ -1588,6 +1581,7 @@ describe('relations', function () {
|
||||||
Link.belongsTo(Product, {
|
Link.belongsTo(Product, {
|
||||||
foreignKey: 'id', // re-use the actual product id
|
foreignKey: 'id', // re-use the actual product id
|
||||||
properties: { id: 'id', name: 'name' }, // denormalize, transfer id
|
properties: { id: 'id', name: 'name' }, // denormalize, transfer id
|
||||||
|
options: { invertProperties: true }
|
||||||
});
|
});
|
||||||
db.automigrate(function() {
|
db.automigrate(function() {
|
||||||
Product.create({ name: 'Product 0' }, done); // offset ids for tests
|
Product.create({ name: 'Product 0' }, done); // offset ids for tests
|
||||||
|
@ -1607,7 +1601,7 @@ describe('relations', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create items on scope', function(done) {
|
it('should associate items on scope', function(done) {
|
||||||
Category.create({ name: 'Category A' }, function(err, cat) {
|
Category.create({ name: 'Category A' }, function(err, cat) {
|
||||||
var link = cat.items.build();
|
var link = cat.items.build();
|
||||||
link.product(product1);
|
link.product(product1);
|
||||||
|
@ -1718,13 +1712,47 @@ describe('relations', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should remove embedded items by reference id', function(done) {
|
it('should have removed embedded items by reference id', function(done) {
|
||||||
Category.findOne(function(err, cat) {
|
Category.findOne(function(err, cat) {
|
||||||
cat.links.should.have.length(1);
|
cat.links.should.have.length(1);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should create items on scope', function(done) {
|
||||||
|
Category.create({ name: 'Category B' }, function(err, cat) {
|
||||||
|
category = cat;
|
||||||
|
var link = cat.items.build({ notes: 'Some notes...' });
|
||||||
|
link.product.create({ name: 'Product 1' }, function(err, p) {
|
||||||
|
cat.save(function(err, cat) { // save parent object!
|
||||||
|
cat.links[0].id.should.eql(p.id);
|
||||||
|
cat.links[0].name.should.equal('Product 1'); // denormalized
|
||||||
|
cat.links[0].notes.should.equal('Some notes...');
|
||||||
|
cat.items.at(0).should.equal(cat.links[0]);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should find items on scope', function(done) {
|
||||||
|
Category.findById(category.id, function(err, cat) {
|
||||||
|
cat.name.should.equal('Category B');
|
||||||
|
cat.links.toObject().should.eql([
|
||||||
|
{id: 5, name: 'Product 1', notes: 'Some notes...'}
|
||||||
|
]);
|
||||||
|
cat.items.at(0).should.equal(cat.links[0]);
|
||||||
|
cat.items(function(err, items) { // alternative access
|
||||||
|
items.should.be.an.array;
|
||||||
|
items.should.have.length(1);
|
||||||
|
items[0].product(function(err, p) {
|
||||||
|
p.name.should.equal('Product 1'); // actual value
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('embedsMany - polymorphic relations', function () {
|
describe('embedsMany - polymorphic relations', function () {
|
||||||
|
@ -1757,7 +1785,8 @@ describe('relations', function () {
|
||||||
});
|
});
|
||||||
Link.belongsTo('linked', {
|
Link.belongsTo('linked', {
|
||||||
polymorphic: true, // needs unique auto-id
|
polymorphic: true, // needs unique auto-id
|
||||||
properties: { name: 'name' } // denormalized
|
properties: { name: 'name' }, // denormalized
|
||||||
|
options: { invertProperties: true }
|
||||||
});
|
});
|
||||||
db.automigrate(done);
|
db.automigrate(done);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue