Sequelize: Create with Association not working - javascript

I have three models: User, Teacher and a Student. A user can either be a teacher or a student depending upon the role.
Now, I would like to populate the Teacher and the Student model as the User model gets populated. This is the query that I am using which isn't populating the Teacher model. (And the student model as well on the other condition)
const user = await User.create({
...userDetails
include: [Teacher]
})
User Model:
const User = connObj.define('user', {
name: {
type: Sequelize.TEXT,
allowNull: false
},
username: {
type: Sequelize.STRING(50),
allowNull: false
},
email: {
type: Sequelize.TEXT,
allowNull: false
},
password: {
type: Sequelize.STRING(100),
allowNull: false,
set (password) {
const passHash = bcrypt.hashSync(password, salt)
this.setDataValue('password', passHash)
}
},
isTeacher: {
type: Sequelize.BOOLEAN,
defaultValue: false
}
})
Teacher Model:
const Teacher = connObj.define('teacher', {})
And the relation is
User.hasMany(Teacher)
User.hasMany(Student)
I have followed what is mentioned in the Sequelize docs and also other Stack Overflow answers but it just doesnt seem to work.

Related

Sequelize – autocompletion for methods and attributes

This is my current setup:
const { Model, DataTypes } = require('sequelize');
class CustomModel extends Model {
static init(attributes, config) {
return super.init(attributes, {
...config,
timestamps: true,
underscored: true,
createdAt: 'created_at',
updatedAt: 'updated_at',
});
}
}
class User extends CustomModel {
ahoy() {
const { email } = this.get();
console.log(`Ahoy, ${email}`);
}
}
User.init({
id: {
type: DataTypes.UUID,
primaryKey: true,
allowNull: false,
defaultValue: DataTypes.UUIDV4,
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true
},
}, myConfigHere);
I now want to ensure that all User attributes, as well as its model methods, are showing up in VSCode autocomplete. How can I make this happen?
const user = await User.findOne({ where: { email: 'john#example.com' } });
user.email; // No autocomplete while typing
user.ahoy() // No autocomplete while typing
When I change the code to class User extends Model, then I can see the ahoy() being autocompleted, yet this does not apply to .email
Is there a way to fix this (e.g. with JSDoc)?
If you are using pure Javascript you won't be able to do that.
Consider using Typescript, then VSCode (or any editor really) will be able to watch your Object and suggest what attribute you want from it.

Add a new field to every document from my mongo DB collection via mongoose

This question was asked several times, but despite that, I wasn't able to solve my problem. In my mongoose collection, I store 30 users with the following mongoose schema. I want to implement a newsletter on my site, therefore I want to add the new field:
newsletter: {
type: Boolean,
default: true
},
My question is: How can I add newsletter false/true to every user?
I found that, but it didn't work.
User.updateMany({}, [{ $set: { newsletter: false }}])
My Schema:
const mongoose = require('mongoose');
const UserSchema = new mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true },
password: { type: String, required: true },
date: { type: Date, default: Date.now },
token: { type: String, required: true }
});
const User = mongoose.model('User', UserSchema);
module.exports = User;
Adding to the schema "newsletter" does solve the problem for new users, but doesn't add the field to the already existing ones.

1:N relationship query to find one in Sequelize.js not working properly

I have started learning sequelize.js with node.js and having hard time defining relationships between models. I am trying to create 1:N relationship between users and roles tables i.e. many users can have same role.
Problem
When I query user model to test the defined relation ship it gives me error that original: error: column "RoleId" does not exist.
roles model:
'use strict';
const {
Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Role extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models) {
// define association here
Role.hasMany(models.User, {as: 'users'});
}
}
Role.init({
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
},
name:{
type: DataTypes.STRING,
allowNull: false
}
}, {
sequelize,
modelName: 'Role',
tableName: 'roles',
});
return Role;
};
users model:
'use strict';
const {
Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class User extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models) {
// define association here
// User.belongsTo(models.Role, {foreignKey: 'roleId', as: 'role'});
User.belongsTo(models.Role);
}
}
User.init({
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
},
name: {
type: DataTypes.STRING,
allowNull: false
},
email: {
type: DataTypes.STRING,
allowNull: false
},
mobile: {
type: DataTypes.STRING,
allowNull: false
}
// },
// roleId: {
// type: DataTypes.STRING,
// allowNull: false
// }
}, {
sequelize,
tableName: 'users',
modelName: 'User',
});
return User;
};
relationship tester js code:
const { User, Role } = require('./models');
User.findOne({
where: {email: 'admin#papertrader.org'}
})
.then((findedUser) => {
console.log(findedUser)
})
.catch((err) => {
console.log("Error while find user : ", err)
});
Can anyone one please guide me what is wrong with my code?

Working with embeeded documents and multiple schemas in one collection, mongoose

I have the following mongoose schemas for a MongoDB:
User
{
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
...
}
userSchema.methods.verifyPassword(password) {
//Verify password match
}
Customer
{
user: [User],
firstname: { type: String, required: true },
lastname: { type: String, required: true },
...
}
Company
{
user: [User],
name: { type: String, required: true },
...
}
I've decided to store the models 'Customer' and 'Company' in the same collection 'Users', as they are account data with only a few different attributes.
I'm implementing a method for login. The problem came when I try to verify the password, how can I implement a unique method for getting this embedded user.password?
Company.findOne() seems to work and Customer.findOne() too. How do I choose one? (I don't know if the login is for a company or customer, only have the email and password). If I try to implement a User model and later User.findOne(), then I can't access user.user.password due to the schema User.
Is there a right way to do it that I am not seeing?

Include Option not Working with belongsTo and Sequelize

I am trying to create an endpoint through which I can access the institute data and the related subject data. I am trying to do this with using the include option on the findAll command.
Model Definitions:
sequelize.define("institutes",
{
instituteId: {
type: DataTypes.STRING,
unique: true,
primaryKey: true
}
,instituteName: {
type: DataTypes.STRING,
unique: true
}
}
sequelize.define("subjectA", {
instituteId: {
type: DataTypes.STRING,
unique: true,
references: { model: "institutes", key: "instituteId" }
}
,subjectTeacher: {
type: DataTypes.STRING
}
}
Query Definition:
const {institutes} = require("../models")
const {subjectA} = require("../models")
module.exports = {
async instituteData (req,res) {
try {
const info = await institutes.findAll({include: [{model: "subjectA", required: true}], limit: 12})
res.send(info)
} catch (err) {
res.send({message: "This request did not work!"})
}
}
}
I also define subjectA.belongsTo(institutes, { foreignKey: 'instituteId' , foreignKeyConstraint:true }); somewhere else in my project.
The result should be a SQL query like SELECT * FROM institutes INNER JOIN subjectA on institutes.instituteID = subjectA.instituteId but as of now the query does not return anything. If I omit the include option however the query works just fine.

Categories

Resources