How to disable createdAt field in a Sequelize model? - node.js

I need an updatedAt field, but not a createdAt field.
So, I wrote this model:
const Vote = sequelize.define('Vote', {
createdAt: false,
updatedAt: { type: DataTypes.DATE, allowNull: false },
type: { type: DataTypes.INTEGER, allowNull: true },
userId: { type: DataTypes.INTEGER, allowNull: false },
postId: { type: DataTypes.INTEGER, allowNull: false }
});
However, when I try to find a row, Sequelize includes createdAt for some reason. I've also tried just removing the createdAt: false, but it makes no difference.
Do I just have to manually filter out createdAt in all my queries?
Shouldn't this be controlled by my model?
Thanks!

Ok, so you can disable createdAt while keeping updatedAt by disabling timestamps, and then manually adding back updatedAt with a literal timestamp type to set updatedAt automatically as normal.
Like this:
updatedAt: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: sequelize.literal('CURRENT_TIMESTAMP')
},
type: { type: DataTypes.INTEGER, allowNull: true },
userId: { type: DataTypes.INTEGER, allowNull: false },
postId: { type: DataTypes.INTEGER, allowNull: false }
},
{ timestamps: false }
);

Related

Why does associating belongsTo in Sequelize give me this error?

I'm stuck with this problem for quite some time now and I don't know what's wrong with my code I'm trying to associate one table to another but only half of it works any help would be greatly appreciated.
models/companies.js
const DataTypes = require('sequelize');
const sequelize = require('../config/database');
const Users = require('./users');
const Companies = sequelize.define(
'companies',
{
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER
},
name: {
type: DataTypes.STRING(50),
unique: true,
allowNull: false
},
image_url: {
type: DataTypes.STRING(100),
unique: true
},
created_at: {
allowNull: true,
type: DataTypes.DATE,
defaultValue: Date.now()
},
updated_at: {
allowNull: true,
type: DataTypes.DATE,
defaultValue: Date.now()
}
},
{
//Rewrite default behavior of sequelize
timestamps: false,
paranoid: true,
underscored: true
}
);
Companies.hasMany(Users);
Users.belongsTo(Companies);
Companies.sync();
module.exports = Companies;
models/users.js
const DataTypes = require('sequelize');
const sequelize = require('../config/database');
const Users = sequelize.define(
'users',
{
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER
},
name: {
type: DataTypes.STRING(40),
allowNull: false
},
email: {
type: DataTypes.STRING(60),
allowNull: false,
unique: true
},
password: {
type: DataTypes.STRING(60)
},
role: {
type: DataTypes.STRING(40),
allowNull: false
},
image_url: {
type: DataTypes.STRING(100),
unique: true
},
batch: {
type: DataTypes.STRING(3)
},
major: {
type: DataTypes.STRING(10)
},
company_id: {
type: DataTypes.INTEGER,
allowNull: false
},
created_at: {
allowNull: true,
type: DataTypes.DATE,
defaultValue: Date.now()
},
updated_at: {
allowNull: true,
type: DataTypes.DATE,
defaultValue: Date.now()
}
},
{
//Rewrite default behavior of sequelize
timestamps: false,
paranoid: true,
underscored: true
}
);
Users.sync();
module.exports = Users;
Then after I try to run this code below
const Companies = require('./database/models/companies');
const Users = require('./database/models/Users');
//Relation 1: Company and Users
Companies.findAll({ include: [ Users ] }).then((res) => console.log(res));
Users.findAll({ include: [ Companies ] }).then((res) => console.log(res));
it gives me this error:
(node:4893) UnhandledPromiseRejectionWarning: SequelizeEagerLoadingError: companies is not associated to users!
I've tried a couple of solutions online but it didn't help in this case.
BelongsTo means one to one relationship while a company may have multiple users (meaning, calling BelongsTo after hasMany collide!).
For more: https://sequelize.org/master/manual/assocs.html

How to findAll query where value is from associated table in Sequelize?

I am using Sequelize as my ORM and I want to know the best way to achieve the desired outcome.
With the models below, how do I return an array that returns all the Books and Novels while removing duplicates that have the same author+title.
var Book = sequelize.define('Book', {
id: {
type: DataTypes.INTEGER,
allowNull: false,
autoIncrement: true,
primaryKey: true
},
title: {
type: DataTypes.STRING
},
author: {
type: DataTypes.STRING
}
//....other columns
})
var Novel = sequelize.define('Novel', {
id: {
type: DataTypes.INTEGER,
allowNull: false,
autoIncrement: true,
primaryKey: true
},
title: {
type: DataTypes.STRING
},
author: {
type: DataTypes.STRING
}
//...other different columns
})

