Hello Guys I have a product model I want to create a route that it updates all the list of products by updating quantity to (quantity=quantity-quantity_added)
and quantity_added to 0
//mongoose
const mongoose = require("mongoose");
//schema
const schema = mongoose.Schema;
//product schema
const productSchema = new schema(
{
name: { type: String, require: true },
description: { type: String, require: false },
image_url: { type: String, require: true },
price: { type: Number, require: true },
quantity: { type: Number, require: true },
rating: { type: Number, require: true },
quantity_added: { type: Number, require: true,dafualt:0 }
},
{
timestamps: true,
}
);
//export
module.exports = Product = mongoose.model("product", productSchema);
Hope you got the idea guys and you can help !
Related
auth.model.ts
import { AppDataSource } from "../app-data-source";
import { User } from "../entity";
class AuthModel {
static register = async (userDTO: RegisterUserDTO) => {
try {
const userRepo = AppDataSource.getRepository(User);
const user = userRepo.create(userDTO);
await userRepo.save(user);
} catch (err: any) {
console.error(err);
throw {
status: 500,
message: err.message,
};
}
};
}
export default AuthModel;
app-data-source.ts
import { DataSource } from "typeorm";
import config from "./config";
import { User } from "./entity";
export const AppDataSource = new DataSource({
type: config.database.type,
host: config.database.host,
port: config.database.port,
username: config.database.username,
password: config.database.password,
database: config.database.name,
entities: [User],
synchronize: true,
});
user.entity.ts
import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, Generated } from "typeorm";
#Entity({ name: "user" })
class User {
#PrimaryGeneratedColumn("uuid", { name: "id" })
userId: string;
#Column({ type: "varchar", length: 100, nullable: false, unique: true })
email: string;
#Column({ type: "varchar", length: 255, nullable: false })
password: string;
#Column({ type: "varchar", length: 255, default: "", nullable: true })
introduce: string;
#Column({ type: "varchar", length: 255, name: "profile_img", default: "", nullable: true })
profileImage: string;
#CreateDateColumn({ type: "datetime", name: "created_at_date", nullable: true })
createdAt: Date;
#Column({ type: "varchar", length: 100, nullable: false, unique: true })
nickname: string;
#Column({ type: "boolean", name: "is_auth_flag", default: false, nullable: true })
isAuth: boolean;
}
export default User;
I make API Server with Express + TypeORM + Mysql
if i send post with postman then success
Postman Success
but i test with jest then throw EntityMetadataNotFoundError: No metadata for "User" was found.
enter image description here
Postman is Success.. but test with jest is throw error
please help me
change entities attribute on app-data-source.ts
I've two Models, Post and Tag with Many To Many relationships.
Post Schema:
const postSchema = new Schema(
{
user: {
type: Schema.Types.ObjectId,
ref: 'User',
required: [true, 'A post must belong to a user.'],
},
title: {
type: String,
unique: [true, 'A Post already exists with this title.'],
required: [true, 'A Post must have a title.'],
},
slug: { type: String, unique: true },
body: { type: String, required: [true, 'A Post must have a body.'] },
coverImage: String,
images: Array,
isDraft: { type: Boolean, default: false },
isPublished: { type: Boolean, default: false },
tags: [{ type: Schema.Types.ObjectId, ref: 'Tag' }],
},
{
timestamps: { currentTime: () => Math.floor(Date.now() / 1000) },
toJSON: { virtuals: true },
toObject: { virtuals: true },
}
)
Tag Schema:
const tagSchema = new Schema(
{
title: { type: String, required: true },
slug: { type: String },
posts: [{ type: Schema.Types.ObjectId, ref: 'Post' }],
},
{
timestamps: { currentTime: () => Math.floor(Date.now() / 1000) },
toJSON: { virtuals: true },
toObject: { virtuals: true },
}
)
Now I want to remove all the references of the Posts from the Tag documents when a Post is deleted.
I'm trying to the following remove middleware in the Post model but it is not working. The post get deleted but the reference still there on the Tag documents.
postSchema.pre('remove', function (next) {
var post = this
post
.model('Tag')
.update(
{ posts: { $in: post.tags } },
{ $pull: { posts: post._id } },
{ multi: true },
next
)
})
After trying many times I finally fired out what wrong I was doing. Following the fix I made to make it work:
In Post Controller I was previously doing this:
const post = await Post.findByIdAndDelete(req.params.id)
Which I changed to:
const post = await Post.findById(req.params.id)
await post.remove()
And in Post Model:
postSchema.pre('remove', async function (next) {
await this.model('Tag').updateMany(
{ posts: this._id },
{ $pull: { posts: this._id } },
{ multi: true },
next
)
})
i want to make a User, Post and comment. connect them together and when i create a Post, it should be connected to one of my users. I don't know why i get an unusual error. Error:
ID cannot represent value: <Buffer 5e 9b f1 3e e9 49 61 38 fc 1a 6f 59>
these are all of my code so if you know whats my problem please help me fix it. Thanks
typeDefs:
import { gql } from 'apollo-server-express';
export const typeDefs = gql`
type User {
id: ID!
name: String!
email: String!
age: Int
posts: [Post!]!
comments: [Comment!]!
}
type Post {
id: ID!
title: String!
body: String!
published: Boolean!
author: User!
comments: [Comment!]!
}
type Comment {
id: ID!
text: String!
author: User!
post: Post!
}
`
UserSchema:
import mongoose, { mongo } from 'mongoose';
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
age: {
type: Number,
required: false
},
posts: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Post'
}
],
comments: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Comment'
}
]
});
module.exports = mongoose.model('User',userSchema);
PostSchema:
import mongoose from 'mongoose';
const postSchema = new mongoose.Schema({
title: {
type: String,
required: true
},
body: {
type: String,
required: true
},
published: {
type: Boolean,
required: true
},
author: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
comments: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Comment'
}
]
});
module.exports = mongoose.model('Post',postSchema);
CommentSchema:
import mongoose from 'mongoose';
const commentSchema = new mongoose.Schema({
text: {
type: String,
required: true
},
author: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
post: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Post'
}
});
module.exports = mongoose.model('Comment',commentSchema);
Resolver:
import Users from './models/User';
import Posts from './models/Post';
import Comments from './models/Comment';
export const resolvers = {
Mutation: {
createUser: async (parent, args, context, info) => {
const user = new Users(args);
await user.save();
return user;
},
createPost: async (parent, { title, body, published, author }, context, info) => {
const user = await Users.findById(author);
if (!user) {
console.log("User not found")
}
console.log(user)
const post = new Posts({ title, body, published, author: user.id });
await post.save();
user.posts.push(post);
await user.save();
return post;
}
}
}
I have found the solution and you should use type: mongoose.Schema.Types.ObjectId and ref: 'Comment' and after that inside resolvers you should use population .
During patch request, along with other changes (e.g. "name" and "email" if required) password changed and then to be hashed.
I have the following code so far patch route:
router.patch("/edit/:_id", (req, res, next) => {
User.findOneAndUpdate({_id : req.params._id},
{$set:
{
email: req.body.email,
name: req.body.name,
password: req.body.password
},
},
{
new : true,
upsert: true,
omitUndefined: true
}
)
.then(user => res.json(user))
.catch(err => console.log(err));
});
Model/Schema
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
var ObjectId = mongoose.Schema.Types.ObjectId;
// Create Schema
const UserSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
});
module.exports = User = mongoose.model("users", UserSchema);
I want to use "bcryptjs" to hash user's password. Please en-light me. Thanks in advance.
All I did in order to solve, add findOneandUpdate pre hooks on schema.
Here is code:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
var ObjectId = mongoose.Schema.Types.ObjectId;
const bcrypt = require("bcryptjs");
// Create Schema
const UserSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
});
UserSchema.pre('findOneAndUpdate', async function (next) {
await this.updateOne({},{ $set: { password: bcrypt.hashSync(this.getUpdate().$set.password, 10) }})
});
module.exports = User = mongoose.model("users", UserSchema);
I am using sequelize CLI to generate and run db migrations. The issue I am having is the id field set to data type Sequelize.UUID appearing as an autoincrement integer in mysql. Here is my user model and migration:
User Model
'use strict';
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define('User', {
UserName: {type:DataTypes.STRING,unique:true,allowNull:false},
FirstName:{type: DataTypes.STRING,allowNull:true},
LastName: {type:DataTypes.STRING,allowNull:true},
Email: {type:DataTypes.STRING,allowNull:false,unique:true,validate: { isEmail: {msg: "Invalid Email"} }},
Password: {type:DataTypes.STRING,allowNull:false},
Avatar: {type:DataTypes.STRING,allowNull:true},
}, {});
User.associate = function(models) {
User.hasMany(models.RoleUser,
{
foreignKey:'UserId',
as:'userroles',
sourceKey:'id'
}),
User.belongsTo(models.Country,
{
foreignKey:'CountryId',
targetKey:'id'
}),
User.belongsToMany(models.Role,
{
through: 'RoleUser',
foreignkey:'UserId'
})
};
return User;
};
**User Migration file:**
'use strict';
const uuidv4 = require('uuid/v4');
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('Users', {
id: {
allowNull: false,
primaryKey: true,
type: Sequelize.UUID
defaultValue:uuidv4()
},
UserName: {
type: Sequelize.STRING
},
FirstName: {
type: Sequelize.STRING
},
LastName: {
type: Sequelize.STRING
},
Email: {
type: Sequelize.STRING
},
Password: {
type: Sequelize.STRING
},
Avatar: {
type: Sequelize.STRING
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('Users');
}
};
AFTER MIGRATION, THE HIS FIELD IS CONVERTED TO INT AUTOINCREMENT IN MYSQL:
id: {
allowNull: false,
primaryKey: true,
type: Sequelize.UUID
defaultValue:uuidv4()
},
Any pointer as to why this is happening? Please assist. Even the associations seem not to be formed at all as foreign keys are of type Sequelize.UUID
I fixed the problem by adding the id field on model with primary key property set to true.
id: {
type:DataTypes.UUID,
allowNull:false,
unique:true,
primaryKey:true
},
Its like sequelize will automatically generate id field of type INTEGER AUTOINCREAMENT if the model does not have a field with primary key set to true.