@@ -110,43 +110,6 @@ class BelongsToMany extends Association {
110110 this . targetAssociation = this ;
111111 }
112112
113- /*
114- * Default/generated foreign/other keys
115- */
116- if ( _ . isObject ( this . options . foreignKey ) ) {
117- this . foreignKeyAttribute = this . options . foreignKey ;
118- this . foreignKey = this . foreignKeyAttribute . name || this . foreignKeyAttribute . fieldName ;
119- } else {
120- if ( ! this . options . foreignKey ) {
121- this . foreignKeyDefault = true ;
122- }
123-
124- this . foreignKeyAttribute = { } ;
125- this . foreignKey = this . options . foreignKey || Utils . camelize (
126- [
127- this . source . options . name . singular ,
128- this . source . primaryKeyAttribute
129- ] . join ( '_' )
130- ) ;
131- }
132-
133- if ( _ . isObject ( this . options . otherKey ) ) {
134- this . otherKeyAttribute = this . options . otherKey ;
135- this . otherKey = this . otherKeyAttribute . name || this . otherKeyAttribute . fieldName ;
136- } else {
137- if ( ! this . options . otherKey ) {
138- this . otherKeyDefault = true ;
139- }
140-
141- this . otherKeyAttribute = { } ;
142- this . otherKey = this . options . otherKey || Utils . camelize (
143- [
144- this . isSelfAssociation ? Utils . singularize ( this . as ) : this . target . options . name . singular ,
145- this . target . primaryKeyAttribute
146- ] . join ( '_' )
147- ) ;
148- }
149-
150113 /*
151114 * Find paired association (if exists)
152115 */
@@ -160,6 +123,23 @@ class BelongsToMany extends Association {
160123 }
161124 } ) ;
162125
126+ /*
127+ * Default/generated source/target keys
128+ */
129+ this . sourceKey = this . options . sourceKey || this . source . primaryKeyAttribute ;
130+ this . sourceKeyField = this . source . rawAttributes [ this . sourceKey ] . field || this . sourceKey ;
131+
132+ if ( this . options . targetKey ) {
133+ this . targetKey = this . options . targetKey ;
134+ this . targetKeyField = this . target . rawAttributes [ this . targetKey ] . field || this . targetKey ;
135+ } else {
136+ this . targetKeyDefault = true ;
137+ this . targetKey = this . target . primaryKeyAttribute ;
138+ this . targetKeyField = this . target . rawAttributes [ this . targetKey ] . field || this . targetKey ;
139+ }
140+
141+ this . _createForeignAndOtherKeys ( ) ;
142+
163143 if ( typeof this . through . model === 'string' ) {
164144 if ( ! this . sequelize . isDefined ( this . through . model ) ) {
165145 this . through . model = this . sequelize . define ( this . through . model , { } , Object . assign ( this . options , {
@@ -178,6 +158,25 @@ class BelongsToMany extends Association {
178158 ] ) ) ;
179159
180160 if ( this . paired ) {
161+ let needInjectPaired = false ;
162+
163+ if ( this . targetKeyDefault ) {
164+ this . targetKey = this . paired . sourceKey ;
165+ this . targetKeyField = this . paired . sourceKeyField ;
166+ this . _createForeignAndOtherKeys ( ) ;
167+ }
168+ if ( this . paired . targetKeyDefault ) {
169+ // in this case paired.otherKey depends on paired.targetKey,
170+ // so cleanup previously wrong generated otherKey
171+ if ( this . paired . targetKey !== this . sourceKey ) {
172+ delete this . through . model . rawAttributes [ this . paired . otherKey ] ;
173+ this . paired . targetKey = this . sourceKey ;
174+ this . paired . targetKeyField = this . sourceKeyField ;
175+ this . paired . _createForeignAndOtherKeys ( ) ;
176+ needInjectPaired = true ;
177+ }
178+ }
179+
181180 if ( this . otherKeyDefault ) {
182181 this . otherKey = this . paired . foreignKey ;
183182 }
@@ -187,9 +186,13 @@ class BelongsToMany extends Association {
187186 if ( this . paired . otherKey !== this . foreignKey ) {
188187 delete this . through . model . rawAttributes [ this . paired . otherKey ] ;
189188 this . paired . otherKey = this . foreignKey ;
190- this . paired . _injectAttributes ( ) ;
189+ needInjectPaired = true ;
191190 }
192191 }
192+
193+ if ( needInjectPaired ) {
194+ this . paired . _injectAttributes ( ) ;
195+ }
193196 }
194197
195198 if ( this . through ) {
@@ -218,6 +221,41 @@ class BelongsToMany extends Association {
218221 } ;
219222 }
220223
224+ _createForeignAndOtherKeys ( ) {
225+ /*
226+ * Default/generated foreign/other keys
227+ */
228+ if ( _ . isObject ( this . options . foreignKey ) ) {
229+ this . foreignKeyAttribute = this . options . foreignKey ;
230+ this . foreignKey = this . foreignKeyAttribute . name || this . foreignKeyAttribute . fieldName ;
231+ } else {
232+ this . foreignKeyAttribute = { } ;
233+ this . foreignKey = this . options . foreignKey || Utils . camelize (
234+ [
235+ this . source . options . name . singular ,
236+ this . sourceKey
237+ ] . join ( '_' )
238+ ) ;
239+ }
240+
241+ if ( _ . isObject ( this . options . otherKey ) ) {
242+ this . otherKeyAttribute = this . options . otherKey ;
243+ this . otherKey = this . otherKeyAttribute . name || this . otherKeyAttribute . fieldName ;
244+ } else {
245+ if ( ! this . options . otherKey ) {
246+ this . otherKeyDefault = true ;
247+ }
248+
249+ this . otherKeyAttribute = { } ;
250+ this . otherKey = this . options . otherKey || Utils . camelize (
251+ [
252+ this . isSelfAssociation ? Utils . singularize ( this . as ) : this . target . options . name . singular ,
253+ this . targetKey
254+ ] . join ( '_' )
255+ ) ;
256+ }
257+ }
258+
221259 // the id is in the target table
222260 // or in an extra table which connects two tables
223261 _injectAttributes ( ) {
@@ -240,12 +278,12 @@ class BelongsToMany extends Association {
240278 }
241279 } ) ;
242280
243- const sourceKey = this . source . rawAttributes [ this . source . primaryKeyAttribute ] ;
281+ const sourceKey = this . source . rawAttributes [ this . sourceKey ] ;
244282 const sourceKeyType = sourceKey . type ;
245- const sourceKeyField = sourceKey . field || this . source . primaryKeyAttribute ;
246- const targetKey = this . target . rawAttributes [ this . target . primaryKeyAttribute ] ;
283+ const sourceKeyField = this . sourceKeyField ;
284+ const targetKey = this . target . rawAttributes [ this . targetKey ] ;
247285 const targetKeyType = targetKey . type ;
248- const targetKeyField = targetKey . field || this . target . primaryKeyAttribute ;
286+ const targetKeyField = this . targetKeyField ;
249287 const sourceAttribute = _ . defaults ( { } , this . foreignKeyAttribute , { type : sourceKeyType } ) ;
250288 const targetAttribute = _ . defaults ( { } , this . otherKeyAttribute , { type : targetKeyType } ) ;
251289
@@ -393,7 +431,7 @@ class BelongsToMany extends Association {
393431
394432 if ( Object ( through . model ) === through . model ) {
395433 throughWhere = { } ;
396- throughWhere [ this . foreignKey ] = instance . get ( this . source . primaryKeyAttribute ) ;
434+ throughWhere [ this . foreignKey ] = instance . get ( this . sourceKey ) ;
397435
398436 if ( through . scope ) {
399437 Object . assign ( throughWhere , through . scope ) ;
@@ -442,12 +480,11 @@ class BelongsToMany extends Association {
442480 * @returns {Promise<number> }
443481 */
444482 count ( instance , options ) {
445- const model = this . target ;
446- const sequelize = model . sequelize ;
483+ const sequelize = this . target . sequelize ;
447484
448485 options = Utils . cloneDeep ( options ) ;
449486 options . attributes = [
450- [ sequelize . fn ( 'COUNT' , sequelize . col ( [ this . target . name , model . primaryKeyField ] . join ( '.' ) ) ) , 'count' ]
487+ [ sequelize . fn ( 'COUNT' , sequelize . col ( [ this . target . name , this . targetKeyField ] . join ( '.' ) ) ) , 'count' ]
451488 ] ;
452489 options . joinTableAttributes = [ ] ;
453490 options . raw = true ;
@@ -474,7 +511,7 @@ class BelongsToMany extends Association {
474511 raw : true
475512 } , options , {
476513 scope : false ,
477- attributes : [ this . target . primaryKeyAttribute ] ,
514+ attributes : [ this . targetKey ] ,
478515 joinTableAttributes : [ ]
479516 } ) ;
480517
@@ -483,7 +520,7 @@ class BelongsToMany extends Association {
483520 return instance . where ( ) ;
484521 }
485522 return {
486- [ this . target . primaryKeyAttribute ] : instance
523+ [ this . targetKey ] : instance
487524 } ;
488525 } ) ;
489526
@@ -495,7 +532,7 @@ class BelongsToMany extends Association {
495532 } ;
496533
497534 return this . get ( sourceInstance , options ) . then ( associatedObjects =>
498- _ . differenceBy ( instancePrimaryKeys , associatedObjects , this . target . primaryKeyAttribute ) . length === 0
535+ _ . differenceBy ( instancePrimaryKeys , associatedObjects , this . targetKey ) . length === 0
499536 ) ;
500537 }
501538
@@ -514,8 +551,8 @@ class BelongsToMany extends Association {
514551 set ( sourceInstance , newAssociatedObjects , options ) {
515552 options = options || { } ;
516553
517- const sourceKey = this . source . primaryKeyAttribute ;
518- const targetKey = this . target . primaryKeyAttribute ;
554+ const sourceKey = this . sourceKey ;
555+ const targetKey = this . targetKey ;
519556 const identifier = this . identifier ;
520557 const foreignIdentifier = this . foreignIdentifier ;
521558 let where = { } ;
@@ -626,8 +663,8 @@ class BelongsToMany extends Association {
626663 options = _ . clone ( options ) || { } ;
627664
628665 const association = this ;
629- const sourceKey = association . source . primaryKeyAttribute ;
630- const targetKey = association . target . primaryKeyAttribute ;
666+ const sourceKey = association . sourceKey ;
667+ const targetKey = association . targetKey ;
631668 const identifier = association . identifier ;
632669 const foreignIdentifier = association . foreignIdentifier ;
633670 const defaultAttributes = options . through || { } ;
@@ -721,8 +758,8 @@ class BelongsToMany extends Association {
721758 oldAssociatedObjects = association . toInstanceArray ( oldAssociatedObjects ) ;
722759
723760 const where = {
724- [ association . identifier ] : sourceInstance . get ( association . source . primaryKeyAttribute ) ,
725- [ association . foreignIdentifier ] : oldAssociatedObjects . map ( newInstance => newInstance . get ( association . target . primaryKeyAttribute ) )
761+ [ association . identifier ] : sourceInstance . get ( association . sourceKey ) ,
762+ [ association . foreignIdentifier ] : oldAssociatedObjects . map ( newInstance => newInstance . get ( association . targetKey ) )
726763 } ;
727764
728765 return association . through . model . destroy ( _ . defaults ( { where } , options ) ) ;
0 commit comments