(Sequelize+Postgres+NodeJS) Inster FK (userID) from another table - node.js

I'm using Sequelize connected to PostgreSQL and as I want to use sync function I would like to prepare valid models to create tables on every environment.
EDIT:
Wallet:
'use strict';
module.exports = function(db, DataTypes) {
var Wallet = db.define('Wallet', {
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true
},
money: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 0
}
createdAt: DataTypes.DATE,
updatedAt: DataTypes.DATE
}, {
tableName: 'wallet',
classMethods:{
associate : function( models ) {
Wallet.belongsTo( models.User,{ foreignKey : 'id_user'});
}
}
});
return Wallet;
};
User:
'use strict';
var bcrypt = require('bcrypt-nodejs');
var crypto = require('crypto');
var moment = require('moment');
var models = require('./');
var afterCreateHook = function(user, options, fn) {
models.Wallet.build({id_user: user.id}).save();
fn(null, user);
};
module.exports = function(db, DataTypes) {
var User = db.define('User', {
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true
},
password: DataTypes.STRING,
email: {
type: DataTypes.STRING,
unique: true,
allowNull: false,
isEmail: true
},
login: {
type: DataTypes.STRING,
unique: true,
allowNull: false
}
}, {
tableName: 'pl_users',
instanceMethods: instanceMethods,
classMethods: {
associate : function( models ) {
User.hasOne( models.Wallet);
}
},
hooks: {
afterCreate: afterCreateHook
}
});
return User;
};
Why
models.Wallet.build({id_user: user.id}).save();
is not working? Account is creating and then I want to create wallet with specific user_id. I don't have even an error...
Help please!

You should check relations from sequelize docs
In your case youu need to define:
Wallet.belongsTo(User,{foreignKey: 'id_user'});
This will add id_user to Wallet model , so you dont need to specify id_user attribute in your WalletModel.
If you are using sequelize import function , you should add the relation in "associate" class method like this:
module.exports = function(db, DataTypes) {
var Wallet = db.define('Wallet', {
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true
},
pin: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 0
},
money: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: 0
},
createdAt: DataTypes.DATE,
updatedAt: DataTypes.DATE
}, {
tableName: 'Wallet',
classMethods:{
associate : function( models ) {
Wallet.belongsTo( models.User,{ foreignKey : 'id_user'});
}
}
});

Related

How to make sequelize model seperate file but same sequelize connection

