Sequelize Eager Loading Error - node.js

I'm getting an issue where include in my query isn't working, and I can't figure out why. I have two models: Question and Suggestion.
Question:
var Question = sequelize.define('Question', {
}, {
classMethods: {
associate: function (models) {
// associations can be defined here
Question.belongsTo(models.User, {
as: 'askerId',
foreignKey: 'askerId'
})
Question.belongsTo(models.User, {
as: 'winnerId',
foreignKey: 'winnerId'
})
Question.hasMany(models.Suggestion)
Question.hasMany(models.TagQuestion)
}
}
})
Suggestion:
var Suggestion = sequelize.define('Suggestion', {
text: DataTypes.STRING
}, {
classMethods: {
associate: function (models) {
// associations can be defined here
Suggestion.belongsTo(models.Question, {
foreignKey: 'questionId',
as: 'question'
})
Suggestion.belongsTo(models.User)
Suggestion.hasMany(models.Vote)
}
}
})
And my attempted query is here:
Question.findAll({
include: [{
model: models.Suggestion
}]
})
But I keep getting the error: SequelizeEagerLoadingError: Suggestion is not associated to Question!
Why are they not associated? They are in my database (based on my migration that I wrote). And how should I set up my associations if I am currently doing it incorrectly? I've looked at other people with this issue and not been able to figure out why my associations are wrong.

I ran into this error because I had a bad syntax. I was using
include: {
model: db.modelOne,
model: db.modelTwo
}
without the brackets []. Including it solved the error.
Anyway, the mentioned docs give this much cleaner option to include all the foreign models recursively:
User.findAll({ include: [{ all: true, nested: true }]});

Please check out your init-models.js, code like this:
question.hasMany(suggestion, { as: 'suggestion', foreignKey: 'questionId'});
suggestion.belongsTo(question, { as: 'question', foreignKey: 'questionId'});
is exist ?
from
"sequelize": "^6.6.2"

Sequelize no longer supports classMethods. classMethods and instanceMethods are removed.
Previous:
const Model = sequelize.define('Model', {
...
}, {
classMethods: {
associate: function (model) {...}
},
instanceMethods: {
someMethod: function () { ...}
}
});
New:
const Model = sequelize.define('Model', {
...
});
// Class Method
Model.associate = function (models) {
...associate the models`enter code here`
};
Refrence: http://docs.sequelizejs.com/manual/tutorial/upgrade-to-v4.html#breaking-changes

Related

Sequelize one to Many insertion is not working?

This is my code :
const add_ticket = await db.Ticket.create({
userId,
travels: ticket.travels,
TicketInventory: {
fare: "Fare",
passenger: "passenger",
seatName: "seatName",
serviceTax: "serviceTax",
}
},
{
include: {
model: db.TicketInventory,
}})
I need to add "TicketInventory" details under "TicketInventory" table ! But it isnt adding - but rest of the details are been added to "ticket" table !
Association : Ticket HasMany TicketInventory and TicketInventory BelongsTo Ticket !
My assocaition code:
/// For Ticket Model
static associate(models) {
Ticket.hasMany(models.TicketInventory, {
foreignKey: 'ticketId',
onDelete: 'CASCADE' ,
as: 'vegetables'
});
}
};
/// For TicketInventory Model
static associate(models) {
TicketInventory.belongsTo(models.Ticket, {
foreignKey: 'ticketId',
});
}
Please help to resolve
This kind of thing...
const add_ticket = await db.Ticket.create({
userId,
travels: ticket.travels,
vegetables: [{
fare: "Fare",
passenger: "passenger",
seatName: "seatName",
serviceTax: "serviceTax",
}]
},
{
include: [{
model: db.TicketInventory,
as: "vegetables"
}]
})

Associations HasMany works but HasOne does not

