I'm trying to understand how Sequelize works and I don't understand why I get SQLITE_ERROR: no such table: Users even though I created the table with sequelize.define. Code:
const { Sequelize, DataTypes } = require('sequelize');
const db = new Sequelize({
dialect: 'sqlite',
storage: './database.sqlite',
});
async function testdb() {
try {
await db.authenticate();
console.log('db connected'); // test 1
} catch (error) {
console.error(error);
}
const User = db.define('User', {
userName: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
},
email: {
type: DataTypes.STRING,
allowNull: false,
},
bio: {
type: DataTypes.TEXT,
},
});
console.log(db.models.User); // test 2
const user = await User.create({
userName: 'epic_user01',
email: 'epic.user#gmail.com',
bio: 'hello world!!!',
});
console.log(user.id); // test 3
}
testdb();
Tests 1 and 2 return successful before I get the error message.
You have to call sync to actually create the tables, add this right after the define and before the create:
await User.sync();
Related
I'm trying to make a simple social media app using react, express and mongodb.
This is the user model:
const UserSchema = new mongoose.Schema(
{
username: { type: String, required: true, unique: true },
password: { type: String, required: true },
email: { type: String, required: true, unique: true},
followers: { type: Array, required: false },
following: { type: Array, required: false },
likes: { type: Array, required: false},
},
{ collection: 'users' }
)
This is the express server:
app.post('/api/follow', async (req, res) => {
const {token, username} = req.body
if (token === null)
{
return res.json({status: 'error'})
}
const user = await User.findOne({username}).lean()
const _visitor = jwt.verify(token, JWT_SECRET)
const visitor = await User.findOne({username: _visitor.username})
if (!user)
{
return res.json({status: 'error', error: 'User not found.'})
}
if (!visitor)
{
return res.json({status: 'error', error: 'User not found.'})
}
visitor.following.push(user._id)
user.followers.push(me._id)
return res.json({status: 'ok'})
})
But when I check the mongodb compass the following and followers arrays are empty.
The best way is to use findOneAndUpdate() method to update a value.
Also, if you are updating from two different collections you can use transactions. This is optional but can be useful to avoid inconsitences in your DB.
So your code can be something similar to this:
const updateVisitor = await User.findOneAndUpdate(
{
username: _visitor.username
},
{
$push:{
following: user._id
}
})
Example here
An the same code for user:
const updateUser = await User.findOneAndUpdate(
{
username: username
},
{
$push:{
followers: me._id
}
})
I'm trying to add a value obtained from a calculator to a user's document in the database, however it's not showing any error or updating the document, the page just loads forever and I'm not sure why. Below is the code where I'm trying to update:
router.post('/tdeecalculator', function(req, res){
User.updateOne({email: "testtesttest#test.com"}, {$set: {tdeenumber: req.body.tdee}})
});
And below is my user schema:
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
tdeenumber: {
type: Number,
required: false
},
ormnumber: {
type: Number,
required: false
}
})
const User = mongoose.model('User', UserSchema);
module.exports = User;
The document in MongoDB shows as this:
_id: 60c217c26c83903ee454c2c5
name: "testtesttest"
email: "testtesttest#test.com"
password: "$2a$10$zQ4Jk3KKCjjNTyY0Z48/X.JkPO0J5lfV6j4gqTR1sLmqxKqvSq8mW"
__v: 0
Could it be because the tdeenumber is not shown in the actual document? Any help would be much appreciated
You should've used async/await before db query also you're not returning a response to the call you receive.
Convert your controller like this and see the error correctly.
// Used async before the function to use await before the db query
router.post('/tdeecalculator', async (req, res) => {
//Wrapped your operation with try/catch block to catch error message and show it in console and response
try {
await User.updateOne({ email: "testtesttest#test.com" }, { $set: { tdeenumber: req.body.tdee } })
res.send({ success: 1 });
return;
} catch (error) {
console.log(error.message);
res.send({
success: 0,
error: error.message
});
}
});
So am still kinda new to nodejs and am currently on a project and would to integrate a referral sytem into it. Basically on registering a user has a generated unique url that ither users can register with, i have gotten pass this part but now am trying to link the new user and the user who owns the link.
Here are my Models:
Referral Model
import mongoose, { mongo } from 'mongoose';
const referralSchema = new mongoose.Schema({
referralId: [
{
type: String,
unique: true
}
],
referralLink: {
type: String,
unique: true
},
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'user'
},
createdAt: {
type: Date,
default: Date.now()
}
})
const Referral = mongoose.model("Referral", referralSchema);
export default Referral;
User Model
import mongoose from 'mongoose';
import passportLocalMongoose from 'passport-local-mongoose'
const userSchema = new mongoose.Schema({
firstName: String,
lastName: String,
email: {
type: String,
trim: true,
required: true,
unique: true,
lowercase: true
},
emailToken: String,
isVerified: Boolean,
username: String,
password: String,
isAdmin: Boolean,
refId: {
type: mongoose.Schema.Types.ObjectId,
ref: "referral",
},
walletId: {
type: mongoose.Schema.Types.ObjectId,
ref: "wallet",
},
plan: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "plan",
}
]
})
userSchema.plugin(passportLocalMongoose);
const User = mongoose.model("User", userSchema);
export default User;
And Here is my code
router.get('/verify-email', async (req, res, next) => {
try {
const user = await User.findOne({ emailToken: req.query.token });
if (!user) {
req.flash('error', 'Token is invalid, Please contact us for assistance');
return res.redirect('/');
}
user.emailToken = null;
user.isVerified = true;
const savedUser = await user.save().then((user) => {
//Create new referral for new user
const newReferrer = new Referral({
referralId: uuidv4(),
referralLink: uuidv4(),
userId: user._id,
});
//save referral to the database
newReferrer.save()
const customUserResponse = { user: savedUser }
customUserResponse.refCode = newReferrer.referralId
req.login(user, async (err) => {
if (err)
return next(err);
req.flash('success', `Welcome to Jenerouszy Mechanism ${user.username}`);
const redirectUrl = req.session.redirectTo || `/dashboard`;
delete req.session.redirectTo;
res.redirect(redirectUrl);
});
});
} catch (error) {
console.log(error);
req.flash('error', 'Something went wrong, please try again or contact us for assistance')
res.redirect('/')
}
});
router.get("/referrals", middlewareObj.isLoggedIn, (req, res) => {
Referral.findOne({ userId: req.user._id })
.populate('user') //Populate model with user
.then(loggedUser => {
//Generate random referral link
const generatedRefLink = `${req.protocol}://${req.headers.host}/register?reflink=${loggedUser.referralLink}/dashboard`
res.render('dashboard/referrals', {
loggedUser: loggedUser,
generatedRefLink: generatedRefLink
})
})
})
I don't know how to go about this, can someone please guide me on what to do.
Before create doesn't work on my sequelize model
I created a template, but for some reason my before create doesn't work and I don't know what it can be anymore.
async createUser(req,res){
const { name,email,login,password } = req.body
const verify = await Users.findOne({where:{login: login}});
if(verify){ return res.status(400).json({result: 'User already exists'})}
const user = await Users.create({name,email,login,password});
}
model:
class Users extends Model {
static init(sequelize){
super.init({
name: DataTypes.STRING,
email: DataTypes.STRING,
login: DataTypes.STRING,
password: DataTypes.STRING,
}, {sequelize, tableName:'users'},
{
hooks: {
beforeCreate: (user) => {
console.log('ae');
},
},
}
)
do not enter my before and do not return my console.log
You should put the hooks option inside the second object parameter. Model.init() interface is:
public static init<M extends Model = Model>(this: ModelCtor<M>, attributes: ModelAttributes, options: InitOptions<M>): void;
Here is a working example:
import { sequelize } from '../../db';
import { Model, DataTypes } from 'sequelize';
class User extends Model {}
User.init(
{
name: DataTypes.STRING,
email: DataTypes.STRING,
login: DataTypes.STRING,
password: DataTypes.STRING,
},
{
sequelize,
tableName: 'users',
hooks: {
beforeCreate: (user) => {
console.log('======== ae ========');
},
},
},
);
(async function test() {
try {
await sequelize.sync({ force: true });
await User.create({ name: 'Alanna', email: 'example#gmail.com', login: 'value', password: '123' });
} catch (error) {
console.log(error);
} finally {
await sequelize.close();
}
})();
The execution results:
======== ae ========
Executing (default): INSERT INTO "users" ("id","name","email","login","password") VALUES (DEFAULT,$1,$2,$3,$4) RETURNING *;
Now, the beforeCreate hook of the User model works fine.
I use the present Sequelize version and try to build the associations between two models. Should be actually pretty simple since Sequelize offers hasMany and belongsTo.
But the call has no effect at all. I tried it with a new SQL DB. The tables itself are created, just without any foreign key.
db controller
const userModel = require('../model/user')
const subjectModel = require('../model/subject')
const database = require('../db/database').sequeliceInstance
async function setupAssociations () {
await database.sync()
// user + subject
userModel.hasMany(subjectModel)
subjectModel.belongsTo(userModel)
// subject and topic
subjectModel.hasMany(topicModel)
topicModel.belongsTo(subjectModel)
// topic and question
topicModel.hasMany(questionModel)
questionModel.belongsTo(topicModel)
// question and answer
questionModel.hasMany(answerModel)
answerModel.belongsTo(questionModel)
return Promise.resolve()
}
user.js
const Sequelize = require('sequelize')
const db = require('../db/database').sequeliceInstance
const user = db.define('user', {
// attributes
firstName: {
type: Sequelize.STRING,
allowNull: false
},
lastName: {
type: Sequelize.STRING,
allowNull: false
},
email: {
type: Sequelize.STRING,
allowNull: false
},
title: {
type: Sequelize.STRING,
allowNull: false
},
password: {
type: Sequelize.TEXT,
allowNull: false
}
})
module.exports = user
subject.js
const Sequelize = require('sequelize')
const db = require('../db/database').sequeliceInstance
const subject = db.define('subject', {
// attributes
subjectName: {
type: Sequelize.TEXT,
allowNull: false
}
})
module.exports = subject
I found the solution.
await database.sync() has to be called at the very end of the function.