How to add Sequelize Association into Model - mysql

I am new to Typescript and trying to connect with the Mysql database I have created the following files
User.ts
export const UserData = sequelize.define('users', {
id: {
type:Sequelize.INTEGER,
autoIncrement:true,
allowNull:false,
primaryKey:true
},
name: {
type:Sequelize.STRING,
allowNull:false
},
address: {
type:Sequelize.INTEGER,
allowNull:false
}
});
Address.ts
export const CityData = sequelize.define('city_data', {
id: {
type:Sequelize.INTEGER,
autoIncrement:true,
allowNull:false,
primaryKey:true
},
city: {
type:Sequelize.STRING,
allowNull:false
},
house_no: {
type:Sequelize.INTEGER,
allowNull:false
}});
here I want to add hasMany association on User model user hasMany => address[] How can I achieve that?
what I am looking here how to use sequelize in typescript how to create setup and save data into tables ?
Thank you in advance

users.hasMany(city_data, {
foreignKey: "address",
});
Or
UserData.hasMany(CityData, {
foreignKey: "address",
});
how to add :
const UserData = sequelize.define('users', {
id: {
type:Sequelize.INTEGER,
autoIncrement:true,
allowNull:false,
primaryKey:true
},
name: {
type:Sequelize.STRING,
allowNull:false
},
address: {
type:Sequelize.INTEGER,
allowNull:false
}
});
UserData.hasMany(city_data, {
foreignKey: "address",
});
export UserData;

Related

Express js - how to remove certain field from response

In my current login api, it returns
"user": {
"id": "3e85decc-2af4-436c-8b7f-e276771234f5",
"email": "cccc#cccc.com",
"password": "$xxxxxxxxxx",
"createdAt": "2021-05-14T08:48:31.000Z",
"updatedAt": "2021-05-14T08:48:31.000Z"
},
"token": "xxxxx"
}
I want to remove the password field in my response, so I use delete user.password in my code, but it's not working
/api/users.js
router.post('/login', (req, res, next) => {
passport.authenticate('local', {session: false}, (err, user, info) =>{
if (err || !user) {...}
req.login(user, {session: false}, (err) => {
if (err) {
res.send(err);
}
const token = jwt.sign(user, 'your_jwt_secret');
console.log(user) // show dataValues and _previousDataValues instead of normal JSON object
delete user.password // not working
return res.json({user, token});
});
})(req, res);
});
I tried to log user object for above file, it returns:
users {
dataValues: {
id: '3e85decc-2af4-436c-8b7f-e276771234f5',
email: 'cccc#cccc.com',
password: '$xxxxxxxxxx',
createdAt: 2021-05-14T08:48:31.000Z,
updatedAt: 2021-05-14T08:48:31.000Z
},
_previousDataValues: {
id: '3e85decc-2af4-436c-8b7f-e276771234f5',
email: 'cccc#cccc.com',
password: '$xxxxxxxxxx',
createdAt: 2021-05-14T08:48:31.000Z,
updatedAt: 2021-05-14T08:48:31.000Z
},
_changed: Set(0) {},
_options: {
isNewRecord: false,
_schema: null,
_schemaDelimiter: '',
raw: true,
attributes: [ 'id', 'email', 'password', 'createdAt', 'updatedAt' ]
},
isNewRecord: false
}
This is my user model. I am using Sequelize.
const Sequelize = require('sequelize');
const DataTypes = Sequelize.DataTypes;
const db = require('../sequelize')
let users = db.define('users', {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
allowNull: false,
primaryKey: true
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: 'email'
},
password: {
type: DataTypes.STRING,
},
},
{
hooks: {
beforeCount(options) {
options.raw = false;
}
}
}
);
module.exports = users;
Finally solved it using user.get({plain: true})
let plainUser = user.get({plain: true})
delete plainUser['password']
return res.json({user, token});
It's probably not a good idea to delete properties from the Model directly. Try using ToJSON() to convert the Model to a plain Javascript object and delete the password from that.
plainUser = user.ToJSON();
delete plainUser.password
why dont you re-create your result response, something like this:
let response = {
"user": {
"id": user.dataValues.id,
"email": user.dataValues.email,
"createdAt": user.dataValues.createdAt,
"updatedAt": user.dataValues.updatedAt
},
"token": "xxxxx"
}
JSON.stringify(response)
Try below code in your model to override the sequelize toJSON function
const User = db.define('users', {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
allowNull: false,
primaryKey: true
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: 'email'
},
password: {
type: DataTypes.STRING,
},
},
{
hooks: {
beforeCount(options) {
options.raw = false;
}
}
}
);
User.prototype.toJSON = function () {
const values = Object.assign({}, this.get());
delete values.password;
return values;
};
or using omit() withlodash for cleaner code
User.prototype.toJSON = function () {
const values = {
..._.omit(this.get(), ['password'])
};
return values;
};

