Tips for properly starting n:m relationships in Sequelize

Within my Express application, I am attempting to establish a many-to-many association between two models: User and Game, using the intermediary model GamePlayer. Following guidance from the Sequelize Docs, I utilized the .belongsToMany() method on both User and Game. Unfortunately, upon implementing this association, my application encounters the error message:

GameScore.belongsTo called with something that's not a subclass of Sequelize.Model
. The scenario also involves a GameScore model linked to Game, where each Game corresponds to one GameScore. Despite experimenting with adding a references object in the GameScore model and mixing in .hasMany() within GamePlayer along with .belongsTo(GamePlayer) statements in both User and Game, the issue persists. Removal of the association resolves the crashing problem, leaving me puzzled as to whether I'm misunderstanding the process at hand or overlooking crucial details. Any insights offered would be immensely appreciated!

The Sequelize version currently employed is 6.3.3.

Beneath lies pertinent code snippets from all interconnected models (imports and interface declarations omitted):

User Model

export default class User extends Model { /* ... solely variable declarations */ }

User.init({
    id: {
        type: DataTypes.UUID,
        defaultValue: DataTypes.UUIDV4,
        primaryKey: true,
    },
    username: {
        type: DataTypes.STRING(50),
        allowNull: false,
    },
    email: {
        type: DataTypes.STRING(255),
        allowNull: false,
    },
    password: {
        type: DataTypes.STRING(255),
        allowNull: false,
    },
    deleted: {
        type: DataTypes.BOOLEAN,
        allowNull: false,
        defaultValue: false,
    },
}, {
    tableName: 'users',
    sequelize: db,
    underscored: true,
});

User.belongsToMany(Game, {
    through: GamePlayer,
});

Game Model

export default class Game extends Model { /* ... solely variable declarations */ }

Game.init({
    id: {
        type: DataTypes.UUID,
        defaultValue: DataTypes.UUIDV4,
        primaryKey: true,
    },
    deleted: {
        type: DataTypes.BOOLEAN,
        allowNull: false,
        defaultValue: false,
    },
}, {
    tableName: 'games',
    sequelize: db,
    underscored: true,
});

Game.hasOne(GameScore);

Game.belongsToMany(User, {
    through: GamePlayer,
});

GamePlayer Model

export default class GamePlayer extends Model { /* ... solely variable declarations */ }

GamePlayer.init({
    gameId: {
        type: DataTypes.UUID,
        references: {
            model: Game,
            key: 'id',
        }
    },
    userId: {
        type: DataTypes.UUID,
        references: {
            model: User,
            key: 'id',
        }
    },
    team: {
        type: DataTypes.TINYINT({ 
            length: 1, 
            unsigned: true,
        }),
        allowNull: false,
    },
    win: {
        type: DataTypes.BOOLEAN,
        allowNull: false,
    },
}, {
    tableName: 'game_players',
    sequelize: db,
    underscored: true,
});

GameScore Model

export default class GameScore extends Model { /* ... solely variable declarations */ }

GameScore.init({
    gameId: {
        type: DataTypes.UUID,
        allowNull: false,
    },
    scoreTeam1: {
        type: DataTypes.TINYINT({
            length: 1,
            unsigned: true,
        }),
        allowNull: false,
    },
    scoreTeam2: {
        type: DataTypes.TINYINT({
            length: 1,
            unsigned: true,
        }),
        allowNull: false,
    },
}, {
    tableName: 'game_scores',
    sequelize: db,
    underscored: true,
});

GameScore.belongsTo(Game, {
    foreignKey: 'gameId',
});

Answer №1

Mansur's insightful comment steered me towards the solution. Make sure to show your appreciation by upvoting his answer here: Sequelize: throw new Error(`${this.name}.belongsToMany called with something that's not a subclass of Sequelize.Model

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Unlocking the Power of Asynchronous Data in Angular's Dynamic Form Patterns

Utilizing the dynamic form pattern in Angular has been incredibly helpful for our team. By defining our controls in ngOnInit, the form is dynamically constructed based on our needs. However, we've encountered a challenge with forms that require initia ...

Testing AG Grid's TypeScript in-line cell editing using Jest

I am currently working on writing Jest tests to evaluate the functionality of my ag-grid table. So far, I have created tests to check the default data in the grid and to test a button that adds an additional row of data to the grid. I am now attempting t ...

Exploring Angular 5's *ngFor directive with an array of objects

