Define Sequelize model such as all inserted entries should be in lowercase - mysql

I need to insert first_name and last_name in a lower case using sequelize and NodeJS.
How do I define a model where all entries should be in lower case?
const Users = sequelize.define('users', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
},
mobile : {
type: Sequelize.STRING,
}
first_name: {
type: Sequelize.STRING,
},
last_name :{
type: Sequelize.STRING,
},
email :{
type: Sequelize.STRING,
}
},
{
freezeTableName: true // Model tableName will be the same as the model name
},
{
where: {
$and: [
sequelize.where(sequelize.fn('lower', sequelize.col('first_name'))),
sequelize.where(sequelize.fn('lower', sequelize.col('last_name')))
]
}
}
);

What you're looking for is beforeCreate() sequelize hook:
const Users = sequelize.define('users', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
},
mobile : {
type: Sequelize.STRING,
}
first_name: {
type: Sequelize.STRING,
},
last_name :{
type: Sequelize.STRING,
},
email :{
type: Sequelize.STRING,
}
},
{
freezeTableName: true
},
hooks: {
beforeCreate: function(user){
user.first_name = user.first_name.toLowerCase();
user.last_name = user.last_name.toLowerCase();
return user;
}
}
);

Related

How to define in my model an array of id from another table in mysql and sequelize

I create an api in express.js, node.js, mysql and sequelize.
I have two models : Custom fields and Customer Types
Here is my customer type model :
module.exports = (sequelize, DataTypes) => {
const CustomerType = sequelize.define("customerType", {
name: {
type: DataTypes.STRING,
allowNull: false
},
description: {
type: DataTypes.STRING,
allowNull: false
},
user_id: {
type: DataTypes.STRING,
allowNull: false
}
})
return CustomerType
}
And there is my custom fields model :
const customerType = require('./customerTypeModel')
module.exports = (sequelize, DataTypes) => {
const CustomField = sequelize.define("customField", {
customer_type_ids: [
{
type: DataTypes.INTEGER,
references: {
model: customerType,
key: "id"
}
}
],
user_id: {
type: DataTypes.STRING,
allowNull: false
},
system_name: {
type: DataTypes.STRING,
allowNull: true
},
title: {
type: DataTypes.STRING,
allowNull: true
},
type: {
type: DataTypes.STRING,
allowNull: true
},
required: {
type: DataTypes.BOOLEAN,
allowNull: true
},
})
return CustomField
}
I need to have in my customField table an array of id from the customerType table.
For exemple i need to get a json like this :
{
"id": 1
"customer_types_ids": [
{
"id": 1,
"name": "Customers",
"description": "Customers",
"user_id": "123456"
},
{
"id": 2,
"name": "Leads",
"description": "Leads",
"user_id": "123456"
}
],
"user_id": "123456",
"system_name": "firstname",
"title": "Firstname",
"type": "text",
"required": true
}
How should I structure my custom field Model to be able to have a json like this in return?
Thanks for your help !
I assume you're expecting a One-to-Many relationship between CustomField and CustomerType. In this case, CustomerType owns the relation, so there is a reference to CustomField in the relational table of CustomerType called customFieldId.
// customerType.js
module.exports = (sequelize, DataTypes) => {
const CustomerType = sequelize.define("customerType", {
name: {
type: DataTypes.STRING,
allowNull: false
},
description: {
type: DataTypes.STRING,
allowNull: false
},
user_id: {
type: DataTypes.STRING,
allowNull: false
}
});
return CustomerType;
}
// customField.js
module.exports = (sequelize, DataTypes) => {
const CustomField = sequelize.define("customField", {
user_id: {
type: DataTypes.STRING,
allowNull: false
},
system_name: {
type: DataTypes.STRING,
allowNull: true
},
title: {
type: DataTypes.STRING,
allowNull: true
},
type: {
type: DataTypes.STRING,
allowNull: true
},
required: {
type: DataTypes.BOOLEAN,
allowNull: true
},
});
return CustomField;
}
// db.js
...
const CustomerType = require("./customerType.js")(sequelize, Sequelize.DataTypes);
const CustomField = require("./customField.js")(sequelize, Sequelize.DataTypes);
CustomField.hasMany(CustomerType, { as: "customer_types_ids" });
CustomerType.belongsTo(CustomField, {
foreignKey: "id",
as: "customFieldId",
});
This should define two relational tables with a One-to-Many relationship. The following code can be used to load a CustomField with all its CustomerTypes.
CustomField.findByPk(id, { include: ["customer_types_ids"] });

Sequelize Eager Loading Error: social_logins not associated to users

