Cant export multiple Sequelize Models from single file - javascript

I have 3 sequelize models that i have defined imported into a file called sequelize.js like so:
const { Sequelize } = require("sequelize");
const UserModel = require("./models/user");
const ItemModel = require("./models/item");
const ReservationModel = require("./models/reservation");
const config = require("./dbconfig");
const db = config.database;
const Item = ItemModel(sequelize, Sequelize);
const User = UserModel(sequelize, Sequelize);
const Reservation = ReservationModel(sequelize, Sequelize);
Reservation.hasMany(Item);
Item.belongsTo(Reservation);
Reservation.belongsTo(User);
I then try to export them:
module.exports = { Item, User, Reservation };
However, when I try to access one of them and use a model function, I get an error.
const Model = require("../../sequelize");
const passport = require("passport");
module.exports = (app) => {
app.post("/registerUser", (req, res, next) => {
passport.authenticate("register", (err, user, info) => {
if (err) {
console.log(err);
}
if (info !== undefined) {
console.log(info.message);
res.send(info.message);
} else {
req.logIn(user, (err) => {
const data = {
first_name: req.body.first_name,
last_name: req.body.last_name,
email: req.body.email,
username: user.email,
};
Model.User.findOne({
where: {
email: data.username,
},
}).then((user) => {
user
.update({
first_name: data.first_name,
last_name: data.last_name,
email: data.email,
})
.then(() => {
console.log("user created in db");
res.status(200).send({ message: "user created" });
});
});
});
}
})(req, res, next);
});
};
results in
TypeError: User.findOne is not a function
This is not an issue when I just export one of them.
module.exports = User;
const User = require("./sequelize");
...
User.findOne(...) //works
I've tried multiple ways of exporting, but none seem to work.
e.g
module.exports = {
Item: Item,
User: User,
Reservation: Reservation,
}
and
exports.Item = Item;
exports.User = User;
exports.Reservation = Reservation;
edit: Here is my user model for reference
module.exports = (sequelize, type) => {
return sequelize.define(
"user",
{
id: {
type: type.INTEGER,
primaryKey: true,
autoIncrement: true,
},
first_name: type.STRING,
last_name: type.STRING,
credentials: type.STRING,
email: {
type: type.STRING,
allowNull: false,
},
password: {
type: type.STRING,
allowNull: false,
},
},
{
tableName: "Users",
}
);
};
Why cant I export these multiple objects?

I have the exact structure you're using by importing all sequelize models into one file then module.exporting them in an object and the only thing I see thats different is how you define your models. I might be out of date but I learned as such:
const Sequelize = require('sequelize');
const db = require('../db');
module.exports = db.define('users', {
id: {
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER,
unique: true
},
}, {
timestamps: true,
});
Db declaration
const Sequelize = require('sequelize');
const db = new Sequelize(
process.env.DATABASE_URL, {
logging: false
}
);
module.exports = db;
Then your central import
const User = require('./user');
const Order = require('./order');
Order.belongsTo(User)
User.hasMany(Order)
module.exports = {
User,
Order
};
Then using it
const models = require('./models');
const results = await models.User.destroy({
where: {
id: id
}
});
if(results){
return results;
}

Found what was wrong. In my passport.js file, where I defined my localStrategy, I was doing an incorrect import.
My export in sequelize.js was
modules.export = {Item, User, Reservation};
while my import in passport.js was just
const User = require("../sequelize");
when it should have been
const Model = require("../sequelize");
const User = Model.User;
looks like I had it imported correctly in my signUp route, but not in my passport config file!

Related

How to implement mongoose discriminators?