I have two models defined in GraphQL Cars and Brands (their association is cars.brand_id = brands.id).
The schema only works when I define:
Cars.hasMany(models.brands, {
sourceKey: 'brand_id',
foreignKey: 'id'
})
Whereas it doesn't work if I define it in the following way:
Cars.hasOne(models.brands, {
sourceKey: 'brand_id',
foreignKey: 'id'
}),
Here I share a bit more of the schema (I am using makeExecutableSchema to split the files definitions):
Associations:
CarBrands.js
CarBrands.associate = models => {
CarBrands.hasOne(models.cars, {
foreignKey: 'brand_id',
});
}
Cars.js
Cars.associate = models => {
Cars.belongsTo(models.brands),
Cars.hasMany(models.car_images, {
foreignKey: {
name: 'car_id',
allowNull: false
},
onDelete: "cascade"
});
};
Car Model:
export const typeDef = `
type Cars {
user_id: Int!,
title: String!,
brands: [CarBrands!],
car_images: [CarImages],
}
`;
The SQL is well-formed, and car_images returns the data correctly whereas brands does not. Any idea why is that?
Any hint will be forever appreciated.
Thanks
You can find the document one-to-one-relationships at there: https://sequelize.org/master/manual/assocs.html#one-to-one-relationships
.In the document introduces 4 options to define one-to-one.
Try it:
Brands.hasOne(Cars, {
foreignKey: 'brand_id'
});
Cars.belongsTo(Brands);

In Nodejs I keep getting Sequelize.js - “is not associated to” error

I have the following 2 tables in node.js:
users
'use strict'
let Sequelize = require('sequelize');
let dbConnection = require('../connection.js');
let users = dbConnection.connection.define('users', {
//user table detail
}, {
classMethods: {associate: function (models) {
// associations can be defined here
users.hasMany(models.chat_histories, {foreignKey: 'sender_id'});
users.hasMany(models.chat_histories, {foreignKey: 'receiver_id'});
}}
}, {
timestamps: false
});
module.exports = users;
chat_histories
'use strict'
let Sequelize = require('sequelize');
let dbConnection = require('../connection.js');
let chat_histories = dbConnection.connection.define(
'chat_histories', {
//chat_history detail
link_id: {
type: Sequelize.STRING(64),
references: 'links', // <<< Note, its table's name, not object name
referencesKey: 'id' // <<< Note, its a column name
},
sender_id: {
type: Sequelize.BIGINT,
references: 'users', // <<< Note, its table's name, not object name
referencesKey: 'id' // <<< Note, its a column name
},
receiver_id: {
type: Sequelize.BIGINT,
references: 'users', // <<< Note, its table's name, not object name
referencesKey: 'id' // <<< Note, its a column name
}
},
{
classMethods: {associate: function (models) {
// associations can be defined here
chat_histories.belongsTo(models.users, {foreignKey: 'sender_id'});
chat_histories.belongsTo(models.users, {foreignKey: 'receiver_id'});
chat_histories.belongsTo(models.links, {foreignKey: 'link_id' });
}}
}, {
timestamps: false
}
);
module.exports = chat_histories;
However, every time when I do query in chat_history table I have the following error message:
SequelizeEagerLoadingError: chat_histories is not associated to users!
Is there anything wrong?
I can see myself have already associated chat_historeis with users table via adding the following in chat_histories.js
classMethods: {associate: function (models) {
// associations can be defined here
chat_histories.belongsTo(models.users, {foreignKey: 'sender_id'});
chat_histories.belongsTo(models.users, {foreignKey: 'receiver_id'});
chat_histories.belongsTo(models.links, {foreignKey: 'link_id' });
}}
And added the following in user.js
classMethods: {associate: function (models) {
// associations can be defined here
users.hasMany(models.chat_histories, {foreignKey: 'sender_id'});
users.hasMany(models.chat_histories, {foreignKey: 'receiver_id'});
users.hasMany(models.links, {foreignKey: 'owner_id'});
}}
At the following is how I do search for SQL statement:
select distinct users from users, chat_histories where (users.id =
chat_histories.sender_id or users.id = chat_histories.receiver_id) and
chat_histories.link_id = :link_id;
let chat_histories = model.chat_histories;
let users = model.users;
let usersList;
const Op = Sequelize.Op;
await users.findAll({
where: {
[Op.and]: [
{
[Op.or]:[
{id: chat_histories.sender_id},
{id: chat_histories.receiver_id}
]
},
{
link_id: link_id
}
],
},
include: [
{
model: chat_histories,
required: false
},
]
}).then(function(data) {
usersList = data;
});
You have not defined associations properly. Associations need to be created for both users and chat_histories table.
users.hasMany(models.chat_histories, { foreignKey: 'sender_id', as: 'chat_histories' });
chat_histories.belongsTo(models.users, { foreignKey: 'sender_id', as: 'user' });
I have never used keywords like references and referencesKey in Sequelize models to define associations. I neither find any reference for them in the documentation.
Hope it helps!
ok at the end I figured out that in the class where I want to do the query, I need to put the following code before doing the query
users.hasMany(chat_histories, {foreignKey: 'sender_id'});
The above code is defined in the class where I did the query instead of in ORM class

