in my project i have two entity, naturalist(user) and comment entity
i create relation between them, how to save reciever_id (joined cloumn) in comment entity
this is my comment entity
#Entity()
export class Comments extends BaseEntity {
#PrimaryGeneratedColumn()
id: string
#ManyToOne(
type => Naturalist,
naturalist => naturalist.comments
)
#JoinColumn({
name: 'naturalist_id',
})
naturalist: Naturalist
#Column({ nullable: true, default: '' })
text?: string
#Column({ nullable: true, default: '' })
sender_id?: string
}
naturalist(my user) entity
#Entity()
export class Naturalist extends BaseEntity {
#PrimaryGeneratedColumn()
id: number
#Column()
user_id: string
#OneToMany(
type => Comments,
comment => comment.naturalist
)
comments: Comments[]
}
DTO contains
{
receiver_id: '2cc2f359-821c-4940-99ae-7386576d861b',
text: 'string',
id: 'e0464049-d1d9-474a-af5b-815805aa1c4b'
}
i want to save receiver_id to my comment entity
if I understand correctly your needs,
I think you need an insert method to do this:
await entityManager.insert(Comments, { naturalist: { id: '2cc2f359-821c-4940-99ae-7386576d861b' } as Naturalist });
Related
So a company can have multiple locations, that means OneToMany.
A Country can have multiple companies.
First I tried with ManyToOne in Country but I can have only 1 companyid per location.
How can I do that thing with the third table?
company.entity.ts
#Entity('company')
export class Company extends BaseEntity {
#PrimaryGeneratedColumn()
id: number
#IsString()
#Column({ type: 'varchar', nullable: true })
mission_statement: string
#IsDateString()
#Column({ type: 'date', nullable: true })
founded_in: Date
#OneToMany(() => Country, (country) => country.countryId, { eager: true })
locations: Country[]
}
country.entity.ts
#Entity('countries')
export class Country extends BaseEntity {
#PrimaryGeneratedColumn('uuid')
id: string
#IsNotEmpty()
#Column({ unique: true })
name: string
#ManyToMany(() => Company, (company) => company.locations, { nullable: true })
#JoinColumn({ name: 'company_id' })
countryId: Company[]
}
I know I should create a third entity for storing the relationship between them but I tried 4 times and for nothing. Do you think you can help me?
I have two entities to create in the table, one for the user and the other to store the token, and when creating a user I need both to be filled in, but I don't know how to do that via the ORM of TYPEORM, how would you do a create?
UserEntity
#Entity('Users')
export class UserEntity {
#ObjectIdColumn()
_id: ObjectId;
#Column({ type: 'string', length: 24 })
name: string;
#Column({ type: 'string', length: 55 })
password: string;
#Column({ type: 'string', length: 24 })
email: string;
#Column({ type: 'number', length: 24 })
celphone: number;
#OneToOne(() => TokenEntity, (TokenEntity) => TokenEntity.user, {
cascade: true,
})
#JoinColumn()
token: TokenEntity;
#CreateDateColumn()
created_at: Date;
#UpdateDateColumn()
updated_at: Date;
}
TokenEntity
#Entity('UserTokens')
export class TokenEntity {
#ObjectIdColumn()
_id: ObjectId;
#OneToOne(() => UserEntity, (user) => user.token)
user: UserEntity;
#Column({ type: 'string', length: '100' })
accessToken: string;
#Column({ type: 'number' })
expereIn: number;
}
UPDATED ---
code repo
export class CreateUserRepo implements ICreateUserContract {
constructor(private menagerRepo: EntityManager) {}
public async create({
user,
token,
}: ICreateUserContract.Input): Promise<void> {
const createUserByToken = new TokenEntity();
createUserByToken.accessToken = token.accessToken;
createUserByToken.expereIn = token.expireIn;
const createUser = new UserEntity();
createUser.name = user.name;
createUser.password = user.password;
createUser.celphone = user.celphone;
createUser.email = user.email;
createUser.token = createUserByToken;
await this.menagerRepo.save(createUser);
}
}
----- Updated
it is saving in both as expected, but in the User document it is saving a Token column, with token info, but I don't want that, I want a connection only, not to save the information in the same document...
As far as I understand, what you want is a bi-directional relation, which is described by typeorm. You attempted that with the inverse sides (UserEntity) => UserEntity.id and (TokenEntity) => TokenEntity.id. However, you want to access UserEntity and TokenEntity respectively, not their id. Change the accessors to (TokenEntity) => TokenEntity.user and (UserEntity) => UserEntity.tokenId, as they are declared in their classes.
I'm working on a nestjs project with TypeORM. I'm setting up a bidirectional ManyToMany relationship between two entities: Notes and Gcalevents. Every Note could be linked to multiple Gcalevents, and every Gcalevent could be linked to many Notes.
Snippets from my entity definitions look like this:
base.entity.ts:
export class BaseEntity {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({ type: 'boolean', default: true })
isActive: boolean;
... // some more fields
}
note.entity.ts:
import { Gcalevent } from './gcalevent.entity';
import { BaseEntity } from './base.entity';
#Entity({ name: 'note' })
export class Note extends BaseEntity {
#Column({ type: 'varchar', length: 300 })
title: string;
...
#ManyToMany(() => Gcalevent, (gcalevent) => gcalevent.notes)
#JoinTable()
gcalevents: Gcalevent[]
}
gcalevent.entity.ts:
import { Note } from "./note.entity";
#Entity({ name: 'gcalevent' })
export class Gcalevent {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({
type: 'varchar',
nullable: false,
})
eventId: string;
...
#ManyToMany(() => Note, (note) => note.gcalevents)
notes: Note[]
}
I believe I'm declaring the ManyToMany relationships correctly, but when I try to generate the TypeORM migration, I get the error TypeError: Class extends value undefined is not a constructor or null, which points to both the note.entity and gcalevent.entity files
I'm guessing this has something to do with the gcalevent.entity and note.entity files importing each other, combined with the note.entity file importing BaseEntity, but not sure how to fix it!
I had the same problem, I've found here
this "workaround" for the issue.
Try using "strings" instead of "types" in the #ManyToMany decorator:
note.entity.ts:
import { Gcalevent } from './gcalevent.entity';
import { BaseEntity } from './base.entity';
#Entity({ name: 'note' })
export class Note extends BaseEntity {
#Column({ type: 'varchar', length: 300 })
title: string;
...
#ManyToMany("Gcalevent","notes")
#JoinTable()
gcalevents: Gcalevent[]
}
gcalevent.entity.ts:
import { Note } from "./note.entity";
#Entity({ name: 'gcalevent' })
export class Gcalevent {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({
type: 'varchar',
nullable: false,
})
eventId: string;
...
#ManyToMany("Note","gcalevents")
notes: Note[]
}
For learning, I made a project testing out TypeGraphql, together with TypeORM. I have a User and Book entity, where I want to have a created_by field on the Book entity.
#ObjectType()
#Entity()
export class Book extends BaseEntity {
#Field(() => ID)
#PrimaryGeneratedColumn()
readonly id: number;
#Field({ nullable: true })
#Column({ nullable: true })
name: string;
#Field(() => User)
#ManyToOne(() => User)
#JoinColumn({ name: 'created_by' })
created_by: User;
// #RelationId((orthodontist: Orthodontist) => orthodontist.created_by)
// createdById: number;
}
#ObjectType()
#Entity()
export class User extends BaseEntity {
#Field(() => ID)
#PrimaryGeneratedColumn()
id: number;
#Field({ nullable: true })
#Column({ nullable: true })
first_name?: string;
#Field({ nullable: true })
#Column({ nullable: true })
last_name?: string;
#Field()
#Column({ unique: true })
email: string;
#Column()
password: string;
#Field(() => [Book!])
#OneToMany(() => Book, book => book.created_by)
created_books: Book[];
}
For my resolver, it simply looks like this, which I am properly loading as the docs say.
#Resolver(Book)
export class OrthodontistResolver {
#Query(() => [Book])
books(): Promise<Book[]> {
return Book.find();
}
}
When I go into my GraphQL playground, and query something like this:
{
books {
name,
id,
}
}
It all works and returns the right data. However, when I try to use the created_by field like this:
{
orthodontists {
name,
id,
created_by {
id
}
}
}
It gives me the following error:
Cannot return null for non-nullable field Book.created_by.
I made sure the relation exists in the database, and set up correctly with it's FK's. Where does this come from though? How can I fix this? I did try using the #RelationId decorator, as seen in the first code example. It unfortunately didn't work.
EDIT:
There is only one book in the database, where the created_by field is not null.
Change your books resolver to return the relationship created_by when using find operation:
#Resolver(Book)
export class OrthodontistResolver {
#Query(() => [Book])
books(): Promise<Book[]> {
return Book.find({
relations: ["created_by"],
});
}
}
I am trying to return and entity including its relation but I am getting an error saying relation xxx not found. I am using the repository pattern.
#Entity({ name: 'person' })
export class PersonEntity {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({ type: 'number' })
statusId: number;
#ManyToOne(() => StatusEntity, status => status.id)
status: StatusEntity;
}
#Entity({ name: 'statuses' })
export class StatusEntity {
#PrimaryGeneratedColumn('increment')
id: number;
#Column({ type: 'varchar', length: 256 })
name: string;
}
I am using postgres and I have a foreign key declared:
"public"."person" ADD CONSTRAINT "FK_person_statusid" FOREIGN KEY ("statusId") REFERENCES "public"."statuses"("id")
In my service:
public async getAll(): Promise<PersonEntity[]> {
return await this.personRepository.find({ relations: ['statuses'] });
}
#Entity({ name: 'person' })
export class PersonEntity {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({ type: 'number' })
statusId: number;
#ManyToOne(() => StatusEntity)
#JoinTable()
status: StatusEntity;
}
#Entity({ name: 'status' })
export class StatusEntity {
#PrimaryGeneratedColumn()
id: number;
#Column({ type: 'varchar', length: 256 })
name: string;
}
Note that I have changed StatusEntity name from statuses to status.
Could you delete the foreign key you created manually, and then update your entity like below and try?
#Entity({ name: 'person' })
export class PersonEntity {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({ type: 'number' })
statusId: number;
#ManyToOne(() => StatusEntity)
#JoinColumn({ name: 'statusId })
status: StatusEntity;
}