I want to use mongoose discriminator for my project to create a collection of users in which there is a document of owner which I want to implement using discriminators. But I am getting an error of
throw new Error('The 2nd parameter to mongoose.model() should be a ' +
^
Error: The 2nd parameter to mongoose.model() should be a schema or a POJO
at Mongoose.model (D:\Github\Food-Delivery-Website\node_modules\mongoose\lib\index.js:473:11)
at Object. (D:\Github\Food-Delivery-Website\models\Owner.js:21:27)
Code is given below:
// This file is models/User.js
const mongoose = require('mongoose');
const { Schema } = mongoose;
const options = { discriminatorKey: 'kind' };
const UserSchema = new Schema(
{
userName: {
type: String,
required: true,
unique: true,
},
restOwned: {
// type: [Schema.Types.ObjectId],
type: Number,
},
},
options,
);
module.exports = mongoose.model('User', UserSchema);
Below is the next file
// This file is models/Owner.js
const mongoose = require('mongoose');
const { Schema } = mongoose;
const User = require('./User');
const OwnerSchema = User.discriminator(
'Owner',
new Schema({
isOwner: {
type: Boolean,
required: true,
},
restName: {
type: String,
required: true,
},
}),
);
module.exports = mongoose.model('Owner', OwnerSchema);
Then I import these two files in userController.js
//This file is controllers/userController.js
const User = require('../models/User');
const Owner = require('../models/Owner');
exports.addUser = async (req, res) => {
try {
const newUser = new User({
userName: req.body.userName,
restOwned: req.body.restOwned,
});
const user = await newUser.save();
res.status(201).json({
status: 'Success',
user,
});
} catch (err) {
res.status(500).json({
status: 'failed',
message: 'Server Error: Failed Storing the Data.',
err,
});
}
};
exports.addOwner = async (req, res) => {
try {
const newOwner = new Owner({
isOwner: req.body.isOwner,
restName: req.body.restName,
});
const owner = await newOwner.save();
res.status(201).json({
status: 'Success',
owner,
});
} catch (err) {
res.status(500).json({
status: 'failed',
message: 'Server Error: Failed Storing the Data.',
err,
});
}
};
What am I doing wrong here?
enter image description here
The Model.discriminator() method returns a Model.
So you can directly export the discriminator and use it as the model
// This file is models/Owner.js
const mongoose = require('mongoose');
const { Schema } = mongoose;
const User = require('./User');
//Directly export the discriminator and use it as the model
module.exports = User.discriminator(
'Owner',
new Schema({
isOwner: {
type: Boolean,
required: true,
},
restName: {
type: String,
required: true,
},
}),
);
//module.exports = mongoose.model('Owner', OwnerSchema);

Monggose array schema type not passing more than one items

I am trying to pass an array of schemas that will populate multiple social media documents in the qrCode document but when I send the post request using Postman it only sends 1 of them.
This is the QrCode Modle where the shcema is being defined
const Joi = require("joi");
const mongoose = require("mongoose");
const { themeSchema } = require("./Theme");
const { userSchema } = require("./User");
const { socialSchema } = require("./Social");
const QrCode = mongoose.model(
"QrCode",
new mongoose.Schema({
user: {
type: userSchema,
required: true,
},
name: {
type: String,
maxLength: 255,
required: true,
trim: true,
},
theme: {
type: themeSchema,
required: true,
},
// Social Media Links
social: [
{
type: socialSchema,
required: true,
},
],
})
);
function ValidateQrCode(qrCode) {
const schema = {
userId: Joi.objectId(),
name: Joi.string().max(255).required(),
themeId: Joi.objectId().required(),
socialId: Joi.array().required().items(Joi.string()),
};
return Joi.validate(qrCode, schema);
}
module.exports.QrCode = QrCode;
module.exports.validate = ValidateQrCode;
This is the post route to create a new qrCode
const { QrCode, validate } = require("../models/QrCode");
const { Theme } = require("../models/Theme");
const { User } = require("../models/User");
const { Social } = require("../models/Social");
const auth = require("../middleware/auth");
const express = require("express");
const router = express.Router();
router.get("/", async (req, res) => {
const qrCodes = await QrCode.find().sort("-name");
res.send(qrCodes);
});
router.post("/", auth, async (req, res) => {
const { error } = validate(req.body);
if (error) res.status(400).send(error.details[0].message);
const theme = await Theme.findById(req.body.themeId);
if (!theme) return res.status(400).send("Invalid theme.");
const social = await Social.findById(req.body.socialId);
if (!social) return res.status(400).send("Invalid social.");
const user = await User.findById(req.user._id);
if (!user) return res.status(400).send("Invalid theme.");
const qrCode = new QrCode({
user: user,
name: req.body.name,
theme: theme,
social: social,
});
await qrCode.save();
res.send(qrCode);
});
module.exports = router;
This is the postman post request that I send
{
"name": "Test399",
"themeId": "60f607ab97943dfaa05811bc",
//the ID's for all the socials
"socialId": ["60f657f97f90bb0cd10cfef1", "60f77d179b05d91894ef32ab"]
}
Your route has
const social = await Social.findById(req.body.socialId);
here you are trying to pass array and Mongoose findById document says to send the _id for query, that is the reason mongoose gives only one value.
Iterate over the array and get values before sending the response.

Error on Sequelize Post - Connection closed without response

New to sequelize. If I remove the {where: {username : uname}} it returns all of the records, but with it I get an error:
uname is being sent as paramter but the error log says username is not defined. Username is a field in the database.
// Find a single User with a username
export function findOne(req, res) {
const uname = req.params.username;
Users.findAll({where: {username : uname}})
.then(data => {
res.send(data);
})
.catch(() => {
res.status(500).send({
message: 'Error retrieving User with username=' + uname
});
});
}
Any idea what I am doing wrong?
User model:
import pkg from 'sequelize';
const { DataTypes } = pkg;
export default (sequelize) => {
const User = sequelize.define('user', {
title: {
type: DataTypes.STRING
},
firstname: {
type: DataTypes.STRING
},
lastname: {
type: DataTypes.STRING
},
username: {
type: DataTypes.STRING
},
password: {
type: DataTypes.STRING
},
email: {
type: DataTypes.STRING
}
});
return User;
};
Route:
import { findOne } from '../controllers/userlogin.controller.js';
import express from 'express';
export default app => {
const router = express.Router();
// Find by User
router.post('/', findOne);
app.use('/api/userlogin', router);
};

How to connect to multiple databases through Sequelize?

I need to connect to different databases depending on the Express route.
For example:
example.com/oneapp
This route must access a database called oneapp
example.com/secondapp
This route must access a database called secondapp
I have these settings in my Sequelize
index.js:
const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const config = require('../../config/database.js');
const db = {};
const sequelize = new Sequelize(config.producao);
fs
.readdirSync(__dirname)
.filter(file => (file.indexOf('.') !== 0) && (file !== path.basename(__filename)) && (file.slice(-3) === '.js'))
.forEach((file) => {
const model = sequelize.import(path.join(__dirname, file));
db[model.name] = model;
});
console.log(db)
Object.keys(db).forEach((modelName) => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;
database.js
module.exports = {
"producao": {
username: 'sa',
password: 'mypass',
database: 'PRODUCAO',
host: 'SVRNAZ002',
dialect: 'mssql',
}
}
Run that code twice with different db settings and keep two sets of the sequelize connection object and array of models.
const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const configs = [require('../../config/database.js'), require('../../config/database2.js')];
module.exports = configs.map(config => {
const db = {};
const sequelize = new Sequelize(config.producao);
// load stuff like normal
db.sequelize = sequelize;
db.Sequelize = Sequelize;
return db;
});
Now you can access both:
const models = require('index');
const firstdb = models[0];
const seconddb = models[1];
maybe this is not the right answer, but I use it and it works.
first I use it for databases usually, the second for images
db.js
const {Sequelize} = require('sequelize')
const config = [
{
dialect: 'sqlite',
storage: './db.sqlite'
},
{
dialect: 'sqlite',
storage: './db_gambar.sqlite'
}
]
const database = config.map( x => new Sequelize(x));
module.exports = { database }
./models/akun.js
const { DataTypes, Model } = require('sequelize');
const { database} = require('./../db');
const sequelize = database[0];
// Tambahan is extend Model
class Akun extends Tambahan{}
Akun.init({
name: {
type: DataTypes.STRING,
allowNull: false
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true
},
password: {
type: DataTypes.STRING,
allowNull: false,
}
},{ sequelize, underscored: true})
./models/gambar.js
const { DataTypes, Model } = require('sequelize');
const { database } = require('./../db');
const sequelize = database[1];
// Tambahan is extend Model
class Gambar extends Tambahan{}
Gambar.init({
name: {
type: DataTypes,
allowNull: false
},
user_id: {
type:DataTypes.INTEGER,
allowNull: false
},
data: {
type:DataTypes.BLOB,
allowNull: false
},
thumbnail: {
type: DataTypes.BLOB,
allowNull: false
}
},{ sequelize , underscored: true})

Best way to import sequelize models in node.js

I am using sequelize orm in node.js. I have made models folders for all model like userModel.js, in userModel.js I have some class-based functions like login and getToken.
// some code of userModel.js
const jwt = require('jsonwebtoken');
module.exports = (sequelize, Sequelize) => {
const UserSchema = sequelize.define('User', {
first_name: {
type: Sequelize.STRING,
},
last_name: {
type: Sequelize.STRING,
},
});
// generate token
UserSchema.genToken = (id) => {
return jwt.sign({ id }, 'test');
}
// user login
UserSchema.login = function (body) {
const User = this;
return User.findOne({
where: { email: body.email}
})
.then((result) => {
return result;
})
.catch((err) => {
return Promise.reject(err);
})
}
return UserSchema;
}
when i import userModel.js in db.js
const Sequelize = require('sequelize');
const config = {};
var db = {};
const sequelize = new Sequelize(config.database, config.username, config.password, {
host: config.host,
dialect: config.dialect,
operatorsAliases: false,
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
db.User = sequelize.import('./../models/userModel');
module.exports = db;
so my question is when I using db variable for userModel like
db.User
I am using VS code editor for coding. So now VS code is showing me all suggestion of sequelize models but it is not showing my functions for login and genToken
//suggest
db.User.find()
db.User.findOne()
//but not include these
db.User.login()
db.User.genToken()
Even when I use db.User.login() or db.User.genToken() it's working as I want but right now I will have to open userModel.js again and again for seeing the name of all functions. How can I import models in a better way?

Categories

Resources