7
votes

Mettre à jour une relation plusieurs-à-plusieurs avec TypeORM

Je rencontre des problèmes pour mettre à jour une entité qui a un reln plusieurs-à-plusieurs, curieux de savoir si je fais quelque chose de mal, ou plus précisément quelle est la bonne façon de le faire

Considérez les entités suivantes ...

const note = await noteRepo.findOneOrFail(noteId);
const foundSubjects = await subjectRepo.findByIds(Array.from(subjectIds));
note.subjects = foundSubjects;
noteRepo.save(note);

Dans mon code, je trouve le nœud, puis j'essaye de le mettre à jour et de l'enregistrer comme ça ...

@Entity
class Subject
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  name: string;

  @ManyToMany(() => Note, note => note.subjects)
  @JoinTable()
  notes: Note[];

  ...

@Entity()
export class Note {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @ManyToMany(() => Subject, (subject: Subject) => subject.notes)
  subjects: Subject[];

Mais hélas, les sujets ne sont pas enregistrés sur la note.

Quelle est la bonne façon de faire cela?

Merci!


1 commentaires

hrmmm, je me demande si j'ai besoin d'utiliser cette syntaxe: github .com / typeorm / typeorm / blob / master / docs /…


3 Réponses :


3
votes

Donc, ce qui suit a fonctionné pour moi:

  subjectIds.forEach(async id => {
  await connection
    .createQueryBuilder()
    .relation(Note, 'subjects')
    .of(note)
    .add(id);
});

Cependant, je pense toujours que la méthode repo.save () devrait fonctionner p >


1 commentaires

Alors, cela signifie-t-il que nous devons écrire des requêtes séparées s'il y a plus de changements à apporter, comme dans la réponse de Nestor Perez?



2
votes

Par défaut, la cascade est définie sur false, vous pouvez l'activer comme suit:

@Entity()
export class Note {
@PrimaryGeneratedColumn('uuid')
id: string;

@ManyToMany(() => Subject, (subject: Subject) => subject.notes, { cascade: true })
subjects: Subject[];


2 commentaires

note.subjects = [{id: 1}, {id: 2}]; noteRepo.save (note); fonctionnera alors.


cela fonctionne pour ajouter les nouveaux sujets, mais que se passe-t-il si nous voulons remplacer ces identifiants par d'autres? Doit-on utiliser le .relation (). Of (). AddAndRemove () ?



4
votes

Dans mon cas, j'essaie de mettre à jour une relation existante mais cela me donne une violation de clé unique car la relation existe déjà, donc je dois d'abord supprimer toutes les relations existantes, puis ajouter les relations de mon utilisateur mis à jour:

export const updateUser = async (user: User): Promise<User | undefined> => {
    /**
     * Get the actual relationships of that user.
     */
    const actualRelationships = await getRepository(User)
        .createQueryBuilder()
        .relation(User, 'roles')
        .of(user).loadMany();

    /**
     * Add new relationships of the user, and delete the old relationships.
     */
    await getRepository(User)
        .createQueryBuilder()
        .relation(User, 'roles')
        .of(user)
        .addAndRemove(user.roles, actualRelationships);

    /**
     * Update only the table USER.
     */
    await getRepository(User)
        .createQueryBuilder()
        .update()
        .set({
            name: user.name,
            username: user.username,
            active: user.active
        })
        .where('id = :id', {id: user.id})
        .execute();

    /**
     * Return the updated user
     */
    return await getUser(user.id, true, true)
};


0 commentaires