Reputation: 43
I'm pretty new to JS and Sequelize and I'm now facing problems when querying the following structure. Maybe I am totally missing some basic point here. Help is much appreciated.
Versions:
await Flight.findOne({
where: { id: flightId },
include: [
{
model: User,
as: "user",
attributes: ["id", "name"],
},
{
model: FlightComment,
as: "comments",
},
],
});
I will get the Error
SequelizeEagerLoadingError: User is not associated to Flight!
which is understandable. So I tried to add the reverse association to the Flight.
Flight.belongsTo(User)
After that I will get the error
Flight.belongsTo called with something that's not a subclass of Sequelize.Model
When I define a userId column in the FlightComment like:
userId: {
type: DataTypes.UUID,
references: {
model: User,
key: "id",
},
},
I will get the following error during database synchrinisation
Executing (default): DROP TABLE IF EXISTS "FlightComments" CASCADE;
TypeError: Cannot read property 'replace' of undefined
I read that you need to define all models in one file, but because of the many numbers of different models I want to keep things apart.
I didn't find any advise in the offical documentaion either.
For every model I've created a own file (there will be alot of different models, so better keep things apart).
File for Flight:
const Flight = db.sequelize.define("Flight", {
//Many beautiful attributes
});
Flight.hasMany(FlightComment, {
as: "comments",
foreignKey: {
name: "flightId",
allowNull: false,
},
onDelete: "CASCADE",
hooks: true,
});
//Another association
module.exports = Flight;
File for FlightComment:
const FlightComment = db.sequelize.define("FlightComment", {
id: {
type: Sequelize.UUID,
defaultValue: Sequelize.UUIDV4,
allowNull: false,
primaryKey: true,
},
message: {
type: DataTypes.STRING,
allowNull: false,
},
});
module.exports = FlightComment;
File for User:
const User = db.sequelize.define(
"User",
{
id: {
type: Sequelize.UUID,
defaultValue: Sequelize.UUIDV4,
allowNull: false,
primaryKey: true,
},
name: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
},
//Many more attributes
},
);
User.hasMany(Flight, {
as: "flights",
foreignKey: {
name: "userId",
allowNull: false,
},
});
User.hasMany(FlightComment, {
as: "comments",
foreignKey: {
name: "userId",
allowNull: false,
},
onDelete: "CASCADE",
hooks: true,
});
module.exports = User;
Upvotes: 0
Views: 915
Reputation: 606
You can initialise your db and its associations programmatically (with a file in the same folder as models) like:
'use strict'
const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.basename(__filename);
const config = {
"username": "root",
"password": "YOUR ROOT PASSWORD HERE",
"database": "YOUR DATABASE NAME HERE",
"dialect": "postgres"
}
const db = {}
let sequelize = new Sequelize(config.database, config.username, config.password, config);
fs.readdirSync(__dirname)
.filter(file => {
return (file.indexOf('.') !== 0)
&& (file !== basename)
&& (file.slice(-3) === '.js');
})
.forEach(file => {
const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes);
db[model.name] = model;
});
Object.keys(db).forEach(modelName => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;
With this you need to declare your model files like this:
module.exports = Flight = (sequelize, DataTypes) => {
const Flight = sequelize.define('Flight', {
//Many beautiful attributes
})
Flight.associate = models => {
Flight.hasMany(models.FlightComment, {
as: 'comments',
foreignKey: {
name: "flightId",
allowNull: false,
},
onDelete: "CASCADE",
hooks: true
})
Flight.belongsTo(models.User, {
as: 'flight',
foreignKey: {
name: "flightId",
allowNull: false,
}
})
}
return Flight
}
Upvotes: 1
Reputation: 43
At the end I defined all models, which are depending on another, within one file. This is not the solution I was searching for but it works...
Upvotes: 1