Merge pull request #286 from fabien/fix/polymorphic-transient
getTransientDataSource helper + embedsMany/polymorphic test case fix
This commit is contained in:
commit
5c7a9aee3a
|
@ -391,13 +391,13 @@ util.inherits(HasOne, Relation);
|
|||
* EmbedsOne subclass
|
||||
* @param {RelationDefinition|Object} definition
|
||||
* @param {Object} modelInstance
|
||||
* @returns {EmbedsMany}
|
||||
* @returns {EmbedsOne}
|
||||
* @constructor
|
||||
* @class EmbedsOne
|
||||
*/
|
||||
function EmbedsOne(definition, modelInstance) {
|
||||
if (!(this instanceof EmbedsOne)) {
|
||||
return new EmbedsMany(definition, modelInstance);
|
||||
return new EmbedsOne(definition, modelInstance);
|
||||
}
|
||||
assert(definition.type === RelationTypes.embedsOne);
|
||||
Relation.apply(this, arguments);
|
||||
|
@ -503,9 +503,9 @@ function lookupModelTo(modelFrom, modelTo, params, singularize) {
|
|||
* @param {Object|String} params Name of the polymorphic relation or params
|
||||
* @returns {Object} The normalized parameters
|
||||
*/
|
||||
function polymorphicParams(params) {
|
||||
function polymorphicParams(params, as) {
|
||||
if (typeof params === 'string') params = { as: params };
|
||||
if (typeof params.as !== 'string') params.as = 'reference'; // default
|
||||
if (typeof params.as !== 'string') params.as = as || 'reference'; // default
|
||||
params.foreignKey = params.foreignKey || i8n.camelize(params.as + '_id', true);
|
||||
params.discriminator = params.discriminator || i8n.camelize(params.as + '_type', true);
|
||||
return params;
|
||||
|
@ -1079,21 +1079,23 @@ RelationDefinition.belongsTo = function (modelFrom, modelTo, params) {
|
|||
|
||||
var idName, relationName, fk;
|
||||
if (params.polymorphic) {
|
||||
relationName = params.as || (typeof modelTo === 'string' ? modelTo : null); // initially
|
||||
|
||||
if (params.polymorphic === true) {
|
||||
// modelTo arg will be the name of the polymorphic relation (string)
|
||||
polymorphic = polymorphicParams(modelTo);
|
||||
polymorphic = polymorphicParams(modelTo, relationName);
|
||||
} else {
|
||||
polymorphic = polymorphicParams(params.polymorphic);
|
||||
polymorphic = polymorphicParams(params.polymorphic, relationName);
|
||||
}
|
||||
|
||||
modelTo = null; // will lookup dynamically
|
||||
|
||||
idName = params.idName || 'id';
|
||||
relationName = params.as || polymorphic.as;
|
||||
relationName = params.as || polymorphic.as; // finally
|
||||
fk = polymorphic.foreignKey;
|
||||
discriminator = polymorphic.discriminator;
|
||||
|
||||
if (typeof polymorphic.idType === 'string') { // explicit key type
|
||||
if (polymorphic.idType) { // explicit key type
|
||||
modelFrom.dataSource.defineProperty(modelFrom.modelName, fk, { type: polymorphic.idType, index: true });
|
||||
} else { // try to use the same foreign key type as modelFrom
|
||||
modelFrom.dataSource.defineForeignKey(modelFrom.modelName, fk, modelFrom.modelName);
|
||||
|
@ -2208,10 +2210,7 @@ EmbedsMany.prototype.build = function(targetModelData) {
|
|||
|
||||
var assignId = (forceId || targetModelData[pk] === undefined);
|
||||
|
||||
if (assignId && typeof connector.generateId === 'function') {
|
||||
var id = connector.generateId(modelTo.modelName, targetModelData, pk);
|
||||
targetModelData[pk] = id;
|
||||
} else if (assignId && pkType === Number) {
|
||||
if (assignId && pkType === Number) {
|
||||
var ids = embeddedList.map(function(m) {
|
||||
return (typeof m[pk] === 'number' ? m[pk] : 0);
|
||||
});
|
||||
|
@ -2220,6 +2219,9 @@ EmbedsMany.prototype.build = function(targetModelData) {
|
|||
} else {
|
||||
targetModelData[pk] = 1;
|
||||
}
|
||||
} else if (assignId && typeof connector.generateId === 'function') {
|
||||
var id = connector.generateId(modelTo.modelName, targetModelData, pk);
|
||||
targetModelData[pk] = id;
|
||||
}
|
||||
|
||||
this.definition.applyProperties(modelInstance, targetModelData);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// This test written in mocha+should.js
|
||||
var should = require('./init.js');
|
||||
var jdb = require('../');
|
||||
var DataSource = jdb.DataSource;
|
||||
|
||||
var db, tmp, Book, Chapter, Author, Reader;
|
||||
var Category, Job;
|
||||
|
@ -7,6 +9,10 @@ var Picture, PictureLink;
|
|||
var Person, Address;
|
||||
var Link;
|
||||
|
||||
var getTransientDataSource = function(settings) {
|
||||
return new DataSource('transient', settings, db.modelBuilder);
|
||||
};
|
||||
|
||||
describe('relations', function () {
|
||||
|
||||
describe('hasMany', function () {
|
||||
|
@ -1679,7 +1685,7 @@ describe('relations', function () {
|
|||
var Other;
|
||||
|
||||
before(function () {
|
||||
tmp = getSchema('transient');
|
||||
tmp = getTransientDataSource();
|
||||
db = getSchema();
|
||||
Person = db.define('Person', {name: String});
|
||||
Passport = tmp.define('Passport',
|
||||
|
@ -1828,7 +1834,7 @@ describe('relations', function () {
|
|||
var address1, address2;
|
||||
|
||||
before(function (done) {
|
||||
tmp = getSchema('transient', {defaultIdType: Number});
|
||||
tmp = getTransientDataSource({defaultIdType: Number});
|
||||
db = getSchema();
|
||||
Person = db.define('Person', {name: String});
|
||||
Address = tmp.define('Address', {street: String});
|
||||
|
@ -2008,7 +2014,7 @@ describe('relations', function () {
|
|||
|
||||
describe('embedsMany - explicit ids', function () {
|
||||
before(function (done) {
|
||||
tmp = getSchema('transient');
|
||||
tmp = getTransientDataSource();
|
||||
db = getSchema();
|
||||
Person = db.define('Person', {name: String});
|
||||
Address = tmp.define('Address', {street: String});
|
||||
|
@ -2415,11 +2421,16 @@ describe('relations', function () {
|
|||
|
||||
before(function (done) {
|
||||
db = getSchema();
|
||||
tmp = getTransientDataSource();
|
||||
|
||||
Book = db.define('Book', {name: String});
|
||||
Author = db.define('Author', {name: String});
|
||||
Reader = db.define('Reader', {name: String});
|
||||
|
||||
Link = db.define('Link', {name: String, notes: String}); // generic model
|
||||
Link = tmp.define('Link', {
|
||||
id: {type: Number, id: true},
|
||||
name: String, notes: String
|
||||
}); // generic model
|
||||
Link.validatesPresenceOf('linkedId');
|
||||
Link.validatesPresenceOf('linkedType');
|
||||
|
||||
|
@ -2433,13 +2444,15 @@ describe('relations', function () {
|
|||
});
|
||||
|
||||
it('can be declared', function (done) {
|
||||
var idType = db.connector.getDefaultIdType();
|
||||
|
||||
Book.embedsMany(Link, { as: 'people',
|
||||
polymorphic: 'linked',
|
||||
scope: { include: 'linked' }
|
||||
});
|
||||
Link.belongsTo('linked', {
|
||||
polymorphic: true, // needs unique auto-id
|
||||
properties: { name: 'name' }, // denormalized
|
||||
polymorphic: { idType: idType }, // native type
|
||||
properties: { name: 'name' }, // denormalized
|
||||
options: { invertProperties: true }
|
||||
});
|
||||
db.automigrate(done);
|
||||
|
|
|
@ -6,10 +6,14 @@ var should = require('./init.js');
|
|||
|
||||
var db, TransientModel, Person, Widget, Item;
|
||||
|
||||
var getTransientDataSource = function(settings) {
|
||||
return new DataSource('transient', settings);
|
||||
};
|
||||
|
||||
describe('Transient connector', function () {
|
||||
|
||||
before(function () {
|
||||
db = getSchema('transient');
|
||||
db = getTransientDataSource();
|
||||
TransientModel = db.define('TransientModel', {}, { idInjection: false });
|
||||
|
||||
Person = TransientModel.extend('Person', {name: String});
|
||||
|
|
Loading…
Reference in New Issue