question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Docs: Add examples for update many-to-many relations with custom properties

See original GitHub issue

Issue type: [x] documentation issue

Database system/driver: [x] mysql / mariadb

TypeORM version: [x] latest

Steps to reproduce or a small repository showing the problem: Is it possible to add more examples in docs for “many-to-many relations with custom properties”? I’m having trouble getting it to work. For example save/update a many to many entity from one of the relationship:

I have 3 tables: users, roles, user_roles

User.ts

@Entity('users')
class User {
  @PrimaryGeneratedColumn('increment')
  id: number;

  @Column()
  name: string;

  @Column()
  email: string;
  
  @OneToMany(() => UserRole, userRole => userRole.user, {
    cascade: true,
    onDelete: 'CASCADE',
    onUpdate: 'CASCADE',
  })
  @JoinColumn({ referencedColumnName: 'user_id' })
  userRoles!: UserRole[];
}

export default User;

Role.ts

@Entity('roles')
class Role {
  @PrimaryGeneratedColumn('increment')
  id: number;

  @Column()
  role: string;

  @OneToMany(() => UserRole, userRole => userRole.role, {
    cascade: true,
    onDelete: 'CASCADE',
    onUpdate: 'CASCADE',
  })
  @JoinColumn({ referencedColumnName: 'role_id' })
  userRoles!: UserRole[];
}

export default Role;

UserRole.ts

@Entity('user_roles')
class UserRole {
 @PrimaryGeneratedColumn('increment')
 id: number;

 @Column()
 user_id!: number;

 @Column()
 role_id!: number;
 
 @CreateDateColumn()
 created_at: Date;

 @UpdateDateColumn()
 updated_at: Date;

 @ManyToOne(() => User, user => user.userRoles)
 @JoinColumn({ name: 'user_id' })
 user!: User;

 @ManyToOne(() => Role, role => role.userRoles)
 @JoinColumn({ name: 'role_id' })
 role!: Role;
}

export default UserRole;

Create a record in user_roles is working, I can save a user with related userRoles:

const user = {
  name: 'test',
  email: 'test@test.com',
  userRoles: [
    { role_id: 1 },
    { role_id: 2 }, 
    { role_id: 3 },
    { role_id: 4 }
  ],
};

await this.usersRepository.save(user);

Update its not working, I want to replace all related user_roles with the new ones, is there any save strategy option in typeorm many to many relation? I have seen in other orms for example ‘replace’ or ‘append‘ option in relation definition This is how im trying to update:

// load user
const user = await this.usersRepository.findById(user_id);

/*
returns

User {
 id: 2,
 name: 'Test user',
 email: 'testuser@test.com',
 userRoles: [
   UserRole {
     id: 376,
     user_id: 2,
     role_id: 1,
     created_at: 2020-09-18T17:26:52.000Z,
     updated_at: 2020-09-18T17:26:52.000Z
   },
   UserRole {
     id: 377,
     user_id: 2,
     role_id: 2,
     created_at: 2020-09-18T17:26:52.000Z,
     updated_at: 2020-09-18T17:26:52.000Z
   },
   UserRole {
     id: 378,
     user_id: 2,
     role_id: 3,
     created_at: 2020-09-18T17:26:53.000Z,
     updated_at: 2020-09-18T17:26:53.000Z
   },
   UserRole {
     id: 379,
     user_id: 2,
     role_id: 4,
     created_at: 2020-09-18T17:26:53.000Z,
     updated_at: 2020-09-18T17:26:53.000Z
   }
 ]
}
*/

// edit user
const newRolesIds = [4, 5, 6,];

user.name = 'updated name';
user.email = 'updatedemail@test.com';


// isnt it suposed to replace old user_roles and create this new ones?
user.userRoles = newRolesIds.map(role_id => {
 const userRole = new UserRole();
 userRole.user_id = user_id;
 userRole.role_id = role_id;
 return userRole;
});

/*
user after edit:
User {
 id: 2,
 name: 'updated name',
 email: 'updatedemail@test.com',
 userRoles: [
   UserRole { user_id: 2, role_id: 4 },
   UserRole { user_id: 2, role_id: 5 },
   UserRole { user_id: 2, role_id: 6 },
 ]
}
*/

this.ormRepository.save(user);

Save fails with this sql error Its a strange update sql, not recognizing user_id and role_id is not eve present in sql am I forgetting to define something in relationships?

QueryFailedError: Cannot add or update a child row: a foreign key constraint fails (`user_roles`, CONSTRAINT `UserRoleUserIdFK` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)
  code: 'ER_NO_REFERENCED_ROW_2',
  errno: 1452,
  sqlState: '23000',
  sqlMessage: 'Cannot add or update a child row: a foreign key constraint fails (`user_roles`, CONSTRAINT `UserRoleUserIdFK` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)',
  query: 'UPDATE `user_roles` SET `user_id` = ?, `updated_at` = CURRENT_TIMESTAMP WHERE `id` = ?',
  parameters: [ undefined, 376 ]

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
allandiegocommented, Nov 26, 2020

@sa-webb typeorm dont suport delete orphaned rows it set the related key to null and in my case it cant be null because its a FK with index, just delete works. There are a PR to add this feat, its exactly my relationship:

https://github.com/typeorm/typeorm/pull/7105

0reactions
sa-webbcommented, Nov 26, 2020

@allandiego I had a lot of issues working with my relationships in my database but ended up working them out. I can try to help you resolve this if I can. I am quite confused by your data modeling though. Without explaining why you’ve defined those three entities can you tell me your desired functionality?

Read more comments on GitHub >

github_iconTop Results From Across the Web

TypeORM: edit a many-to-many relations with custom properties
The query shows query: UPDATE 'user_roles' SET 'user_id' = ? WHERE 'id' = ? -- PARAMETERS: [null,1]', which means that the user_id =...
Read more >
07 - TypeORM many to many relations with custom properties
repo:https://github.com/Rowadz/typeorm_ytDOCS: many to many : https://typeorm.io/#/ many-to-many - relations ~~~~~~~~~~~~~~~~~~~~~~follow ...
Read more >
Many-to-many relations - typeorm - GitBook
Let's take for example Question and Category entities. A question can have multiple categories, and each category can have multiple questions.
Read more >
Many-to-many relations | TypeORM Docs
Many-to-many is a relation where A contains multiple instances of B, and B contain multiple instances of A. Let's take for example Question...
Read more >
Many-to-many relationships - Django documentation
To define a many-to-many relationship, use ManyToManyField . In this example, an Article can be published in multiple Publication objects, and a Publication ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found