Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add information on extra attributes on join table in N:M relati… #494

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
53 changes: 53 additions & 0 deletions docs/associations/belongs-to-many.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,59 @@ class Toot extends Model<InferAttributes<Toot>, InferCreationAttributes<Toot>> {
In TypeScript, you need to declare the typing of your foreign keys, but they will still be configured by Sequelize automatically.
You can still, of course, use any [attribute decorator](../models/defining-models.mdx) to customize them.

### Associations with extra attributes on through table

When creating an N:M association, for example, with User and Project through UserProjects you might want extra attributes on the junction table like the "role" attribute.
This relationship can be setup like this:

```ts
class UserProject extends Model<InferAttributes<UserProject>, InferCreationAttributes<UserProject>> {
@Attribute(DataTypes.STRING)
declare role: string;

declare projectId: number;
declare userId: number;
}

class Project extends Model<InferAttributes<Project>, InferCreationAttributes<Project>> {
@Attribute(DataTypes.STRING)
declare name: string;

declare UserProject?: NonAttribute<UserProject>;
}

class User extends Model<InferAttributes<User>, InferCreationAttributes<User>> {
@Attribute(DataTypes.STRING)
declare username: string;

@BelongsToMany(() => Project, {
through: UserProject,
})
declare projects?: NonAttribute<Project[]>;

declare getProjects: BelongsToManyGetAssociationsMixin<Project>;
declare setProjects: BelongsToManySetAssociationsMixin<Project, number>;
declare addProjects: BelongsToManyAddAssociationsMixin<Project, number>;
}
```

Creating multiple associations with the same extra attributes is possible by passing a single object on the through attribute:
```ts
user1.setProjects([project1, project2, project3], { through: { role: 'admin' }})
```

With the [set](#association-setter-setx) and [add](#association-adder-addx) mixins different extra attributes per association can be set by passing an array of objects of the same length as the ammount of associations:
```ts
user1.setProjects([project1, project2, project3], {
through: [
{ role: 'admin' },
{ role: 'manager' },
{ role: 'designer' },
]
})
(await user1.getProducts()).map(x => x.UserProduct?.role) // [ 'admin', 'manager', 'designer' ]
```

## Inverse Association

The `BelongsToMany` association automatically creates the inverse association on the target model, which is also a `BelongsToMany` association.
Expand Down