#node.js #typescript #sequelize.js #next.js
Вопрос:
У меня есть этот файл в проекте NextJS:
// ~/src/models/user/account.ts
import Joi, { ValidationError } from 'joi';
import Sequelize, { Model } from 'sequelize';
// other imports...
import database from '..';
export class UserAccount extends Model {
public id?: number;
public name = '';
public email = '';
public password = '';
public dateOfBirth?: Date;
public documentNumber = '';
public documentType: DocumentType = 'cpf';
public emailConfirmationToken = '';
public emailConfirmedAt?: Date;
public resetPasswordToken = '';
public passwordResetAt?: Date;
public readonly deletedAt?: Date;
public readonly createdAt?: Date;
public readonly updatedAt?: Date;
// some custom methods...
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
UserAccount.associate = (models) =>
UserAccount.hasMany(models.Launching, {
foreignKey: 'id',
as: 'launchings',
});
UserAccount.init(
{
name: { type: Sequelize.STRING, allowNull: false },
email: Sequelize.STRING,
// other fields...
},
{
sequelize: database,
tableName: 'user_accounts',
// other properties like scope...
},
);
export default UserAccount;
Затем Launching
модель, которая «ПРИНАДЛЕЖИТ» UserAccount
вышеперечисленному:
// ~/src/models/launching/launching.ts:
import Joi from 'joi';
import Sequelize, { Model } from 'sequelize';
import database from '..';
class Launching extends Model {
public id?: number;
public ownerId?: number;
public name = '';
public slug = '';
public duration = 0;
public startedAt = new Date();
public readonly deletedAt?: Date;
public readonly createdAt?: Date;
public readonly updatedAt?: Date;
}
Launching.init(
{
name: Sequelize.STRING,
slug: { type: Sequelize.STRING, unique: true, allowNull: false },
duration: Sequelize.INTEGER,
startedAt: Sequelize.DATE,
},
{
sequelize: database,
},
);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
Launching.associate = (models) =>
Launching.belongsTo(models.UserAccount, {
foreignKey: 'owner_id',
as: 'owner',
});
Это инициатор базы данных:
import Sequelize, { Options } from 'sequelize';
import databaseConfig from '../config/database';
import logger from '../common/logger';
import processModels from './processModels';
function Database() {
const connection = new Sequelize.Sequelize({
...(databaseConfig as Options),
logging: (sql, timing) =>
logger.info(
sql,
typeof timing === 'number' ? `Elapsed time: ${timing}ms` : '',
),
});
processModels(connection);
return connection;
}
const database = Database();
export default database;
My problem is that Sequelize can never «see» my associations. I declared the «associate» method and tried to call it via some «magic loop» reading files from the models directory — as some examples do in Javascript on the web (like here)
But the only result I see in the console is:
original: Error: Field 'owner_id' doesn't have a default value
at Packet.asError (~/project/node_modules/mysql2/lib/packets/packet.js:712:17)
at Execute.execute (~/project/node_modules/mysql2/lib/commands/command.js:28:26)
at Connection.handlePacket (~/project/node_modules/mysql2/lib/connection.js:425:32)
at PacketParser.onPacket (~/project/node_modules/mysql2/lib/connection.js:75:12)
at PacketParser.executeStart (~/project/node_modules/mysql2/lib/packet_parser.js:75:16)
at Socket.<anonymous> (~/project/node_modules/mysql2/lib/connection.js:82:25)
at Socket.emit (events.js:310:20)
at addChunk (_stream_readable.js:286:12)
at readableAddChunk (_stream_readable.js:268:9)
at Socket.Readable.push (_stream_readable.js:209:10)
at TCP.onStreamRead (internal/stream_base_commons.js:186:23) {
code: 'ER_NO_DEFAULT_FOR_FIELD',
errno: 1364,
sqlState: 'HY000',
sqlMessage: "Field 'owner_id' doesn't have a default value",
sql: 'INSERT INTO `launchings` (`id`,`name`,`slug`,`duration`,`started_at`,`created_at`,`updated_at`) VALUES (DEFAULT,?,?,?,?,?,?);',
parameters: [
'My Project',
'my-project',
35,
'2021-07-16 02:10:07',
'2021-07-16 02:10:07',
'2021-07-16 02:10:07'
]
},
sql: 'INSERT INTO `launchings` (`id`,`name`,`slug`,`duration`,`started_at`,`created_at`,`updated_at`) VALUES (DEFAULT,?,?,?,?,?,?);',
parameters: [
'My Project',
'my-project',
35,
'2021-07-16 02:10:07',
'2021-07-16 02:10:07',
'2021-07-16 02:10:07'
]
}
So, actually, my problems are:
- Is it possible to use TS and NextJS and Sequelize and its model relations methods? Because it looks like the models are never aware of its relationships.
- All the «solutions» I found googling were indicating to «use a different file to declare the relationships, where you can import all the Models and only then call the «hasMany», «belongsTo», methods in each one». It also doesn’t look like a good strategy. And wait: what file, exactly? Because an external file would need to be «imported» by some NextJS file, right? Since I’m not in a regular «NodeJs» application, I do not have an «entry point script file». And «_document.tsx» in NextJs doesn’t sound like a good solution here. Right?