不要怂,就是干,撸起袖子干!

Commit 08fcb5ce by Mick Hansen

fix(belongs-to-many): properly pair association based on the through argument

The code would previously pair association based on the through.model argument of the original options.
However options.through.model would generally be undefined since users usually just pass through: Model and the normalization to through.model
actually happened on association.through rather than options.through.
Normalization now happens on the options set before being assigned to association.through
1 parent e368ce68
...@@ -36,11 +36,23 @@ var Utils = require('./../utils') ...@@ -36,11 +36,23 @@ var Utils = require('./../utils')
var BelongsToMany = function(source, target, options) { var BelongsToMany = function(source, target, options) {
Association.call(this); Association.call(this);
options = options || {};
if (options.through === undefined || options.through === true || options.through === null) {
throw new Error('belongsToMany must be given a through option, either a string or a model');
}
if (!options.through.model) {
options.through = {
model: options.through
};
}
this.associationType = 'BelongsToMany'; this.associationType = 'BelongsToMany';
this.source = source; this.source = source;
this.target = target; this.target = target;
this.targetAssociation = null; this.targetAssociation = null;
this.options = options || {}; this.options = options;
this.sequelize = source.modelManager.sequelize; this.sequelize = source.modelManager.sequelize;
this.through = options.through; this.through = options.through;
this.scope = options.scope; this.scope = options.scope;
...@@ -71,16 +83,6 @@ var BelongsToMany = function(source, target, options) { ...@@ -71,16 +83,6 @@ var BelongsToMany = function(source, target, options) {
this.isSelfAssociation ? (this.as || this.target.tableName) : this.target.tableName this.isSelfAssociation ? (this.as || this.target.tableName) : this.target.tableName
); );
if (this.through === undefined || this.through === true || this.through === null) {
throw new Error('belongsToMany must be given a through option, either a string or a model');
}
if (!this.through.model) {
this.through = {
model: this.through
};
}
/* /*
* If self association, this is the target association - Unless we find a pairing association * If self association, this is the target association - Unless we find a pairing association
*/ */
......
...@@ -11,7 +11,7 @@ var chai = require('chai') ...@@ -11,7 +11,7 @@ var chai = require('chai')
, Promise = current.Promise; , Promise = current.Promise;
describe(Support.getTestDialectTeaser('belongsToMany'), function() { describe(Support.getTestDialectTeaser('belongsToMany'), function() {
describe('optimizations using bulk create, destroy and update', function() { describe('optimizations using bulk create, destroy and update', function() {
var User = current.define('User', { username: DataTypes.STRING }) var User = current.define('User', { username: DataTypes.STRING })
, Task = current.define('Task', { title: DataTypes.STRING }) , Task = current.define('Task', { title: DataTypes.STRING })
, UserTasks = current.define('UserTasks', {}); , UserTasks = current.define('UserTasks', {});
...@@ -63,27 +63,47 @@ describe(Support.getTestDialectTeaser('belongsToMany'), function() { ...@@ -63,27 +63,47 @@ describe(Support.getTestDialectTeaser('belongsToMany'), function() {
expect(this.destroy).to.have.been.calledOnce; expect(this.destroy).to.have.been.calledOnce;
}); });
}); });
});
describe('belongsToMany', function () { describe('self-associations', function () {
it('works with singular and plural name for self-associations', function () { it('does not pair multiple self associations with different through arguments', function () {
// Models taken from https://github.com/sequelize/sequelize/issues/3796 var User = current.define('user', {})
var Service = current.define('service', {}) , UserFollowers = current.define('userFollowers', {})
, Instance = Service.Instance; , Invite = current.define('invite', {});
Service.belongsToMany(Service, {through: 'Supplements', as: 'supplements'}); User.Followers = User.belongsToMany(User, {
Service.belongsToMany(Service, {through: 'Supplements', as: {singular: 'supplemented', plural: 'supplemented'}}); through: UserFollowers
});
expect(Instance.prototype).to.have.property('getSupplements').which.is.a.function; User.Invites = User.belongsToMany(User, {
foreignKey: 'InviteeId',
through: Invite
});
expect(Instance.prototype).to.have.property('addSupplement').which.is.a.function; expect(User.Followers.paired).not.to.be.ok;
expect(Instance.prototype).to.have.property('addSupplements').which.is.a.function; expect(User.Invites.paired).not.to.be.ok;
expect(Instance.prototype).to.have.property('getSupplemented').which.is.a.function; expect(User.Followers.otherKey).not.to.equal(User.Invites.foreignKey);
expect(Instance.prototype).not.to.have.property('getSupplementeds').which.is.a.function; });
expect(Instance.prototype).to.have.property('addSupplemented').which.is.a.function; it('works with singular and plural name for self-associations', function () {
expect(Instance.prototype).not.to.have.property('addSupplementeds').which.is.a.function; // Models taken from https://github.com/sequelize/sequelize/issues/3796
}); var Service = current.define('service', {})
, Instance = Service.Instance;
Service.belongsToMany(Service, {through: 'Supplements', as: 'supplements'});
Service.belongsToMany(Service, {through: 'Supplements', as: {singular: 'supplemented', plural: 'supplemented'}});
expect(Instance.prototype).to.have.property('getSupplements').which.is.a.function;
expect(Instance.prototype).to.have.property('addSupplement').which.is.a.function;
expect(Instance.prototype).to.have.property('addSupplements').which.is.a.function;
expect(Instance.prototype).to.have.property('getSupplemented').which.is.a.function;
expect(Instance.prototype).not.to.have.property('getSupplementeds').which.is.a.function;
expect(Instance.prototype).to.have.property('addSupplemented').which.is.a.function;
expect(Instance.prototype).not.to.have.property('addSupplementeds').which.is.a.function;
}); });
}); });
}); });
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!