Fix the hasMany through connection

This commit is contained in:
Raymond Feng 2014-06-16 00:36:12 -07:00
parent 1406c22a64
commit 34c1998f04
1 changed files with 36 additions and 19 deletions

View File

@ -203,14 +203,15 @@ util.inherits(HasOne, Relation);
* @param {*} foreignKey The foreign key * @param {*} foreignKey The foreign key
* @returns {Object} The relation object * @returns {Object} The relation object
*/ */
function findBelongsTo(model, foreignKey) { function findBelongsTo(modelFrom, modelTo, keyTo) {
var relations = model.relations; var relations = modelFrom.relations;
var keys = Object.keys(relations); var keys = Object.keys(relations);
for (var k = 0; k < keys.length; k++) { for (var k = 0; k < keys.length; k++) {
var rel = relations[keys[k]]; var rel = relations[keys[k]];
if (rel.type === RelationTypes.belongsTo && if (rel.type === RelationTypes.belongsTo &&
rel.keyFrom === foreignKey) { rel.modelTo === modelTo &&
return keys[k]; rel.keyTo === keyTo) {
return rel.keyFrom;
} }
} }
return null; return null;
@ -378,25 +379,30 @@ HasMany.prototype.destroyById = function (id, cb) {
// Create an instance of the target model and connect it to the instance of // Create an instance of the target model and connect it to the instance of
// the source model by creating an instance of the through model // the source model by creating an instance of the through model
HasManyThrough.prototype.create = function create(data, done) { HasManyThrough.prototype.create = function create(data, done) {
var modelTo = this.definition.modelTo; var definition = this.definition;
var modelThrough = this.definition.modelThrough; var modelTo = definition.modelTo;
var fk = this.definition.keyTo; var modelThrough = definition.modelThrough;
var fk2 = this.definition.keyThrough;
if (typeof data === 'function' && !done) { if (typeof data === 'function' && !done) {
done = data; done = data;
data = {}; data = {};
} }
var self = this.modelInstance; var modelInstance = this.modelInstance;
// First create the target model // First create the target model
modelTo.create(data, function (err, ac) { modelTo.create(data, function (err, ac) {
if (err) { if (err) {
return done && done(err, ac); return done && done(err, ac);
} }
// The primary key for the target model
var pk2 = modelTo.dataSource.idName(modelTo.modelName) || 'id';
var fk1 = findBelongsTo(modelThrough, definition.modelFrom,
definition.keyFrom);
var fk2 = findBelongsTo(modelThrough, definition.modelTo, pk2);
var d = {}; var d = {};
d[findBelongsTo(modelThrough, fk)] = self; d[fk1] = modelInstance[definition.keyFrom];
d[findBelongsTo(modelThrough, fk2)] = ac; d[fk2] = ac[pk2];
// Then create the through model // Then create the through model
modelThrough.create(d, function (e) { modelThrough.create(d, function (e) {
if (e) { if (e) {
@ -416,17 +422,28 @@ HasManyThrough.prototype.create = function create(data, done) {
* @param {Object|ID} acInst The actual instance or id value * @param {Object|ID} acInst The actual instance or id value
*/ */
HasManyThrough.prototype.add = function (acInst, done) { HasManyThrough.prototype.add = function (acInst, done) {
var modelThrough = this.definition.modelThrough; var definition = this.definition;
var fk = this.definition.keyTo; var modelThrough = definition.modelThrough;
var fk2 = this.definition.keyThrough; var modelTo = definition.modelTo;
var pk = this.definition.keyFrom; var pk1 = definition.keyFrom;
var data = {}; var data = {};
var query = {}; var query = {};
query[fk] = this[pk];
data[findBelongsTo(modelThrough, fk)] = this.modelInstance; var fk1 = findBelongsTo(modelThrough, definition.modelFrom,
query[fk2] = acInst[pk] || acInst; definition.keyFrom);
data[findBelongsTo(modelThrough, fk2)] = acInst;
// The primary key for the target model
var pk2 = modelTo.dataSource.idName(modelTo.modelName) || 'id';
var fk2 = findBelongsTo(modelThrough, definition.modelTo, pk2);
query[fk1] = this.modelInstance[pk1];
query[fk2] = acInst[pk2] || acInst;
data[fk1] = this.modelInstance[pk1];
data[fk2] = acInst[pk2] || acInst;
// Create an instance of the through model // Create an instance of the through model
modelThrough.findOrCreate({where: query}, data, done); modelThrough.findOrCreate({where: query}, data, done);
}; };