I am working with Typeorm and MongoDB. I have a UserAlert entity that saves the _id of another User entity as a field. My question is how you can get the information of the entity that that _id refers to. It would be something similar to populate in mongoose.
Example:
User:
#Entity({ name: 'Users' })
export default class User extends BaseEntity {
#ObjectIdColumn()
_id!: ObjectID;
#Column('string')
firstName!: string;
#Column('string')
lastName!: string;
#Column('string')
phoneNumber!: string;
}
User Alert:
#Entity({ name: 'UserAlerts' })
export default class UserAlert extends BaseEntity {
#ObjectIdColumn()
_id!: ObjectID;
//REFERENCE
#ObjectIdColumn()
userId!: ObjectID;
#Column('date')
date!: Date;
}
Result: User Alert
{
"_id":"asdbfsdf32112312dasdas",
"date":"15/09/2021",
"User":{
"_id":"asdas6d5412634123654",
"firstName":"Jorge",
"lastName":"Mamani",
"phoneNumber":"465465"
}
}
How would I have to present the data in Type GraphQL?
Related
I`m using Prisma with NestJS and PostgreSQL
In my schema.prisma i have this
model User {
userId Int #id #default(autoincrement())
firstName String? #db.VarChar(25)
lastName String? #db.VarChar(25)
login String #unique #db.VarChar(60)
email String #unique
password String
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
role Role? #default(ADMIN)
createdUsers User[] #relation("createdBy")
createdBy User? #relation("createdBy", fields: [creatorId], references: [userId])
creatorId Int?
}
enum Role {
ADMIN
MANAGER
WAREHOUSE
USER
}
So when a make create request like this
{
login: "A",
email: "A",
password: "A"
}
it saves in DB - that`s ok. By after the same request i get this error "Unique constraint failed on the (not available)". So shouldn't there be a not unique column name instead of (not available) or that is ok case? Where am i wrong?
I was trying drop table Users and make different unique combs, don`t know what else i can do...
UPD:
async create(createUserDto: CreateUserDto) {
return this.prisma.user.create({
data: {
...createUserDto
}
})
}
export class CreateUserDto {
#IsNotEmpty()
login: string;
#IsNotEmpty()
#IsEmail()
email: string;
#IsNotEmpty()
#MinLength(6)
password: string;
}
UPD 2.0
Finally, moved to TypeORM, it is bug like #num8er mentioned
https://github.com/prisma/prisma/issues/10829
Ty for all the replies
I am new to NestJs and trying to create nested schema in Mongoose as I want this data structure in my database:
{
name:"John",
age:28,
address:{
city:"Delhi",
state:"Delhi
}
}
For this I have created below mongoose schema:
user.schema.ts
import mongoose from "mongoose";
export const UserSchema = new mongoose.Schema({
name:{type:String},
age:{type:Number},
address:{
city:{type:String},
state:{type:String}
}
});
How Can I write Dto class for this schema.Someone let me know As I want to add data inside database.
You can simply create two DTO classes in the following way.
export class AdressDto {
readonly city: string;
readonly state: string;
}
export class UserDto {
readonly name: string;
readonly age: number;
readonly address: AdressDto
}
In the official Nestjs documentation you can find how to use DTO
in your controllers, and you can also find how to use validators if you want to use them.
I have user and profile entities and they have a onetoone relation together.
I am using typeorm and postgres
I used joincolumn on user and have access to RelationId (or Column) profileId on user side
However I want to have userId on profile side as well
How can I accomplish this?
something like this:
export class User extends BaseEntity {
#OneToOne(()=>Profile)
profile:number
#Column()
profileId:number
}
////////
export class Profile extends BaseEntity{
#OneToOne(()=>Profile)
user: number
#Column()
userId: number
}
You may find answer in documantation.
Relations can be uni-directional and bi-directional. Uni-directional are relations with a relation decorator only on one side. Bi-directional are relations with decorators on both sides of a relation.
#JoinColumn must only be on one side of the relation - on the table that will own the foreign key.
import {User} from "./User";
#Entity()
export class Profile {
#PrimaryGeneratedColumn()
id: number;
#Column()
gender: string;
#Column()
photo: string;
#OneToOne(type => User, user => user.profile) // specify inverse side as a second parameter
user: User;
}
import {Entity, PrimaryGeneratedColumn, Column, OneToOne, JoinColumn} from "typeorm";
import {Profile} from "./Profile";
#Entity()
export class User {
#PrimaryGeneratedColumn()
id: number;
#Column()
name: string;
#OneToOne(type => Profile, profile => profile.user) // specify inverse side as a second parameter
#JoinColumn()
profile: Profile;
}
I created a very small reproduction repository.
Please also have a look at my possible fix down below.
I have a graph and a graph node entity. The graph only knows about its start graph node and the node itself knows about which graph it belongs to and its successor.
#Entity()
export class Graph extends BaseEntity {
#PrimaryGeneratedColumn("uuid")
public id: string;
#Column({ nullable: true })
public startNodeId?: string;
#ManyToOne(() => GraphNode)
#JoinColumn({ name: "startNodeId" })
public startNode?: GraphNode;
}
#Entity()
export class GraphNode extends BaseEntity {
#PrimaryGeneratedColumn("uuid")
public id: string;
#PrimaryColumn("uuid")
public graphId: string;
#ManyToOne(() => Graph, { onDelete: "CASCADE" })
#JoinColumn({ name: "graphId" })
public graph: Graph;
#Column({ nullable: true })
public successorGraphNodeId?: string;
#ManyToOne(() => GraphNode)
#JoinColumn({ name: "successorGraphNodeId" })
public successorGraphNode?: GraphNode;
}
As you can see the graph's startnode might be null. Further the graph node might have no successor, so this field might be null too. It's important that a graph node has a composite primary key, because it always belongs to one graph.
I created some very basic CRUD repository actions to create a graph and a graph node. Later on I want to update the start node id of that graph.
The graph nodes repository just creates a new entity
public createGraphNode(graphId: string, successorGraphNodeId?: string): Promise<GraphNode> {
const graphNode: GraphNode = new GraphNode();
graphNode.graphId = graphId;
graphNode.successorGraphNodeId = successorGraphNodeId;
return graphNode.save();
}
The graphs repository creates a new entity and is able to update its start node id
public createGraph(startNodeId?: string): Promise<Graph> {
const graph: Graph = new Graph();
graph.startNodeId = startNodeId;
return graph.save();
}
public updateStartNodeId(graphId: string, startNodeId: string): Promise<UpdateResult> {
return this.update(graphId, {
startNodeId
});
}
When running the application I create a new graph. After that I create a new graph node and assign the graph id to it. This graph node has no successor. Last I assign the graph node as the graph start node.
const graph: Graph = await graphsRepository.createGraph();
const graphNode: GraphNode = await graphNodesRepository.createGraphNode(graph.id);
await graphsRepository.updateStartNodeId(graph.id, graphNode.id);
By doing so I'm getting the following database error
QueryFailedError: insert or update on table "graph" violates foreign
key constraint "FK_0e4022833a9efc062c01637e552"
It seems my entity design is wrong. Does someone know how to fix it?
Thanks in advance
I might have a fix for it
Graph entity
Create a reference to the PK via referencedColumnName: "id"
#ManyToOne(() => GraphNode)
#JoinColumn({ name: "startNodeId", referencedColumnName: "id" })
public startNode?: GraphNode;
Graph node entity
Do the same for the successor graph node
#ManyToOne(() => GraphNode)
#JoinColumn({ name: "successorGraphNodeId", referencedColumnName: "id" })
public successorGraphNode?: GraphNode;
Also add the Unique decorator to the entity and mark the id field as unique
#Unique(["id"])
The only problem I have is that I don't know why I have to solve it this way.
I don't know why I have to reference the PK of the referenced table via referencedColumnName: "id", this should be obvious
I also don't know why I have to mark the id column as unique via #Unique(["id"]) because this field will always be unique
In your .Save() pass the id as parameter otherwise it will consider you are creating new data.
Might be a silly question, but I just had a debate with a colleague.
What should be used in TS shape an object, a class or an interface?
I need to know that a function returns an object of a certain type, what should be used?
export class Person{
name: string;
lastName: strig;
dob: Date;
constructor() {}
}
or
export interface IPerson{
name: string;
lastName: string;
dob: Date;
}
For me the best way to create an Object is to use INTERFACE ! Because you can easily store it as an JSON Object on a database like Firebase... You have no function only properties
Then you could use the CLASS with functions to manage Objects type INTERFACE
The interface
export interface IObject {
id : string,
name: string,
description : string
}
And then the class
import { IObject } from "../interfaces/iobject";
export class ObjectService {
myObject = {} as IObject
constructor() {}
getDescription(anObject : IObject){ return anObject.description }
}