everyone. I'm very new for sequelize ORM with nodejs.
I've just created couple files for models seperately and I also seperate sequelize.js to connect to database.
The problem is when I make association between model(file)(Self Associate work well) and I've got an error
**** "hasMany called with something that's not a subclass of Sequelize.Model"
I tried to solved this but doesn't work until I put every model in the same file. So, I realized that every model must use common sequelize connection.
Is there anyways to solve this problem without sequelize-cli (I don't want to use sequelize-cli)
My code belows
Many thanks,
sequelize.js
const config = require("config");
const { Sequelize } = require("sequelize");
const sequelize = new Sequelize(
config.get("database"),
config.get("user"),
config.get("cipher"),
{
dialect: "mariadb",
timezone: "Asia/Bangkok",
}
);
module.exports = sequelize;
user.js
const { DataTypes, Model } = require("sequelize");
const sequelize = require("./sequelize");
const Position = require("./position");
class User extends Model {}
User.init(
{
uuid: {
type: DataTypes.UUID,
allowNull: false,
defaultValue: DataTypes.UUIDV4,
},
title: {
type: DataTypes.STRING,
allowNull: false,
},
firstname: {
type: DataTypes.STRING,
allowNull: false,
},
lastname: {
type: DataTypes.STRING,
allowNull: false,
},
phone: {
type: DataTypes.STRING,
allowNull: true,
},
email: {
type: DataTypes.STRING,
allowNull: true,
validate: {
isEmail: true,
},
},
imgurl: {
type: DataTypes.STRING,
allowNull: true,
},
login: {
type: DataTypes.STRING,
allowNull: false,
},
passphase: {
type: DataTypes.STRING,
allowNull: false,
},
status: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 1,
},
},
{
sequelize,
modelName: "User",
tableName: "users",
timestamps: true,
}
);
User.belongsToMany(User, {
as: "CreatedUser",
foreignKey: "user_id",
through: "UserCreator",
});
User.belongsToMany(User, {
as: "Creator",
foreignKey: "creator_id",
through: "UserCreator",
});
User.belongsToMany(User, {
as: "ModifiedUser",
foreignKey: "user_id",
through: "UserModifier",
});
User.belongsToMany(User, {
as: "Modifier",
foreignKey: "modifier_id",
through: "UserModifier",
});
User.belongsTo(Position);
module.exports = User;
position.js
const { DataTypes, Model } = require("sequelize");
const sequelize = require("./sequelize");
const User = require("./user");
class Position extends Model {}
Position.init(
{
uuid: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
},
name: {
type: DataTypes.STRING,
allowNull: false,
},
status: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 1,
},
},
{
sequelize,
modelName: "Position",
tableName: "postions",
timestamps: true,
}
);
Position.hasMany(User, {
foreignKey: {
type: DataTypes.UUIDV4,
allowNull: false,
},
});
module.exports = Position;
Sequelize has a .define() method to create all your schemas in JSON. If you want to keep your connection to the database separate from your models, I suggest doing something like this
./models/schemas/User.js
const userSchema = {
attribute1: {
type: ...,
option1: ...,
option2: ...,
.
.
},
.
.
}
export default userSchema
Do the same with Position.js
Then:
./models/models.js
import {sequelize} from 'path/to/sequelize.js'
import positionSchema from './schemas/Position.js'
import userSchema from './schemas/User.js'
const User = sequelize.define("user", userSchema, { freezeTableName: true });
const Position = sequelize.define("position", positionSchema, { freezeTableName: true });
// add associations
export {
User,
Position,
.
.
}

User is not associated to Temperature. Sequelize Eager loading error

In my application every user can record many temperatures, but one temperature record should have only one user. I am trying to execute the following code and facing an 'User is not associated with Temperature' Error. Please review my code below and let me know where i have gone wrong.
This is my User model
const { Sequelize, DataTypes, Model } = require('sequelize');
const sequelize = require('../connection');
var Temperature = require('./temperature');
var User = sequelize.define('User', {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
primaryKey: true,
},
firstName: {
type: DataTypes.STRING,
allowNull: false
},
lastName: {
type: DataTypes.STRING,
allowNull: false
},
email: {
type: DataTypes.STRING,
allowNull: false
},
password: {
type: DataTypes.STRING,
allowNull: false
},
status: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: 'Active'
},
role: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: 'Admin'
}
});
User.associate = (models) => {
User.hasMany(models.Temperature, { as: 'temperatures' })
}
module.exports = User;
This is my Temperature model
const { Sequelize, DataTypes, Model } = require('sequelize');
const sequelize = require('../connection');
const User = require('./users');
var Temperature = sequelize.define('Temperature', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
userId: {
type: DataTypes.INTEGER,
allowNull: false,
},
temperature: {
type: DataTypes.FLOAT,
allowNull: false
},
recordDateTime: {
type: DataTypes.DATE,
allowNull: false
}
});
Temperature.associate = (models) => {
Temperature.belongsTo(models.User, { foreignKey: 'userId', as: 'user' })
}
module.exports = Temperature;
I am getting error in running the following code
Temperature.findAll({ include: User, raw:true})
.then((res)=>{
console.log(res);
})
Can you anyone please help in figuring out this issue.
The associate functions in both the models are not executing.
you don't need to add userId column into Temperature model schema, just define associations as you have already did and even if you want to add userId column in model schema the do it like below but must add it in migration file of your Temperature model schema like below
userId: {
type: Sequelize.INTEGER,
allowNull: false,
references: {
model: 'Users', // <----- name of the table
key: 'id' // <----- primary key
}
}