Users Model defined like this.
const db = require ('../../config/db_config');
const users = db.sequelize.define('users', {
id: {
type: db.DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
first_name: {
type: db.DataTypes.STRING(150),
},
last_name: {
type: db.DataTypes.STRING(150),
},
email: {
type: db.DataTypes.STRING(256),
required: true,
unique: true
},
password: {
type: db.DataTypes.STRING,
},
student_id: {
type: db.DataTypes.STRING
},
status: {
type: db.DataTypes.BOOLEAN,
required: true,
defaultValue: 0
},
is_deleted: {
type: db.DataTypes.BOOLEAN,
required: true,
defaultValue: 0
},
createdAt: db.DataTypes.DATE,
updatedAt: db.DataTypes.DATE,
});
module.exports = users;
social_logins Model defined like this
const db = require ('../../config/db_config');
const socialLogins = db.sequelize.define('social_logins', {
id: {
type: db.DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
token: {
type: db.DataTypes.STRING
},
tokenType: {
type: db.DataTypes.STRING
},
fb_id: {
type: db.DataTypes.STRING
},
user_id: {
type: db.DataTypes.INTEGER
},
is_deleted: {
type: db.DataTypes.BOOLEAN,
required: true,
defaultValue: false
}
}, { underscored: true, timestamp: true, tableName: 'social_logins' });
module.exports = socialLogins;
User model associated with the social_logins model using belongsTo function
socialLoginsModel.belongsTo(users)
Sequelize throws eagerLoadingError
Error EagerLoadingError [SequelizeEagerLoadingError]: social_logins is
not associated to users!
While running this query given below.
const userModel = require ('./users_model');
const socialLoginModel = require('../social_logins/social_logins_model');
let id = "123456";
let email = "ex#example.com";
userModel.findOne({
where: { email },
include: [{
model: socialLogins,
where: {
fb_id: id
}
}]
});
you should have associations like this based on your model names
socialLogins.belongsTo(users) & users.hasOne(socialLogins)/ users.hasMany(socialLogins) based on your relations being defined in DB

Node.js Sequelize virtual column pulling value from other model

I'm working with Sequelize 5.7, trying to utilize virtual datatype,
to pull related information into a model.
Given simplified company and user models, how do I get company.name
into user.companyname ?
company
let Schema = sequelize.define(
"company",
{
id: {
type: DataTypes.INTEGER.UNSIGNED,
autoIncrement: true,
primaryKey: true
},
name: {
type: DataTypes.STRING(45)
}
}
);
user
let Schema = sequelize.define(
"user",
{
id: {
type: DataTypes.INTEGER.UNSIGNED,
autoIncrement: true,
primaryKey: true
},
login: {
type: DataTypes.STRING(45),
unique: true
},
company: {
type: DataTypes.INTEGER.UNSIGNED,
references: {
model: sequelize.model('company'),
key: 'id'
}
},
/* This companyname contruct is pure fantasy, and the target of my question */
companyname: {
type: new DataTypes.VIRTUAL(DataTypes.STRING,['company']),
references: {
model: 'company',
key: 'name'
}
}
}
);
In your case, I think it is a better idea to use a relationship (an association)
Sequelize Associations
const User = sequelize.define('user', {
id: {
type: DataTypes.INTEGER.UNSIGNED,
autoIncrement: true,
primaryKey: true
},
login: {
type: DataTypes.STRING(45),
unique: true
},
company_id: {
type: DataTypes.INTEGER.UNSIGNED,
},
});
const Company = sequelize.define('company', {
id: {
type: DataTypes.INTEGER.UNSIGNED,
autoIncrement: true,
primaryKey: true,
},
name: {
type: DataTypes.STRING,
},
});
User.belongsTo(Company, {
foreignKey: 'company_id', // you can use this to customize the fk, default would be like companyId
});
Company.hasMany(User);
Then when calling your model you do something like:
User.findAll({ include: Company }).then(users => console.log(users));
I solved the problem by using type: DataTypes.VIRTUAL in model
const { Model, DataTypes } = require('sequelize');
class User extends Model {
static init(sequelize) {
super.init({
id: {
type: DataTypes.INTEGER.UNSIGNED,
autoIncrement: true,
primaryKey: true
},
login: {
type: DataTypes.STRING(45),
unique: true
},
company_id: {
type: DataTypes.INTEGER.UNSIGNED,
},
companyname:{
type: DataTypes.VIRTUAL,
get() {
return this.Company?.get().name;
},
set(/*value*/) {
throw new Error('Do not try to set the `companyname` value!');
}
},
}, {
sequelize
})
}
static associate(models) {
this.belongsTo(Company, {
foreignKey: 'company_id',
});
}
}
module.exports = User;
to search just include the association :
User.findAll({ include: Company })
I usually create each model using 'class' in different files, but if you need, just include the code below in the #jalex19 solution
companyname:{
type: DataTypes.VIRTUAL,
get() {
return this.Company?.get().name;
},
set(/*value*/) {
throw new Error('Do not try to set the `fullName` value!');
}
},

Can i use `SET` variable in sequelize in nodejs

Can i use SET variable in sequelize in nodejs?
Sequelize
Model
Session Model
"use strict";
module.exports = (sequelize, DataTypes) => {
const Sessions = sequelize.define(
"sessions",
{
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
challenge_id: {
type: DataTypes.INTEGER,
references: {
model: "challenges",
key: "id"
},
allowNull: false
},
createdAt: { type: DataTypes.DATE },
createdBy: {
type: DataTypes.INTEGER,
references: {
model: "users",
key: "id"
},
allowNull: false
},
showAtLeaderboard: { type: DataTypes.ENUM("yes", "no") },
sessionFile: { type: DataTypes.STRING },
score: { type: DataTypes.INTEGER },
},
{
timestamps: false,
underscored: true
}
);
return Sessions;
};
Challenge Model
"use strict";
module.exports = (sequelize, DataTypes) => {
const Challenges = sequelize.define(
"challenges",
{
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
song_id: { type: DataTypes.INTEGER },
challenge_name: { type: DataTypes.STRING },
challengeDescription: { type: DataTypes.STRING },
challengeImg: { type: DataTypes.STRING },
challengeType: { type: DataTypes.STRING },
coins: { type: DataTypes.INTEGER },
createdAt: { type: DataTypes.DATE },
expireAt: { type: DataTypes.DATE },
isActive: { type: DataTypes.ENUM("yes", "no") },
tags: { type: DataTypes.STRING }
},
{
timestamps: false,
underscored: true
}
);
return Challenges;
};
Relationship
db.challenges.hasMany(db.sessions, {
foreignKey: "challenge_id",
sourceKey: "id"
});
Can I perform below SQL query with sequelize Orm model?
SET #rank=0
SELECT `challenges`.`*`, `sessions`.*, #rank:=#rank+1 AS rank FROM `challenges` JOIN `sessions` ON `sessions`.`challenge_id` = `challenges`.`id` ORDER BY `sessions`.`score` DESC
Sequelize support this type of query with it's ORM Model.

Performing FULLTEXT search after JOIN operation in sequelize

I have two tables Category and Events and I want to perform a FULLTEXT search on the columns Events.Name,Description,Society and Category.Name after performing a join operation on both the tables in sequelize.
The modals have been defined as follows:
Events.js
(function () {
'use strict';
module.exports = function(sequelize, DataTypes) {
var Events = sequelize.define("Events", { //Must be same as table name
Id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true // Automatically gets converted to SERIAL for postgres
},
Name: {
type: DataTypes.STRING,
notNull: true
},
Description: {
type: DataTypes.STRING,
notNull: true
},
Venue: {
type: DataTypes.STRING,
notNull: true
},
StartTime: {
type: DataTypes.STRING,
notNull: true
},
EndTime: {
type: DataTypes.STRING,
notNull: true
},
StartDate: {
type: DataTypes.STRING,
notNull: true
},
EndDate: {
type: DataTypes.STRING,
notNull: true
},
CurrentRound: {
type: DataTypes.STRING,
notNull: true
},
Society: {
type: DataTypes.STRING,
notNull: true
},
CategoryId: {
type: DataTypes.INTEGER,
notNull: true
},
MaxContestants: {
type: DataTypes.INTEGER,
notNull: true
},
Status: {
type: DataTypes.STRING,
notNull: true
},
Pdf: {
type: DataTypes.STRING,
notNull: true
}
}, {
timestamps: false,
tableName: 'Events',
freezeTableName: true
}, {
indexes: [
{ type: 'FULLTEXT', fields: 'name' }
]
},{
classMethods: {
associate: function(models) {
Events.belongsTo(models.Category);
}
}
});
return Events;
};
}());
Category.js
module.exports = function(sequelize, DataTypes) {
var Category = sequelize.define("Category", {
Id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true // Automatically gets converted to SERIAL for postgres
},
Name: DataTypes.STRING
}, {
timestamps: false,
tableName: 'Category',
freezeTableName: true
},{
Indexes: [
{ type: 'FULLTEXT', fields: ['Name'] }
]
}, {
classMethods: {
associate: function(models) {
Category.hasMany(models.Events);
}
}
});
return Category;
};
The query I am performing is :
Model.Events.findAll({
include: [{ model: Model.Category }],having: ['MATCH(Events.Name,Description,Society,Category.Name) AGAINST(?)', query] }).then(function(data) {
console.log(JSON.stringify(data));
r.status = statusCodes.SUCCESS;
r.data = JSON.stringify(data);
return res.end(r.toString());
}).catch(function(err){
console.log(err);
r.status = statusCodes.SERVER_ERROR;
r.data = err;
return res.end(r.toString());
});
The errors I am getting are :
FULLTEXT index does not exits.
Incorrect arguments to the match.
I am not sure if a foreign key has been created.
Please help me out by correcting my query.