Sequelize Multi Inserting Data

Hi everybody =) It's my first time using sequelize with postgresql, and I have problem with multi inserting data with sequelize(node.js). We have some tables(see in pic)
Table Relations
1) Clients -> 1:M -> Contracts
2) Contracts -> 1:M -> Contracts_attaches
3) Rates -> 1:M -> Contracts_attaches
Clients Model
const Client = db.define('clients', {
id_clients: {
type: Sequelize.INTEGER,
allowNull: false,
autoIncrement: true,
primaryKey: true,
},
nclients: {
type: Sequelize.STRING
}
-some fields-
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
Rate Model
const Rate = db.define('rates', {
id_rates: {
type: Sequelize.INTEGER,
allowNull: false,
autoIncrement: true,
primaryKey: true
}
--fields--
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
})
Contract Model
const Contract = db.define('contracts', {
id_contracts: {
type: Sequelize.INTEGER,
allowNull: false,
autoIncrement: true,
primaryKey: true
},
--fields--
id_clients: {
type: Sequelize.INTEGER,
allowNull: false
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
})
Contract_attach Model
const Contract_attach = db.define('contract_attach', {
id: {
type: Sequelize.INTEGER,
allowNull: false,
autoIncrement: true,
primaryKey: true
},
contracts_id: {
type: Sequelize.INTEGER,
references:{
model:'contracts',
key:'id_contracts'
}
},
rate_id: {
type: Sequelize.INTEGER
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
},
})
Association config
Contract.belongsTo(Contract_attach, { foreignKey:'id_contracts', sourceKey:'contracts_id' });
Contract_attach.hasMany(Contract,{foreignKey:'id_contracts', sourceKey:'contracts_id'});
Contract_attach.hasMany(Rate,{foreignKey: 'id_rates', sourceKey: 'rate_id'});
Rate.belongsTo(Contract_attach, { foreignKey: 'rate_id', sourceKey: 'id_rates' });
Example Inserting Data
I try insert data like this code
Contract.create({'numcontract':22,'datereg':'2019-12-11','id_clients':5,Contract_attach:[{'rate_id':2,'rate_id':3}]},
{include: [Contract_attach]}).then(result => console.log(result));
or this code
Contract.create({'numcontract':22,'datereg':'2019-12-11','id_clients':5,Contract_attach:[{'ratename':'Small Buissness','ratename':'Small Buissness 10'}]},
{include: [Contract_attach]}).then(result => console.log(result));
When I try insert data with this code, sequelize inserting data just for Contract table, and ignoring insert to Contract_attach.
PS. Rate table have data, and we don't need insert data to the Rate table.
For some, it may and will be useful, but I solved this problem like this
Contr.create({'numcontract':22,'datereg':'2019-12-11','id_clients':5})
.then(function(contr){
contract_att.bulkCreate([{'contracts_id':contr.id_contracts, 'rate_id':2},{'contracts_id':contr.id_contracts,'rate_id':3}]);
});
If you have another solution, pls share ))
There are several issues here
you said Contract > 1:M > Contract_attach then you write Contract_attach.hasMany(Contract...etc. it should be the other way around Contract.hasMany(Contract_attach...etc same goes for rates
In diagram there is relation between Contract_attach and rates but the define you didn't define this reference
Its not clear that columns rate_id and contract_id are nullable or not. based on that we can define if Contract_attach can or can not be belong to 2 different tables.
I think that the database schema need to change or explain why its in this way

sequelize - inner join gives an error after added a foreign key

i have these 2 models:
module.exports = function(sequelize, DataTypes) {
return sequelize.define('services_prices', {
id: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true
},
service_id: {
type: DataTypes.INTEGER(11),
allowNull: true,
references: {
model: 'services',
key: 'id'
}
},
created_at: {
type: DataTypes.DATE,
allowNull: false
},
limit: {
type: DataTypes.INTEGER(11),
allowNull: true
},
price: {
type: DataTypes.INTEGER(11),
allowNull: true
}
});
};
which is parent of this model: (services_user_prices can override services_prices )
module.exports = function(sequelize, DataTypes) {
return sequelize.define('services_user_prices', {
id: {
type: DataTypes.INTEGER(11),
allowNull: false,
primaryKey: true,
autoIncrement: true
},
user_id: {
type: DataTypes.INTEGER(11),
allowNull: true
},
created_at: {
type: DataTypes.DATE,
allowNull: false
},
currency: {
type: DataTypes.STRING(255),
allowNull: true
},
is_active: {
type: DataTypes.INTEGER(1),
allowNull: true,
defaultValue: '0'
},
is_trial: {
type: DataTypes.INTEGER(1),
allowNull: true,
defaultValue: '0'
},
start_date: {
type: DataTypes.DATE,
allowNull: false
},
end_date: {
type: DataTypes.DATE,
allowNull: true
},
price: {
type: DataTypes.INTEGER(11),
allowNull: true
},
bundle_price_id: {
type: DataTypes.INTEGER(11),
allowNull: true,
references: {
model: 'services_prices',
key: 'id'
}
}
});
};
when trying to join them i get an error:
EagerLoadingError: services_prices is not associated to services_user_prices!
const result= await db.services_user_prices.findOne({
where: { is_active: 1, user_id: 123 }, include:[{db.services_prices}]
});
in the db services_user_prices has foreign key to services_prices table
what am i doing wrong?
Well if you are using sequelize then you need to update your model because
by default, sequelize will be looking for foreign key starts with model name like
you have defined bundle_price_id as a foreign key for services_prices.
You need to change your column name to services_price_id then it will get fixed.
or if you want to use bundle_price_id you need to define it in your model relation as.
Model.belongsTo(models.ModelName, { foreignKey: 'your_key'} )
Please feel free if you need to ask anything else.
As complement of the above answer you need to add an identifier with as: on the association like this:
Model.belongsTo(models.ModelName, { foreignKey: 'your_key', as:'your_identifier' } )
Then when you do the include on the method you also call the identifier:
await db.services_user_prices.findOne({
where: { is_active: 1, user_id: 123 },
include:[{
model: db.services_prices
as: 'your_identifier'
}]
});
If you don't define the foreignKey field, the as field will set the column name.

how can i use limit in include model using sequelize

i want to get user's images at limit 2 from Follow model.
Models
const Follow = connector.define('Follow', {
no: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
follower_id: {
type: Sequelize.INTEGER,
allowNull: true
},
target_id: {
type: Sequelize.INTEGER,
allowNull: true
},
isDelete: {
type: Sequelize.BOOLEAN,
allowNull: false
},
create_dt,
delete_dt
}
const User = connector.define('User', {
no: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
username: {
type: Sequelize.STRING,
allowNull: false
},
email: {
type: Sequelize.STRING,
allowNull: false
},
password: {
type: Sequelize.STRING,
allowNull: false
},
profile_img: {
type: Sequelize.STRING,
allowNull: true
},
bio: {
type: Sequelize.STRING,
allowNull: true
},
phone: {
type: Sequelize.STRING,
allowNull: true
},
gender: {
type: Sequelize.STRING,
allowNull: true
},
website: {
type: Sequelize.STRING,
allowNull: true
},
isDelete: {
type: Sequelize.BOOLEAN,
allowNull: false
},
create_dt,
update_dt,
delete_dt
}
const Image = connector.define('Image', {
no: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
file: {
type: Sequelize.STRING,
allowNull: false
},
location: {
type: Sequelize.STRING,
allowNull: true
},
caption: {
type: Sequelize.STRING,
allowNull: true
},
tags: {
type: Sequelize.STRING,
allowNull: true
},
isDelete: {
type: Sequelize.BOOLEAN,
allowNull: false
},
create_dt,
update_dt,
delete_dt,
user_id: {
type: Sequelize.INTEGER,
allowNull: true
}
}
and, join
User.hasMany(Image, {foreignKey: 'user_id'})
Image.belongsTo(User, {foreignKey: 'user_id'})
User.hasMany(Follow, {foreignKey: 'follower_id'})
Follow.belongsTo(User, {foreignKey: 'follower_id'})
User.hasMany(Follow, {foreignKey: 'target_id'})
Follow.belongsTo(User, {foreignKey: 'target_id'})
so, i tried get user's images from follow by use include.
const followerImages = await Follow.findAll({
attributes: ['target_id'],
where:{
follower_id: loginUser_id
},
include:[
{
model: User,
required: true,
attributes: ['username', 'email', 'profile_img'],
include:[
{
model: Image,
required: true
}
]
}
]
})
but i want to get images at limit 2.
so i tried that
const followerImages = await Follow.findAll({
attributes: ['target_id'],
where:{
follower_id: loginUser_id
},
include:[
{
model: User,
required: true,
attributes: ['username', 'email', 'profile_img'],
include:[
{
model: Image,
required: true,
limit: 2
}
]
}
]
})
but it makes bugs i cant understand.
images field is a array contain empty object at 4.
all same..
what is the problem?
how can i solve this problem??
You can try :
include:[
{
model: Image,
attributes : ['id','user_id','image'] , // <---- don't forget to add foreign key ( user_id )
separate : true, // <--- Run separate query
limit: 2
}
]
Limit causes the issues some time on nested level , so it always safe to run that query separately.

Resources