sequelize association N:M Table and 1:N Table

I am using sequelize, mysql for node.js!
Have a question and post it.
First, to create a review table with N: M relationship between user table and store table!
Please refer to the ReviewImage Table, which is a 1: N relationship with the Review Table.
For synchronization, please refer to the Review Table and ReviewImage Table.
I don't know what the problem is even if I browse the sequelize API documentation!
Have you ever done the wrong database design?
Should I design a review image table?
const Sequelize = require('sequelize');
const env = process.env.NODE_ENV || 'development';
const config = require('../config/config')[env];
const db = {};
const sequelize = new Sequelize(
config.database, config.username, config.password, config);
db.sequelize = sequelize;
db.Sequelize = Sequelize;
db.User = require('./UserModel')(sequelize, Sequelize);
db.Store = require('./StoreModel')(sequelize, Sequelize);
db.Review = require('./reviewModel')(sequelize, Sequelize);
db.ImageReview = require('./imageReviewModel')(sequelize, Sequelize);
/** N:M User : Store (Review) */
db.User.belongsToMany(db.Store, { through: db.Review});
db.Store.belongsToMany(db.User, { through: db.Review});
/** 1:N review : imageReview */
db.Review.hasMany(db.ImageReview);
db.ImageReview.belongsTo(db.Review);
module.exports = db;
// userModel.js
module.exports = (sequelize, DataTypes) => {
return sequelize.define('User',{
userPlatformType:{
type: DataTypes.STRING(50),
},
userNickname:{
type: DataTypes.STRING(50),
allowNull: false,
unique : true,
},
customerEmail: {
type: DataTypes.STRING(100),
allowNull: false,
unique: true,
},
userPassword:{
type: DataTypes.STRING(200),
allowNull: false,
},
salt:{
type: DataTypes.STRING(200),
},
userPhoneNumber:{
type: DataTypes.STRING(45),
},
userDateOfBirth:{
type: DataTypes.DATEONLY,
},
userWeddingDay:{
type: DataTypes.DATEONLY,
},
userProfile: {
type: DataTypes.STRING(200),
allowNull: true,
},
}, {
freezeTableName: true,
});
};
// storeModel.js
module.exports = (sequelize, DataTypes) => {
return sequelize.define('Store',{
storeName:{
type: DataTypes.STRING(50),
},
storeCategory: {
type: DataTypes.STRING(100),
allowNull: false,
unique: true,
},
storeAddress:{
type: DataTypes.STRING(150),
allowNull: false,
unique : true,
},
storeLatitude:{
type: DataTypes.STRING(45),
},
storeLongtitude:{
type: DataTypes.STRING(45),
},
storeCondition: {
type: DataTypes.STRING(200),
allowNull: false,
},
storePhoneNumber:{
type: DataTypes.STRING(200),
allowNull: false,
},
storeProfile:{
type: DataTypes.STRING(200),
},
storeWifi:{
type: DataTypes.STRING(45),
},
storePost:{
type: DataTypes.STRING(100),
},
storeItem:{
type: DataTypes.STRING(100),
},
storeIntro:{
type: DataTypes.STRING(100),
},
storeLike: {
type: DataTypes.INTEGER,
defaultValue: 0,
},
storeRating: {
type: DataTypes.INTEGER,
defaultValue: 0,
},
storeIsJoin: {
type: DataTypes.BOOLEAN,
defaultValue: false,
},
}, {
freezeTableName: true,
});
};
//ReviewModel.js
module.exports = (sequelize, DataTypes) => {
return sequelize.define('Review',{
reviewWriter :{
type: DataTypes.STRING(50),
allowNull: false,
},
reviewContent :{
type: DataTypes.STRING(200),
allowNull: false,
},
reviewGrade : {
type: DataTypes.INTEGER,
allowNull: false,
},
reviewIsDeclare : {
type: DataTypes.BOOLEAN,
allowNull: false,
},
}, {
freezeTableName: true,
});
};
//ReviewImage.js
module.exports = (sequelize, DataTypes) => {
return sequelize.define('ImageReview',{
reviewImageUrl :{
type: DataTypes.STRING(200),
allowNull: false,
},
}, {
freezeTableName: true,
});
};