Here is the data I am working with: Initial set of data: var input = [ {ru: "R201", area: "211", unit: "211"}, {ru: "R201", area: "212", unit: "NONE"}, {ru: "R201", area: "HCC", unit: "NONE"}]; Desired result data: var result = [ {area: ...

callbacks in amazon-cognito-identity-js

When working with amazon-cognito-identity-js, I encountered an issue with the callback function. This is what it currently looks like: cognitoUser?.getUserAttributes((err, results) => { if (err) { console.log(err.message || JSON.stringify(err)); ...

The feature to disable legend click in Chart.js does not activate unless the specific condition is met

I am working with chartjs and have encountered a scenario where I need to disable actions when a legend item is clicked, but only under certain conditions. I was able to accomplish this using the following code snippet: legend: { position: 'right& ...

A custom Typescript type for immutable values within an object

I am struggling with finding the right data type for my function, where I need to work with static types. I have experimented with Type, interface, class, Record, and others, but none seem to fit perfectly. GEOLOCATIONS is a constant record that maps cou ...

Issue with destructuring in function parameter in TSLint code analysis

I'm trying to resolve the tslint error that occurs in the object destructuring parameter of this code snippet: export function renameProperty( oldProp: string, newProp: string, {[oldProp]: old, ...others} ): any { return { [ne ...

Tips for effectively utilizing ng-multiselect-dropdown without the need for [(ngModel)]

Using the ng-multiselect-dropdown in Angular 14, I encountered an issue when trying to use singleSelection without initial data (without [(ngModel)]) to display a placeholder. Here is my code snippet: <ng-multiselect-dropdown [placeholder]="&a ...

Keep an eye out for any instances of new files being created in nodemon js or npm

Is there a way to monitor only for new file creation events using nodemon js, npm, or any other packages? For instance, in a project, whenever a new file is created, a specific script needs to be executed to carry out additional tasks for a one-time setup. ...

Using Firebase Database, Angular2 employs UID (User ID) as the primary key

Creating a signup component in my app using Firebase as the authentication method and database. After registering a new user, a key is generated and all user information, including the UID from authentication, is saved in the database. I want to use the UI ...

What is the way to imitate a variable with Jasmine Spy?

Trying to troubleshoot a login feature, how can I mock everything except string variables? @Component({ selector: 'app-login', templateUrl: './login.component.html', styleUrls: ['./login.component.scss']) export c ...

Alternatives to using wildcards in TypeScript

In my code, I have defined an interface called ColumnDef which consists of two methods: getValue that returns type C and getComponent which takes an input argument of type C. Everything is functioning properly as intended. interface ColumnDef<R, C> { ...

Managing File Validation with Yup and React Hook Form

Currently, I'm working on a form that includes an input field of type file. My goal is to make this particular field required. const { register, handleSubmit } = useForm({ defaultValues, resolver: yupResolver(schema), }); <form onSubmit={handl ...

What is the best approach to re-establish a websocket connection in TypeScript?

Encountering an issue when trying to add a "retry()" method: ERROR in src/app/films.service.ts(28,20): error TS2339: Property 'retry' does not exist on type 'WebSocketSubject'. this.wsSubject.retry().subscribe( (msg) => this. ...

Potential absence of value in Typescript object

interface c { state?: {b: string} } const x: c = { state: {b: 'c'}} console.log(x.state.b) The code snippet above shows an interface called c with an optional property called state. Although the property b of the state object is accessed i ...

When validation fails, all fields are highlighted in the Div containing the FormGroup

In my Angular application, I need to utilize two fields - produced date and expiry date. It is important to note that I must use <div [formGroup]...> since this component will be called within other forms. Using the form tag here is not an option. ...

Tips for creating a string extension in TypeScript

Adding a custom method to a string in TypeScript can be achieved like so: const myPoint : string = "23"; const customNumber = myPoint.convertUsingMyCustomImplementation(); Attempting to define the method with a capital 'S' results in the followi ...

Removing query parameters in Angular when clicking the back button

I am in need of a way to verify if my income URL follows a specific format and then open a modal to perform an action. I have achieved this using the following code: route.queryParams.subscribe(async params => { if (!isNaN(params.rt)) { c ...

Associations in Typescript Sequelize

There are two simple models in a 1:N relationship - one student has many tasks. // StudentModel.ts interface StudentI extends Model<InferAttributes<StudentI>, InferCreationAttributes<StudentI>> { id: CreationOptional<number> ...

Exploring the concept of class type definition in Typescript can lead to an

To achieve overloading of a class definition in TypeScript, you can set up the constructor to accept either a value for a certain property or no value at all. When instantiated with a value passed to the constructor, the property is typed based on the prov ...