date_format with sequelize mysql

I am using sequelize for my backend and I want to add a where condition with YYYY-mm-dd
In mysql we use date_format(dateCreated, "%d-%m-%Y").
But how to achieve it in Sequelize. I searched all over the google but nothing helped me out
My present Sequelize query. I want to get data of dateCreated = '2020-05-31'.
const apartmentOrdersData = await apartments_order.findAll(
{
where: { apid: req.body.apid }, group: ['apcid'],
attributes: ['apcid', [sequelize.fn('sum', sequelize.col('totalCost')), 'total_amount'],],
include: [apartments_child]
});
My model:
const { DataTypes, Model } = require('sequelize');
const sequelize = require('../../../mysql_connection/sequilize');
const admins = require('./admins');
const apartments_child = require('./apartments_child');
class apartments_order extends Model { }
apartments_order.init({
// Model attributes are defined here
apoid: {
type: DataTypes.INTEGER,
primaryKey: true
},
invoiceNo: {
type: DataTypes.STRING
},
apid: {
type: DataTypes.INTEGER
},
apcid: {
type: DataTypes.INTEGER
},
apcbid: {
type: DataTypes.INTEGER
},
totalCost: {
type: DataTypes.DECIMAL
},
dateCreated: {
type: DataTypes.DATE
},
dateUpdated: {
type: DataTypes.DATE
},
createdBy: {
type: DataTypes.STRING
},
updatedBy: {
type: DataTypes.STRING
},
status: {
type: DataTypes.STRING
}
}, {
sequelize,
timestamps: false,
logging: false,
tableName: 'apartments_order'
});
apartments_order.hasOne(admins, { foreignKey: 'aid', sourceKey: 'createdBy' });
apartments_order.hasOne(apartments_child, { foreignKey: 'apcid', sourceKey: 'apcid' });
module.exports = apartments_order;
One thing that you can do is use a setter and getter for the columns.
Follow an example (on your field declaration, you can manipulate the data inside getter() and setter():
dateUpdated: {
type: Sequelize.STRING,
defaultValue: '[]',
get() {
const d = this.getDataValue('dateUpdated');
return format(d, 'Y-m-d');
},
set(value) {
return this.setDataValue('dateUpdated', format(value, <your-format-here>)
},
type: DataTypes.DATE,
},

GraphQL - operating elements of array

I would like to display some information about members, but I don't know how to resolve array of field 'time'. This is array, because it shows their login time. What should I do?
I used GraphQLString, but I am aware of this bad solution.
So I'm getting an error:
"message": "String cannot represent value: [\"12:08\"]",
Here is schema.js
const axios = require("axios");
const {
GraphQLObjectType,
GraphQLString,
GraphQLList,
GraphQLSchema
} = require("graphql");
const memberType = new GraphQLObjectType({
name: "Member",
fields: () => ({
nick: {
type: GraphQLString
},
name_and_surname: {
type: GraphQLString
},
time: {
type: GraphQLString
}
})
});
//Root Query
const RootQuery = new GraphQLObjectType({
name: "RootQueryType",
fields: {
users: {
type: new GraphQLList(memberType),
description: "List of members",
resolve(parent, args) {
return axios
.get("http://25.98.140.121:5000/data")
.then(res => res.data);
}
}
}
})
module.exports = new GraphQLSchema({
query: RootQuery
});
And here is JSON
[
{
"time": [
"12:08"
],
"nick": "Cogi12",
"name_and_surname: "John Steps"
},
{
"time": [
"12:16"
],
"nick": "haris22",
"name_and_surname": "Kenny Jobs"
},
{
"time": [
"12:07",
"12:08",
"12:17",
"12:19",
"12:45",
"13:25"
],
"nick": "Wonski",
"name_and_surname": "Mathew Oxford"
}
]
you can use GraphQLList along with GraphQLString for time type like this,
const memberType = new GraphQLObjectType({
name: "Member",
fields: () => ({
nick: {
type: GraphQLString
},
name_and_surname: {
type: GraphQLString
},
time: {
type: new GraphQLList(GraphQLString)
}
})
});

Sequelize association cant work on my code,please

im recently to sequelize.
I have 2 table, data_track and car_detail. i want to try associate that 2 table but it never associated.
it's always return error
SequelizeEagerLoadingError: car_detail is not associated to data_track!
please help me
both table have same primary key column name
data_track.js
const Sequelize = require('sequelize')
const gps_status_track = require("./../../configs/gps_status_track")
const data_track = gps_status_track.define('data_track',
{
car_id:{
type:Sequelize.INTEGER,
primaryKey:true
},
off_time:{
type:Sequelize.INTEGER,
},
nopol:{
type:Sequelize.STRING
},
wilayah:{
type:Sequelize.STRING
},
status:{
type:Sequelize.STRING
},
o_path:{
type:Sequelize.STRING
},
keterangan:{
type:Sequelize.STRING
},
last_update:{
type:"TIMESTAMP"
},
},
{
createdAt:'created_at',
updatedAt:'updated_at',
deletedAt:'deleted_at',
freezeTableName: true,
}
)
data_track.associate = (models)=>{
data_track.belongsTo(models.car_detail,{foreignKey:'car_id',as:'dataTrack'})
}
module.exports = data_track
car_detail.js
const Sequelize = require('sequelize')
const gps_status_track = require("./../../configs/gps_status_track")
const car_detail = gps_status_track.define('car_detail',
{
car_id:{
type:Sequelize.INTEGER,
primaryKey:true
},
nopol:{
type:Sequelize.STRING
},
wilayah:{
type:Sequelize.STRING
},
o_path:{
type:Sequelize.STRING
},
},
{
createdAt:'created_at',
updatedAt:'updated_at',
deletedAt:'deleted_at',
freezeTableName: true,
}
)
car_detail.associate = (models)=>{
car_detail.hasOne(models.data_track,{foreignKey:'car_id',as:'carDetail'})
}
module.exports = car_detail
Thanks!
Try doing it this way:
DataTrack.js:
module.exports = (sequelize, Sequelize) => {
const DataTrack = sequelize.define('data_track',
{
car_id: {
type: Sequelize.INTEGER,
primaryKey: true
},
off_time: {
type: Sequelize.INTEGER,
},
nopol: {
type: Sequelize.STRING
},
wilayah: {
type: Sequelize.STRING
},
status: {
type: Sequelize.STRING
},
o_path: {
type: Sequelize.STRING
},
keterangan: {
type: Sequelize.STRING
},
last_update: {
type: "TIMESTAMP"
},
},
{
createdAt: 'created_at',
updatedAt: 'updated_at',
deletedAt: 'deleted_at',
freezeTableName: true,
});
return DataTrack;
}
CarDetail.js:
module.exports = (sequelize, Sequelize) => {
const CarDetail = sequelize.define('car_detail',
{
car_id: {
type: Sequelize.INTEGER,
primaryKey: true
},
nopol: {
type: Sequelize.STRING
},
wilayah: {
type: Sequelize.STRING
},
o_path: {
type: Sequelize.STRING
},
},
{
createdAt: 'created_at',
updatedAt: 'updated_at',
deletedAt: 'deleted_at',
freezeTableName: true,
}
);
return CarDetail;
}
db.config.js:
const env = require('./env.js')
const Sequelize = require('sequelize')
const sequelize = new Sequelize(env.database, env.username, env.password, {
host: env.host,
dialect: env.dialect
})
const db = {}
db.Sequelize = Sequelize
db.sequelize = sequelize
db.data_track = require('../models/DataTrack')(sequelize, Sequelize)
db.car_detail = require('../models/CarDetail')(sequelize, Sequelize)
db.car_detail.hasOne(db.data_track, { foreignKey: { name: 'cars_id', allowNull: false } })
db.data_track.belongsTo(db.car_detail, { foreignKey: { name: 'cars_id', allowNull: false } })
module.exports = db
You're defining association is not correct.
car_detail.hasOne(models.data_track,{foreignKey:'carIDFK', sourceKey: 'cardDetailPKId', as:'carDetail'})
In the data track model, the association will look like.
data_track.belongsTo(models.car_detail,{foreignKey:'carIDFK', targetKey: 'cardDetailTablePKId'})

Error with sequelize many to many association using Field attribute

I'm using sequelize v3.11.0 and sails v0.11.0 using MySQL DB.
I have my models/User.js
module.exports = {
attributes: {
firstName: {
type: Sequelize.STRING,
allowNull: false,
field:'first_name'
},
lastName: {
type: Sequelize.STRING,
field:'last_name'
},
phone: {
type: Sequelize.STRING
}
}
}
model/Category.js
module.exports = {
attributes: {
name: {
type: Sequelize.STRING,
allowNull:false,
unique:true,
},
description: {
type: Sequelize.STRING
}
}
}
model/UsersCategory.js
module.exports = {
attributes: { },
options: {
tableName: 'user_categories'
},
associations: function() {
User.belongsToMany(Category, {
through: UsersCategory,
foreignKey: {
name:'userId',
field:'user_id'
}
});
Category.belongsToMany(User, {
through: UsersCategory,
foreignKey: {
name:'categoryId',
field:'category_id'
}
});
}
};
But when I'm executing this code In my database user_categories table I'm geting the attribute as:
category_id , userId
I'm not getting that why userId in camelcase.
when I'm doing:
User.findAll({
include: [
{all:true}
]
})
I'm getting error:
"ER_BAD_FIELD_ERROR: Unknown column 'Categories.UsersCategory.user_id' in 'on clause'"
But If I user userId and CategoryId in my UserCategory model then It working Fine.
Is there is some problem with the Field in many to many association?