How can I make an order with n:m associations?

I'm using sequelize.js for ORM, and I have some questions while I use it.
Models looks like this
var Keyword = db.define('keyword', {
name: db.STRING,
});
var KeywordSearchableMap = db.define('keyword_searchable_map', {
keyword_id: db.INTEGER,
searchable: db.STRING,
searchable_id: db.STRING,
score: db.STRING,
});
var Searchable = db.define('searchable') {
name: db.STRING,
});
Keyword.belongsToMany(Searchable, {
through: {
model: KeywordSearchableMap,
},
foreignKey: 'keyword_id'
});
Searchable.belongsToMany(Keyword, {
through: {
model: KeywordSearchableMap,
},
foreignKey: 'searchable_id'
});
And I want to get 'Searchable' things by Keyword.getSearchables() order by 'score' field in 'KeywordSearchableMap'
Is there any methods to get sorted searchable objects?

Where clause for associated objects with Node and sequelize

I have Books which have an author and an editor. I'd like to query for all books with a title like '%gone% and author.name like '%paul%' - I couldn't find documentation about doing this, but I've tried various formats based on what I've googled.
Attempt using a filter on includes:
var includes = [
{"model": db.User, as: 'Author', through: {"where": {"name": { like: '%paul%'}}}}
];
var filter = { title: { like: '%gone%'}};
return Book.findAll({ include: includes, order: 'id desc', where: filter});
While the restriction on title works, the author name is ignored (no errors).
Variation without the 'through' (same result - doesn't affect resultset):
var includes = [
{"model": db.User, as: 'Author', "where": {"name": { like: '%paul%' } } }
];
And how I initiatively thought it might work (causes error):
var filter = { title: { like: '%gone%'}, 'author.name' : { like : '%paul%' } };
Any clues or pointers to documentation to help me do this??
Thanks.
Model:
var User = sequelize.define('User', {
name: {
type: DataTypes.STRING
},
...
classMethods: {
associate: function (models) {
User.hasMany(Book, { as: 'Author', foreignKey: 'author_id' });
User.hasMany(Book, { as: 'Editor', foreignKey: 'editor_id' });
},
...
}
var Book = sequelize.define('Book', {
title: {
type: DataTypes.STRING,
len: [20]
},
...
classMethods: {
associate: function (models) {
Book.belongsTo(User, { as: 'Author', foreignKey: 'author_id' });
Book.belongsTo(User, { as: 'Editor', foreignKey: 'editor_id' });
},
...
I got it to work by removing the 'as' in the User associations to Book to:
User.hasMany(Book, { foreignKey: 'author_id' });
User.hasMany(Book, { foreignKey: 'editor_id' });
Then I can filter as expected with:
var includes = [
{model: db.User, as: 'Author'},
{model: db.User, as: 'Editor'}
];
var filter = { title: { like: '%gone%'}, 'Author.name' : { like : '%paul%' } };
return Book.findAll({ include: includes, order: 'id desc', where: filter});
It helped to turn on logging of SQL statements as described here: How can I see the SQL generated by Sequelize.js?

Resources