sequelize-typescript icon indicating copy to clipboard operation
sequelize-typescript copied to clipboard

"Foreign key is missing" error when {constraints: false}

Open KiNgLerArter opened this issue 3 years ago • 2 comments

Issue

Polymorphic associations are not working

Versions

  • sequelize: ^7.0.0-alpha.2
  • sequelize-typescript: ^2.1.1
  • typescript: ^4.2.3

Issue type

  • [x] bug report
  • [ ] feature request

Actual behavior

"Foreign key is missing" error when {constraints: false} is being set for each association

Expected behavior

No errors, foreign key is not needed

Steps to reproduce

Try to reproduce simple belongsToMany polymorphic relation

Related code

users table

@Table({ tableName: 'users' })
export class User extends Model<User, UserCreationAttrs> {
  ...some fields...

  @BelongsToMany(() => ChatDialog, {
    through: {
      model: () => UsersChats,
      unique: false,
    },
    foreignKey: 'userId',
    constraints: false,
  })
  chatDialogs: ChatDialog[];

  @BelongsToMany(() => ChatGroup, {
    through: {
      model: () => UsersChats,
      unique: false,
    },
    foreignKey: 'userId',
    constraints: false,
  })
  chatGroups: ChatGroup[];
}

chat_dialogs table

@Table({ tableName: 'chat_dialogs' })
export class ChatDialog extends Model<ChatDialog, ChatDialogCreationAttrs> {
  @Column({
    type: DataType.INTEGER,
    unique: true,
    autoIncrement: true,
    primaryKey: true,
  })
  id: number;

  @Column({
    type: DataType.STRING,
  })
  name: string;

  @BelongsToMany(() => User, {
    through: {
      model: () => UsersChats,
      unique: false,
      scope: { chatType: 'dialog' },
    },
    foreignKey: 'chatId',
    constraints: false,
  })
  users: User[];
}

chat_groups table

@Table({ tableName: 'chat_groups' })
export class ChatGroup extends Model<ChatGroup, ChatGroupCreationAttrs> {
  @Column({
    type: DataType.INTEGER,
    unique: true,
    autoIncrement: true,
    primaryKey: true,
  })
  id: number;

  @Column({
    type: DataType.STRING,
  })
  name: string;

  @BelongsToMany(() => User, {
    through: {
      model: () => UsersChats,
      unique: false,
      scope: { chatType: 'group' },
    },
    foreignKey: 'chatId',
    constraints: false,
  })
  users: User[];
}

users_chats table

@Table({ tableName: 'users_chats', createdAt: false, updatedAt: false })
export class UsersChats extends Model<UsersChats> {
  @Column({
    type: DataType.INTEGER,
    unique: true,
    autoIncrement: true,
    primaryKey: true,
  })
  id: number;

  @ForeignKey(() => User)
  @Column({
    type: DataType.INTEGER,
  })
  userId: number;

  @Column({
    type: DataType.INTEGER,
    unique: 'id_type',
    references: null,
  })
  chatId: number;

  @Column({
    type: DataType.STRING,
    unique: 'id_type',
  })
  chatType: string;
}

ERROR

image

KiNgLerArter avatar Jan 09 '22 15:01 KiNgLerArter

Specify otherKey prop on BelongsToMany assoc. You should only need the chatId one since that one is not marked on through model.

@Table({ tableName: 'users' })
export class User extends Model<User, UserCreationAttrs> {
  ...some fields...

  @BelongsToMany(() => ChatDialog, {
    through: {
      model: () => UsersChats,
      unique: false,
    },
    foreignKey: 'userId',
    otherKey: 'chatId', <--- THIS one
    constraints: false,
  })
  chatDialogs: ChatDialog[];

  @BelongsToMany(() => ChatGroup, {
    through: {
      model: () => UsersChats,
      unique: false,
    },
    foreignKey: 'userId',
    otherKey: 'chatId', <--- and THIS one
    constraints: false,
  })
  chatGroups: ChatGroup[];
}

lukashroch avatar Apr 04 '22 12:04 lukashroch

Any updates on this, facing the same issue?

rodgetech avatar Feb 19 '24 00:02 rodgetech