I am using sequelize version:5.21.2, and has the following error: 'Tweet is not associated to User!'
Error: { SequelizeEagerLoadingError: Tweet is not associated to User!
at Function._getIncludedAssociation (D:\References\Youtube\Sequelize\sequelize-1-hour\node_modules\sequelize\lib\model.js:715:13)
at Function._validateIncludedElement (D:\References\Youtube\Sequelize\sequelize-1-hour\node_modules\sequelize\lib\model.js:619:53)
at options.include.options.include.map.include (D:\References\Youtube\Sequelize\sequelize-1-hour\node_modules\sequelize\lib\model.js:516:37)
at Array.map (<anonymous>)
I have two models
Tweet.js
const Sequelize = require('sequelize');
//sequelize comes from global.sequelize in connection.js
const Tweet = sequelize.define('Tweet', {
id: {
type: Sequelize.INTEGER(11),
allowNull: true,
autoIncrement: true,
primaryKey: true
},
userId: Sequelize.INTEGER(11),
content: Sequelize.STRING(300)
});
Tweet.associate = function(models) {
Tweet.belongsTo(models.User, { foreignKey: 'userId' });
};
module.exports = Tweet;
and User.Js
const Sequelize = require('sequelize');
//sequelize comes from global.sequelize in connection.js
const User = sequelize.define('User', {
id: {
type: Sequelize.INTEGER(11),
primaryKey: true
},
username: {
type: Sequelize.STRING(35),
},
passwd: {
type: Sequelize.STRING(20),
allowNull: false
}
});
User.associate = function(models) {
User.hasMany(models.Tweet);
};
module.exports = User;
and the code which throws error is
const users = await User.findAll({
where: { id: '1' },
include: [Tweet]
}).catch(errHandler);
I don't know how to include Tweets when a user is fetched.
You have defined functions, inside your models, that create your associations. However, you never call these functions. After instanciating your Sequelize object and initializing your models, you should run the following code to have your associations created:
for(let modelName in sequelize.models) {
sequelize.models[modelName].associate(sequelize.models);
}
See:
Sequelize models member
Iterating through objects in Javascript
Related
I have this already created two tables called User and Profile.
This is how my model for User looks like..
const Sequelize = require("sequelize");
const db = require("../db");
const User = db.define("User", {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
name: {
type: Sequelize.STRING,
allowNull: true,
},
email: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
validator: {
isEmail: true,
},
},
});
module.exports = User;
and model for Profile looks like..
const Sequelize = require("sequelize");
const User = require("./User");
const db = require("../db");
const Profile = db.define("Profile", {
image: {
type: Sequelize.STRING,
},
description: {
type: Sequelize.TEXT,
},
});
module.exports = Profile;
Now I want to define a one-to-one relationship between User and Profile such that user will recieve a profileId column.
so i am defining it like this
Profile.hasOne(User, {
foreignKey: {
allowNull: false,
},
});
User.belongsTo(Profile);
Now i am not able to figure out how to write migrations for the newly added foreign key
can anyone help me please..
Thanks.
I got the answer. for someone who is confused like me here is the answer
since the User table already exists, migrations for the foreignkey will look like this
module.exports = {
async up(queryInterface, Sequelize) {
return await queryInterface.addColumn("Users", "ProfileId", {
type: Sequelize.INTEGER,
references: {
model: "Profiles",
key: "id",
},
});
},
async down(queryInterface, Sequelize) {
return await queryInterface.removeColumn("Users", "ProfileId", {
type: Sequelize.INTEGER,
references: {
model: "Profiles",
key: "id",
},
});
},
};
the Users in addColumn and removeColumn is the name of the table in which foreignkey was added.
the ProfileId is the name for foreignkey which you would have specified in hasOne.
hope this helps..
I have 2 tables, users and users_signature where the signature takes several applications and I need to make a select according to the application.
Models:
user
const { INTEGER } = require('sequelize');
const Sequelize = require('sequelize');
const database = require('../../config/db');
const User_has_signature = require('./user_has_signature');
const Usuario = database.define('usuario', {
usu_id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true
},
usu_rg: {
type: Sequelize.STRING,
},
},
{
freezeTableName: true,
createdAt: false,
updatedAt: false,
});
User.hasMany(User_has_signature, {as: 'user_has_signature'});
module.exports = User;
User_has_signature
const { INTEGER } = require('sequelize');
const Sequelize = require('sequelize');
const database = require('../../config/db');
const User_has_signature = database.define('user_has_signature', {
usu_has_signature_id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true
},
user_usu_id: {
type: Sequelize.STRING,
},
signature_aplicativo_signature_aplicativo_id: {
type: Sequelize.STRING,
},
signature_type_signature_type_id: {
type: Sequelize.STRING,
},
},
{
freezeTableName: true,
createdAt: false,
updatedAt: false,
});
User_has_signature.associate = (models) => {
User_has_signature.belongsTo(models.User,
{ foreignKey: 'user_usu_id', as: 'users' });
};
module.exports = User_has_signature;
Controller
UserController
const User = require("../../model/user/user")
const User_has_signature = require("../../model/user/user_has_signature")
async index(req, res){
const user = await User.findAll({
include: [{
model: User_has_signature,
foreignKey: 'user_usu_id',
through: {
where: {signature_ttype_signature_type_id: 3}
}
}]
})
res.status(200).json(user)
return
}
The error that is returning to me in the terminal is: (node:15168)
UnhandledPromiseRejectionWarning: SequelizeEagerLoadingError:
user_has_signature is associated to usuario using an alias. You must
use the 'as' keyword to specify the alias within your include
statement
I think you have to specify the alias you have given when writing your query :
include: [{
model: User_has_signature,
foreignKey: 'user_usu_id',
as : 'users'
through: {
where: {signature_ttype_signature_type_id: 3}
}]
Either way I'm using Sequelize more in Typescript, so I'm not sure of the syntax.
The way it handles One to Many relationship isn't the clearest I've seen (Like Symfony or Spring)
Hello I am new to nodejs and currently I integrated Sequelize with NodeJs. I make different models and define associations but when I fetch data then I received following error
TypeError: include.model.getTableName is not a function
My Box Model
const Sequelize = require('sequelize');
const PostBox = require("./PostBox");
module.exports = function (sequelize) {
var Box = sequelize.define('box', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
references: {
model: PostBox,
key: "box_id" // this is the `posts.post_id` column - name it according to your posts table definition (the one defined in ./Post)
}
}
}, {timestamp: false});
Box.associate = function (models) {
Box.hasMany(models.PostBox, {targetKey: 'user_posts_id',foreginkey: 'id'});
};
return Box;
};
Post Box Model
const Sequelize = require('sequelize');
var Post = require('./Post');
module.exports = function (sequelize) {
var PostBox = sequelize.define('user_posts_boxes', {
id: {
type: Sequelize.INTEGER,
primaryKey: true
},
user_posts_id: {
type: Sequelize.INTEGER,
references: {
model: Post,
key: "id" // this is the `posts.post_id` column - name it according to your posts table definition (the one defined in ./Post)
}
},
box_id: {
type: Sequelize.INTEGER,
},
user_id: {
type: Sequelize.INTEGER
},
post_type_id: {
type: Sequelize.INTEGER
}
}, {timestamp: false}
);
PostBox.associate = function (models) {
PostBox.belongsTo(models.Post, {targetKey: 'id', foreignKey: 'user_posts_id'});
};
return PostBox;
};
This is my base model from where I am calling associated model
const Sequelize = require('sequelize');
var Box = require('./Box');
const sequelize = new Sequelize('store_db', 'root', 'root', {
host: 'localhost',
dialect: 'mysql'
});
const User = require("./User")(sequelize);
const PostBox = require("./PostBox")(sequelize);
const Post = require("./Post")(sequelize);
function findOneUer() {
return User.findOne({attributes: ['id', 'username']});
}
function findPostById(id) {
var post = PostBox.findOne({
attributes: ['id', "user_posts_id", "box_id"],
where: {id: id},
include: [
{model: Box, required: true}
]
});
return post;
}
module.exports = {findPostById: findPostById};
When I call findPostById(2) method from my base mode then I received this error.
i'm using NodeJS & Sequelize for a school project and i'm struggling on making associations w/ sequelize work. I tried a couple of things before but nothing that made my day.
Basically the thing is that a user can have several playlists (hasMany).
And a playlist belongs to a user (belongsTo).
My error is:
Association with alias "playlist" does not exist on users
Here are my models:
/* USER MODEL */
const Sequelize = require('sequelize');
const { db } = require('../utils/db');
const User = db.define('users', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER,
},
userID: {
type: Sequelize.INTEGER,
allowNull: false,
field: 'user_id',
},
firstName: {
type: Sequelize.STRING,
field: 'first_name',
allowNull: false,
},
}, {
underscored: true,
tableName: 'users',
freezeTableName: true, // Model tableName will be the same as the model name
});
module.exports = {
User,
};
/* PLAYLIST MODEL */
const sequelize = require('sequelize');
const { db } = require('../utils/db');
const Playlist = db.define('playlist', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: sequelize.INTEGER,
},
name: {
type: sequelize.STRING,
field: 'name',
allowNull: false,
},
coverUrl: {
type: sequelize.STRING,
field: 'cover_url',
allowNull: true,
},
ownerId: {
type: sequelize.INTEGER,
allowNull: false,
references: {
model: 'users',
key: 'user_id',
},
},
}, {
underscored: true,
tableName: 'playlist',
freezeTableName: true,
});
module.exports = {
Playlist,
};
Here is how i load my models:
const { Credentials } = require('./credentials');
const { User } = require('./users');
const { Playlist } = require('./playlist');
function loadModels() {
User.associate = (models) => {
User.hasMany(models.Playlist, { as: 'playlist' });
};
Playlist.associate = (models) => {
Playlist.belongsTo(models.User, { foreignKey: 'owner_id', as: 'owner' });
};
Credentials.sync({ force: false });
User.sync({ force: false });
Playlist.sync({ force: false });
}
module.exports = {
loadModels,
};
And finally here is my query where i get this error:
const express = require('express');
const { auth } = require('../../middlewares/auth');
const { Playlist } = require('../../models/playlist');
const { User } = require('../../models/users');
const router = express.Router();
router.get('/playlist', [], auth, (req, res) => {
User.findOne({
where: { userID: req.user.user_id }, include: 'playlist',
}).then((r) => {
console.log(r);
});
});
module.exports = router;
I'm trying to get all the playlist that belongs to a user.
I removed all the useless code (jwt check etc..)
So when i'm doing a get request on /playlist I get:
Unhandled rejection Error: Association with alias "playlist" does not exist on users.
I understand the error but don't understand why i get this.
What did I miss, any ideas ?
Thanks,
I finally fixed it by re-make all my models and definitions with migrations.
I had the same problem and the solution was that Sequelize pluralize the models name so in my case "playlist" does not exist on users because Sequelize pluralized my model so I had to put "Playlists" instead.
I am trying to map sequelize one to many association by referring to sequelize documentation but I could not able to find a complete example to get it work.
I have a ClaimType model as follows
const Sequelize = require('sequelize');
module.exports = function (sequelize) {
const ClaimType = sequelize.define('claim_type', {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
primaryKey: true
},
name: {
type: Sequelize.STRING
}
}, {
timestamps: false,
freezeTableName: true
});
return ClaimType;
};
and MaxClaimAmount
const Sequelize = require('sequelize');
module.exports = function (sequelize) {
const MaxClaimAmount = sequelize.define('max_claim_amount', {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
primaryKey: true
},
amount: {
type: Sequelize.DECIMAL
},
year: {
type: Sequelize.INTEGER
}
}, {
timestamps: false,
freezeTableName: true
});
return MaxClaimAmount;
};
finally in index.js
const ClaimType = require('./model/claim_type.js')(sequelize);
const MaxClaimAmount = require('./model/max_claim_amount.js')(sequelize);
ClaimType.hasMany(MaxClaimAmount, { as: 'claimAmount' });
sequelize.sync({ force: false }).then(() => {
return sequelize.transaction(function (t) {
return ClaimType.create({
name: 'OPD'
}, { transaction: t }).then(function (claimType) {
// want to know how to associate MaxClaimAmount
});
}).then(function (result) {
sequelize.close();
console.log(result);
}).catch(function (err) {
sequelize.close();
console.log(err);
});
});
ClaimType object is returned from the first part of the transaction and I want to know how to implement the association between ClaimType and MaxClaimAmount?
You make the association in your models.
(Associations: one-to-many in sequelize docs)
const ClaimType = sequelize.define('claim_type', {/* ... */})
const MaxClaimAmount = sequelize.define('max_claim_type', {/* ... */})
ClaimType.hasMany(MaxClaimAmount, {as: 'MaxClaims'})
This will add the attribute claim_typeId or claim_type_id to MaxClaimAmount (you will see the column appear in your table). Instances of ClaimType will get the accessors getMaxClaims and setMaxClaims (so you can set foreign id on table)
The next step would be creating your backend routes and using the accessor instance methods to set a foreign key. The accessor functions are called like so: (instance1).setMaxClaims(instance2)
Instances are returned from queries