Been trying to get my Many to Many association to work, but unable to do so. I looked at the example code, but it's not working for me.
// user.model.ts
import { Table, Model, Column, BelongsToMany } from 'sequelize-typescript';
import { Room, UserRoom } from './index';
@Table
class User extends Model<User> {
@PrimaryKey
@AutoIncrement
@Column
id: number;
@Column
spotify_id: number;
@BelongsToMany(() => Room, () => UserRoom)
rooms: Room[];
}
export default User;
// room.model.ts
import { Table, Model, Column, BelongsToMany } from 'sequelize-typescript';
import { User, UserRoom } from './index';
@Table
class Room extends Model<Room> {
@PrimaryKey
@AutoIncrement
@Column
id: number;
@Column
name: string;
@Column
image: string;
@BelongsToMany(() => User, () => UserRoom)
users: User[];
}
export default Room;
// user_room.model.ts
import { Table, Model, Column, ForeignKey, PrimaryKey } from 'sequelize-typescript';
import { Room, User } from './index';
@Table
class UserRoom extends Model<UserRoom> {
@ForeignKey(() => User)
@PrimaryKey
@Column
user_id: number;
@ForeignKey(() => Room)
@PrimaryKey
@Column
room_id: number;
}
export default UserRoom;
This results in the following error:
[...]/node_modules/sequelize-typescript/lib/models/association/BaseAssociation.js:55
throw new Error("Foreign key for \"" + relatedClass.name + "\" is missing " +
^
Error: Foreign key for "Room" is missing on "User_Room".
Is there something I'm missing? It's basically a 1-1 copy of the example code.
Restarting the development server seemed to have fixed it somehow.
My next problem is querying though. I want to get all rooms from a user with his id.
My query:
const rooms = await models.UserRoom
.findAll<models.UserRoom>({
include: [models.Room],
where: {
userId: id,
},
});
The error:
SequelizeEagerLoadingError: Room is not associated to UserRoom!
Why isn't it associated? I don't get what I'm missing.
Hey @sandervspl, this is because the association exists between User and Room, not UserRoom and User or Room. So you either need to define an additional relation (one-to-many between UserRoom and Room) if you want to retrieve the data like you did or you implement it like:
const rooms = await models.Room
.findAll({
include: [{
model: models.User,
where: {id}
}],
});
@sandervspl Is this still an issue for you or can this be closed?
Close this issue due to inactivity
Hi @RobinBuschmann, I have a same issue:
My code:
//role.model.ts
@Table
export default class Role extends Model<Role> {
@PrimaryKey
@AutoIncrement
@Column(DataType.INTEGER)
id: number;
@Column(DataType.TEXT)
name: string;
@BelongsToMany(() => Permission, () => PermissionRole)
permissions: Permission[];
@HasMany(() => User)
users: User[];
}
//permission.model.ts
@Table
export default class Permission extends Model<Permission> {
@PrimaryKey
@AutoIncrement
@Column(DataType.INTEGER)
id: number;
@Column(DataType.TEXT)
name: string;
@Column(DataType.TEXT)
method: string;
@BelongsToMany(() => Role, () => PermissionRole)
roles: Role[];
}
//permission-role.model.ts
@Table
export default class PermissionRole extends Model<PermissionRole> {
@ForeignKey(() => Permission)
@PrimaryKey
@Column
permission_id: number;
@BelongsTo(() => Permission)
permission: Permission;
@ForeignKey(() => Role)
@PrimaryKey
@Column
role_id: string;
@BelongsTo(() => Role)
role: Role;
}
This results in the following error:
Error: Foreign key for "Role" is missing on "Permission".
Hi @RobinBuschmann, I have a same issue:
My code:
//role.model.ts @Table export default class Role extends Model<Role> { @PrimaryKey @AutoIncrement @Column(DataType.INTEGER) id: number; @Column(DataType.TEXT) name: string; @BelongsToMany(() => Permission, () => PermissionRole) permissions: Permission[]; @HasMany(() => User) users: User[]; }//permission.model.ts @Table export default class Permission extends Model<Permission> { @PrimaryKey @AutoIncrement @Column(DataType.INTEGER) id: number; @Column(DataType.TEXT) name: string; @Column(DataType.TEXT) method: string; @BelongsToMany(() => Role, () => PermissionRole) roles: Role[]; }//permission-role.model.ts @Table export default class PermissionRole extends Model<PermissionRole> { @ForeignKey(() => Permission) @PrimaryKey @Column permission_id: number; @BelongsTo(() => Permission) permission: Permission; @ForeignKey(() => Role) @PrimaryKey @Column role_id: string; @BelongsTo(() => Role) role: Role; }This results in the following error:
Error: Foreign key for "Role" is missing on "Permission".
I did fix this issue setting manually the foreign key and other key on BelongsToMany annotation:
//role.model.ts
Table
export default class Role extends Model<Role> {
@PrimaryKey
@AutoIncrement
@Column(DataType.INTEGER)
id: number;
@Column(DataType.TEXT)
name: string;
@BelongsToMany(() => Permission, () => PermissionRole, "permission_id", "role_id")
permissions: Permission[];
@HasMany(() => User)
users: User[];
}
I just had the same issue. @albinojunior 's solution solved it for me though.
Perhaps this should be in the docs since the example is incomplete and results in this error?
I am experiencing different problem with many-to-many:
@BelongsToMany(() => Role, () => UserRole) roles: Role[];
The error is
(node:41692) UnhandledPromiseRejectionWarning: TypeError: Cannot read property
'prototype' of undefined
at Sequelize.model (...\node_modules\sequelize-typescript\dist\sequelize\
sequelize\sequelize.js:25:61)
Via poor man's debugger (i.e. console) I get
BelongsToManyAssociation {
associatedClassGetter: [Function],
options:
{ foreignKey: undefined,
otherKey: undefined,
through: [Function],
as: 'roles' } }
and the through function is returning undefined.
Can anybody help?
Thanks, Karel
For anyone running into this issue, the problem was with "smart" import of all models from one file
import User from "./user.model";
import Role from "./role.model";
import UserRole from "./userRole.model";
export { Role, User, UserRole };
and importing them as import { Role, UserRole } from "./index"; which resulted in Role and UserRole being undefined. Changing that to import Role from './role.model' fixed the problem.
I guess, I have to study JavaScript exports more ... (the problem was in importing completely different file through paths style import and not using the path).
Try this article, it may help you
https://medium.com/@eth3rnit3/sequelize-relationships-ultimate-guide-f26801a75554
Most helpful comment
I did fix this issue setting manually the foreign key and other key on BelongsToMany annotation: