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

Commit 2247a16f by Mick Hansen

fix(belongsToMany): otherKey should be inferred from paired foreignKey if undefined, fixes #2845

1 parent 0e5bbe88
......@@ -8,7 +8,13 @@ var Utils = require('./../utils')
, Model = require('../model')
, CounterCache = require('../plugins/counter-cache')
, util = require('util')
, HasManyDoubleLinked = require('./has-many-double-linked');
, HasManyDoubleLinked = require('./has-many-double-linked')
, deprecatedSeen = {}
, deprecated = function(message) {
if (deprecatedSeen[message]) return;
console.warn(message);
deprecatedSeen[message] = true;
};
module.exports = (function() {
var BelongsToMany = function(source, target, options) {
......@@ -36,10 +42,18 @@ module.exports = (function() {
this.through = true;
}
if (this.through) {
deprecated('belongsToMany: not defining through or defining through as true has been deprecated, please provide a string or a model');
}
if (Utils._.isObject(this.options.foreignKey)) {
this.foreignKeyAttribute = this.options.foreignKey;
this.foreignKey = this.foreignKeyAttribute.name || this.foreignKeyAttribute.fieldName;
} else {
if (!this.options.foreignKey) {
this.foreignKeyDefault = true;
}
this.foreignKeyAttribute = {};
this.foreignKey = this.options.foreignKey || Utils._.camelizeIf(
[
......@@ -54,6 +68,10 @@ module.exports = (function() {
this.otherKeyAttribute = this.options.otherKey;
this.otherKey = this.otherKeyAttribute.name || this.otherKeyAttribute.fieldName;
} else {
if (!this.options.otherKey) {
this.otherKeyDefault = true;
}
this.otherKeyAttribute = {};
this.otherKey = this.options.otherKey || Utils._.camelizeIf(
[
......@@ -104,6 +122,23 @@ module.exports = (function() {
this.through.model = this.combinedTableName;
}
/*
* Find paired association (if exists)
*/
_.each(this.target.associations, function(association, accessor) {
if (association.associationType !== 'BelongsToMany') return;
if (association.target !== this.source) return;
if (this.options.through.model === association.options.through.model) {
this.paired = association;
}
}, this);
if (this.paired) {
if (this.otherKeyDefault) this.otherKey = this.paired.foreignKey;
if (this.paired.otherKeyDefault) this.paired.otherKey = this.foreignKey;
}
if (typeof this.through.model === 'string') {
if (!this.sequelize.isDefined(this.through.model)) {
this.through.model = this.sequelize.define(this.through.model, {}, _.extend(this.options, {
......
......@@ -809,6 +809,35 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), function() {
expect(attributes.place_id).to.be.ok;
expect(attributes.user_id).to.be.ok;
});
it('should infer otherKey from paired BTM relationship with a through string defined', function () {
var User = this.sequelize.define('User', {});
var Place = this.sequelize.define('User', {});
var Places = User.belongsToMany(Place, { through: 'user_places', foreignKey: 'user_id' });
var Users = Place.belongsToMany(User, { through: 'user_places', foreignKey: 'place_id' });
expect(Places.foreignKey).to.equal('user_id');
expect(Users.foreignKey).to.equal('place_id');
expect(Places.otherKey).to.equal('place_id');
expect(Users.otherKey).to.equal('user_id');
});
it('should infer otherKey from paired BTM relationship with a through model defined', function () {
var User = this.sequelize.define('User', {});
var Place = this.sequelize.define('User', {});
var UserPlace = this.sequelize.define('UserPlace', {});
var Places = User.belongsToMany(Place, { through: UserPlace, foreignKey: 'user_id' });
var Users = Place.belongsToMany(User, { through: UserPlace, foreignKey: 'place_id' });
expect(Places.foreignKey).to.equal('user_id');
expect(Users.foreignKey).to.equal('place_id');
expect(Places.otherKey).to.equal('place_id');
expect(Users.otherKey).to.equal('user_id');
});
});
describe('foreign key with fields specified', function() {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!