How to save relation in @ManyToMany in typeORM
Solution 1
How to save relations?
Let's assume you have an array of articles and you want to create a relation to a classification entity. You just assign the array to the property articles
and save the entity; typeorm will automatically create the relation.
classification.articles = [article1, article2];
await this.classificationRepository.save(classification);
For this to work, the article entities have to be saved already. If you want typeorm to automatically save the article entities, you can set cascade
to true
.
@ManyToMany(type => Article, article => article.classifications, { cascade: true })
Your example
async create(dto: ArticleClassificationDto): Promise<any> {
let article = await this.repository.create(dto);
article = await this.repository.save(article);
const classifications = await this.classificationRepository.findByIds(article.classification, {relations: ['articles']});
for (const classification of classifications) {
classification.articles.push(article);
}
return this.classificationRepository.save(classifications);
}
Solution 2
in my case i have user and role, 1st you have to initialize your manytomany in your entities :
in user entity :
@ManyToMany((type) => Role, {
cascade: true,
})
@JoinTable({
name: "users_roles",
joinColumn: { name: "userId", referencedColumnName: "id" },
inverseJoinColumn: { name: "roleId" }
})
roles: Role[];
in role entity :
//Many-to-many relation with user
@ManyToMany((type) => User, (user) => user.roles)
users: User[];
in my service i create a new entity from my data then i added role data to my new entity object :
let entity = await this.userRepository.create(data);
let entity2 = {
...entity,
roles: data.selectedRoles,
};
const user = await this.userRepository.save(entity2);
this is the exemple in typeorm website :
const category1 = new Category();
category1.name = "animals";
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "zoo";
await connection.manager.save(category2);
const question = new Question();
question.title = "dogs";
question.text = "who let the dogs out?";
question.categories = [category1, category2];
await connection.manager.save(question);
Eve-Sama
I'm really willing to help everyone who's in trouble about development within my ability.I hope this community will be more fantastic and perfect becase of my join!
Updated on May 10, 2021Comments
-
Eve-Sama about 3 years
There are 2 entities named
Article
andClassification
. And the relation of them is@ManyToMany
.Here's my question: How to save the relation?
My code as below:
@Entity() export class Article { @PrimaryGeneratedColumn() id: number; @Column() name: string; @CreateDateColumn() createTime: Date; @UpdateDateColumn() updateTime: Date; @Column({ type: 'text', }) content: string; @Column({ default: 0, }) likeAmount: number; @Column({ default: 0, }) commentAmount: number; } @Entity() export class Classification { @PrimaryGeneratedColumn() id: number; @CreateDateColumn() createTime: Date; @UpdateDateColumn() updateTime: Date; @Column() name: string; @ManyToMany(type => Article) @JoinTable() articles: Article[]; }
I can save the
Article
andClassification
successful. But I'm not sure how to save the relation of them.I have tried to save the relation via below code:
async create(dto: ArticleClassificationDto): Promise<any> { const article = this.repository.save(dto); article.then(value => { console.log(value);//console the object article value.classification.forEach(item => { const classification = new Classification(); classification.id = item.id; classification.articles = []; classification.articles.push(value); this.classificationService.save(classification); }) }); console.log(article); return null; }
And the post data strcture like that
{ "name":"artile name", "content":"article content", "classification":[{ "id":4 },{ "id":3 }] }
At the beginning, it works.
But when I post the data again, the old record was replaced rather create another record.
What should I do next?
Just look below code please.
async create(dto: ArticleClassificationDto): Promise<any> { this.repository.save(dto).then(article => { article.classification.forEach(item => { this.ClassificationRepository.findOne( { // the privous method is get all the articles from databse and push into this array // relations: ['articles'], where: { id: item }// now I change the data strcture, just contains id instead of {id} } ).then(classification => { // console.log(article); console.log(classification); // cmd will show ' UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'push' of undefined' withous below line code. But if I init the array manually,the old record will be replaced again. // classification.articles = []; classification.articles.push(article); this.ClassificationRepository.save(classification); }); }) }) return null; }
-
Eve-Sama about 5 yearsI have tried your method. And it didn't work for me. I have updated my question, can u help next?
-
Kim Kern about 5 yearsThis is a different problem now: You are posting the
classifications
with theirid
's.id
is thePrimaryGeneratedColumn
of theclassification
entity. If you want to create a new object, you must not include the primary column, otherwise the entity will be updated instead of created if the primary column (id
) already exists. -
Eve-Sama about 5 yearsBut I just wanna save the relation of them. Not save the entity
Classification
.I do wanna create a new object, but notclassification
, just new relation ofclassification
andarticle
.And I need theid
ofClassification
automatically generated with an auto-increment value when I insert a newClassification
. I'm not clear how to realize my target? -
Kim Kern about 5 yearsOk, so all entities already exist; you just want to create the relation between the entities!? Then just load your classification entity from the database
findOne(classificationId)
, assign the articles to the classification entity you loaded from the database and then save the classification entity. -
Eve-Sama about 5 yearsI have done as what u said. But there was something wrong with it. I have posted the code in the question.
-
Kim Kern about 5 yearsYou are creating a new entity
const classification = new Classification();
instead of loading the existing one from the database. -
Eve-Sama about 5 yearsAre you sure the code you watched is below
Just look below code please
? -
Kim Kern about 5 yearsLet us continue this discussion in chat.
-
Eve-Sama about 5 yearsthx, I have tried to add ManyToMany in Article,Now I have ManyToMany in Article and Classification,but still not work for me. And I tried another solution: find all articles that classification contains, just like
classification{id:4,articles:[article1,article2]}
,thenclassification.articles.push(newArticle)
.Then it works. But I know this is a terrible solution. -
Eve-Sama about 5 yearsI guess I figure it out. When I create a object of Classification. And set its id. In that time, the articles is empty. So I push one article in it, the typeorm will think it has only one article even if it has a lot of articles in database? So the previous solution is right?
-
Kim Kern about 5 yearsMh, I'm afraid I can't completely follow what you're doing. :-/ However, you should either create a new entity without setting an
id
or load an existing entity from the database with itsid
. -
Eve-Sama about 5 yearsemm,sorry to bother u, cause my english is not good. How about chatting in the linking now you posted yesterday?