Как сказано в документах :
Когда определяется связь между двумя моделями, экземпляры этих моделей получают специальные методы для взаимодействия со связанными с ними аналогами .
Вы пытаетесь вызвать эти специальные методы в классе Model. Вот рабочий пример:
import { sequelize } from '../../db';
import { Model, DataTypes, BelongsToManyGetAssociationsMixin, BelongsToManyCountAssociationsMixin } from 'sequelize';
class User extends Model {}
User.init(
{
firstName: DataTypes.STRING,
},
{ sequelize, modelName: 'User' },
);
class Week extends Model {
public getUsers!: BelongsToManyGetAssociationsMixin<User>;
public countUsers!: BelongsToManyCountAssociationsMixin;
}
Week.init(
{
date: {
type: DataTypes.DATE,
allowNull: false,
unique: true,
},
},
{ sequelize, modelName: 'Week' },
);
class Roster extends Model {}
Roster.init(
{
weekId: {
type: DataTypes.INTEGER,
allowNull: false,
unique: false,
},
userId: {
type: DataTypes.INTEGER,
allowNull: true,
unique: false,
},
},
{ sequelize, modelName: 'Roster' },
);
User.belongsToMany(Week, { through: Roster, foreignKey: { name: 'weekId' } });
Week.belongsToMany(User, { through: Roster, foreignKey: { name: 'userId', allowNull: true } });
(async function test() {
try {
// create tables
await sequelize.sync({ force: true });
// seed
const week = await Week.create(
{
date: new Date(),
Users: [
{ firstName: 'james' },
{ firstName: 'elsa' },
{ firstName: 'tim' },
{ firstName: 'lee' },
{ firstName: 'jasmine' },
],
},
{ include: [User] },
);
// test
const count = await week.countUsers();
console.log('count:', count);
const users = await week.getUsers();
console.log('users count:', users.length);
} catch (error) {
console.log(error);
} finally {
await sequelize.close();
}
})();
Результаты выполнения:
Executing (default): DROP TABLE IF EXISTS "Roster" CASCADE;
Executing (default): DROP TABLE IF EXISTS "Week" CASCADE;
Executing (default): DROP TABLE IF EXISTS "User" CASCADE;
Executing (default): DROP TABLE IF EXISTS "User" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "User" ("id" SERIAL , "firstName" VARCHAR(255), PRIMARY KEY ("id"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'User' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): DROP TABLE IF EXISTS "Week" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "Week" ("id" SERIAL , "date" TIMESTAMP WITH TIME ZONE NOT NULL UNIQUE, PRIMARY KEY ("id"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'Week' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): DROP TABLE IF EXISTS "Roster" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "Roster" ("weekId" INTEGER NOT NULL REFERENCES "User" ("id") ON DELETE CASCADE ON UPDATE CASCADE, "userId" INTEGER REFERENCES "Week" ("id") ON DELETE CASCADE ON UPDATE CASCADE, UNIQUE ("weekId", "userId"), PRIMARY KEY ("weekId","userId"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'Roster' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): INSERT INTO "Week" ("id","date") VALUES (DEFAULT,$1) RETURNING *;
Executing (default): INSERT INTO "User" ("id","firstName") VALUES (DEFAULT,$1) RETURNING *;
Executing (default): INSERT INTO "User" ("id","firstName") VALUES (DEFAULT,$1) RETURNING *;
Executing (default): INSERT INTO "User" ("id","firstName") VALUES (DEFAULT,$1) RETURNING *;
Executing (default): INSERT INTO "User" ("id","firstName") VALUES (DEFAULT,$1) RETURNING *;
Executing (default): INSERT INTO "User" ("id","firstName") VALUES (DEFAULT,$1) RETURNING *;
Executing (default): INSERT INTO "Roster" ("weekId","userId") VALUES ($1,$2) RETURNING *;
Executing (default): INSERT INTO "Roster" ("weekId","userId") VALUES ($1,$2) RETURNING *;
Executing (default): INSERT INTO "Roster" ("weekId","userId") VALUES ($1,$2) RETURNING *;
Executing (default): INSERT INTO "Roster" ("weekId","userId") VALUES ($1,$2) RETURNING *;
Executing (default): INSERT INTO "Roster" ("weekId","userId") VALUES ($1,$2) RETURNING *;
Executing (default): SELECT COUNT("User"."id") AS "count" FROM "User" AS "User" INNER JOIN "Roster" AS "Roster" ON "User"."id" = "Roster"."weekId" AND "Roster"."userId" = 1;
count: 5
Executing (default): SELECT "User"."id", "User"."firstName", "Roster"."weekId" AS "Roster.weekId", "Roster"."userId" AS "Roster.userId" FROM "User" AS "User" INNER JOIN "Roster" AS "Roster" ON "User"."id" = "Roster"."weekId" AND "Roster"."userId" = 1;
users count: 5
проверка базы данных:
node-sequelize-examples=# select * from "User";
id | firstName
----+-----------
1 | james
2 | elsa
3 | tim
4 | lee
5 | jasmine
(5 rows)
node-sequelize-examples=# select * from "Week";
id | date
----+---------------------------
1 | 2020-04-14 01:56:56.55+00
(1 row)
node-sequelize-examples=# select * from "Roster";
weekId | userId
--------+--------
1 | 1
2 | 1
3 | 1
4 | 1
5 | 1
(5 rows)
Версии зависимостей: "sequelize": "^5.21.3"
, postgres:9.6
исходный код: https://github.com/mrdulin/node-sequelize-examples/tree/master/src/examples/stackoverflow/60805725