Cannot read property 'menu_id' of undefined

I tried to create database with 3 tables: restaurant,restaurant_menu,menu and their relationship is restaurant have many menu and menu can belong to many restarant by sequelize in Nodejs.
restaurant.model.js
'use strict';
module.exports = (sequelize, DataTypes) => {
const restaurant = sequelize.define('restaurant', {
id: {
type: DataTypes.INTEGER,
allowNull: false,
autoIncrement: true,
primaryKey: true
},
name: DataTypes.STRING,
address: DataTypes.STRING,
phone: DataTypes.STRING,
lat: {
type: DataTypes.DOUBLE,
allowNull: false,
defaultValue: 0
},
lng: {
type: DataTypes.DOUBLE,
allowNull: false,
defaultValue: 0
},
user_owner: {
type: DataTypes.INTEGER,
defaultValue: 0
},
image: {
type: DataTypes.TEXT,
allowNull: false
},
payment_url: {
type: DataTypes.TEXT,
allowNull: false
}
}, {
freezeTableName: true,
timestamps: false
});
restaurant.associate = function (models) {
// associations can be defined here
restaurant.belongsToMany(models.menu, {
through: {
model: models.restaurant_menu
},
foreignKey: 'restaurant_id'
})
};
return restaurant;
};
menu.model.js
'use strict';
module.exports = (sequelize, DataTypes) => {
const menu = sequelize.define('menu', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
allowNull: false
},
name: DataTypes.STRING(50),
description: DataTypes.STRING(500),
image: DataTypes.TEXT
}, {
freezeTableName: true,
timestamps: false
});
menu.associate = function (models) {
// associations can be defined here
menu.belongsToMany(models.restaurant, {
through: {
model: models.restaurant_menu
},
foreignKey: "menu_id"
});
};
return menu;
};
restaurant_menu.model.js
'use strict';
module.exports = (sequelize, DataTypes) => {
const restarant_menu = sequelize.define('restarant_menu', {
restaurant_id: {
type: DataTypes.INTEGER,
primaryKey: true,
allowNull: false,
references: {
model: 'restaurant'
}
},
menu_id: {
type: DataTypes.INTEGER,
primaryKey: true,
allowNull: false,
references: {
model: 'menu'
}
}
}, {
freezeTableName: true,
timestamps: false
});
restarant_menu.associate = function (models) {
// associations can be defined here
};
return restarant_menu;
};
i tried to run migration, but i get error:
Cannot read property 'menu_id' of undefined
How can I fix it?
I believe you are writing old syntax, checkout documentation.
https://sequelize.org/master/manual/advanced-many-to-many.html

How to query associated models in Node/Postgres

I'm building an app in express and I'm using postgres and sequelize for ORM. I have two models, User and Post.
In my user.js and post.js files I have:
module.exports = function(sequelize, DataTypes) {
return sequelize.define('users', {
id: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
name: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: ""
},
module.exports = function(sequelize, DataTypes) {
return sequelize.define('posts', {
id: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
user_id: {
type: DataTypes.INTEGER,
allowNull: true
},
title: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: ""
},
I imported those two models and I made the following associations:
User.hasMany(Post, { foreignKey: 'user_id' });
Post.belongsTo(User, { foreignKey: 'user_id' });
I am trying to render all the posts done by a user, but I'm probably missing something.
In my routes I can get the correct user but I don't know how to proceed.
router.route('/:id').get(async (req, res) => {
const user = await User.findById(req.params.id);
console.log(user);
res.send(user);
})
Thanks!
findById does not support the associated model ,
User.findById(req.params.id);
You can change findById to findOne and include model like this ,
User.findOne({
where : { id : req.params.id },
include : {
model : Post
}
});

Resources