Reputation: 13300
I've been spending hours for nothing. I've had so many sources, they are all kinda the same, but I just couldn't make my project work.
This question Sequelize.js - "is not associated to" is so much the same to mine, BUT, this question of mine shouldn't be a duplicate. Because it has certainly a new issue!
To list down my sources, the ones that I've read thoroughly and tried out:
To add context, I'm trying to provide a route that lets the users get their profile. Every USER has ONLY one ROLE.
Like so:
{
id: 4,
email: '[email protected]',
role: {
id: 2,
name: 'admin'
}
}
Using findOne with WHERE and INCLUDE
exports.getme = (req, res) => {
db.users.findOne({
where: { id: req.user.id },
include: [{
model: db.roles,
}]
})
.then(data => {
res.send(data)
})
.catch(err => {
console.log(err)
res.status(500).send({
message: "An error has occured while retrieving data."
})
})
}
The error that I get is:
Role is not associated to User!
And here are the models, and how I put their respective associations:
Role.js
'use strict';
module.exports = (sequelize, DataTypes) => {
const Role = sequelize.define('Role', {
id: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true,
field: "id"
},
role: DataTypes.STRING
}, {
timestamps: false
});
Role.associate = function (models) {
Role.hasMany(models.User, {
foreignKey: "roleId",
sourceKey: "id"
})
}
return Role;
};
User.js
'use strict';
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define('User', {
id: { type: DataTypes.BIGINT, allowNull: false, autoIncrement: true, unique: true, primaryKey: true },
email: DataTypes.STRING,
}, {});
User.associate = function (models) {
User.belongsTo(models.Role, {
foreignKey: "roleId",
targetKey: "id"
});
}
return User
}
Also, when I check the relations of my tables, I can only see details in my USER table, but none in my ROLES table.
EDIT: Anatoly from the comment section pointed out that it seems db.users
has no association when the findOne
fires up. Here's how I setup my models in my server.js
:
....
const db = require("./app/models")
if (process.env.NODE_ENV === "production") {
db.sequelize.sync().then(() => {
useRoutes()
seedDB()
})
} else {
db.sequelize.sync({ force: true }).then(() => {
console.log("Drop and re-sync db.")
useRoutes()
seedDB()
})
}
function useRoutes() {
console.log("Use routes...")
require("./app/routes/user/user.routes")(app)
require("./app/routes/emojis/emojis.routes")(app)
require("./app/routes/auth/auth.routes")(app)
const db = require("./app/models")
// Custom.
db.op = db.Sequelize.Op
// Models
db.appsettings = require("./app/models/appsettings/appsettings.model")(db.sequelize, db.Sequelize)
db.countries = require("./app/models/appsettings/country.model")(db.sequelize, db.Sequelize)
db.users = require("./app/models/user/user.model")(db.sequelize, db.Sequelize)
db.roles = require("./app/models/user/role.model")(db.sequelize, db.Sequelize)
db.userscores = require("./app/models/user/userscore.model")(db.sequelize, db.Sequelize)
db.answers = require("./app/models/game/answer.model")(db.sequelize, db.Sequelize)
db.categories = require("./app/models/game/category.model")(db.sequelize, db.Sequelize)
db.questions = require("./app/models/game/question.model")(db.sequelize, db.Sequelize)
db.useracoomplishedquestions = require("./app/models/game/useracoomplishedquestion.model")(db.sequelize, db.Sequelize)
}
models/index.js (generated by Sequelize and I modified it a bit and use glob
to scan through subfolders easily)
'use strict';
const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config')[env];
const db = {};
const glob = require("glob")
let sequelize;
if (config.use_env_variable) {
sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
sequelize = new Sequelize(config.database, config.username, config.password, config);
}
// Use glob to access model files inside subfolders.
const files = glob.sync(__dirname + "/*/*.js")
files.forEach(file => {
const model = sequelize['import'](file);
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;
Upvotes: 2
Views: 4343
Reputation: 22803
By this code
// Models
db.appsettings = require("./app/models/appsettings/appsettings.model")(db.sequelize, db.Sequelize)
db.countries = require("./app/models/appsettings/country.model")(db.sequelize, db.Sequelize)
db.users = require("./app/models/user/user.model")(db.sequelize, db.Sequelize)
db.roles = require("./app/models/user/role.model")(db.sequelize, db.Sequelize)
db.userscores = require("./app/models/user/userscore.model")(db.sequelize, db.Sequelize)
db.answers = require("./app/models/game/answer.model")(db.sequelize, db.Sequelize)
db.categories = require("./app/models/game/category.model")(db.sequelize, db.Sequelize)
db.questions = require("./app/models/game/question.model")(db.sequelize, db.Sequelize)
db.useracoomplishedquestions = require("./app/models/game/useracoomplishedquestion.model")(db.sequelize, db.Sequelize)
you overridden model definitions registered in models/index.js that's why these models don't have associations. Just remove these lines.
Upvotes: 1