Relationship Manytoone / Onetomany Typeorm does not save foreign key

Asked

Viewed 587 times

1

Hello, I am developing an Node API using Typeorm and Sqlite3, but when using the Manytoone/Onetomany relationship, it does not save the foreign key. The scenario is as follows: I have a user who can have one or more lists and a list can only belong to one user. When implementing this with typeorm, it does not save the foreign key.

save method of the list:

    async save(request: Request, response: Response) {
    let { user_id, products } = request.body;

    products = products.map(product => {
      return { id: product };
    });

    const listRepository = getRepository(List);

    const data = { user_id, products };

    const schema = Yup.object().shape({
      user_id: Yup.number().required(),
      products: Yup.array(
        Yup.object().shape({
          id: Yup.number().required(),
        }),
      ),
    });

    await schema.validate(data, {
      abortEarly: false,
    });

    const list = listRepository.create(data);

    await listRepository.save(list);

    return response.status(201).json(list);
  },

List template:

@Entity()
export default class List {
  @PrimaryGeneratedColumn()
  id: number;

  @ManyToMany(type => Product)
  @JoinTable({
    name: 'list_product',
    joinColumn: {
      name: 'list_id',
      referencedColumnName: 'id',
    },
    inverseJoinColumn: {
      name: 'product_id',
      referencedColumnName: 'id',
    },
  })
  products: Product[];

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

The list template has two relationships, a Manytomany and Manytoone (which is not saving the user id in the table)

User model:

@Entity('user')
export default class User {
  @PrimaryGeneratedColumn('increment')
  id: number;

  @Column()
  username: string;

  @Column()
  password: string;

  @OneToMany(() => List, list => list.user)
  @JoinColumn({ name: 'user_id' })
  lists: List[];
}

When I send a request to the url that calls the save method, it saves the data in the many table, but it does not save the user id in the "list" table. That is, The N:M relation is working perfectly, but the 1:N relationship is not working, it simply saves the user id as null.

  • I think that’s the problem there @Joincollumn() in both entities!

  • @Leandrade think that this is not the problem itself. I did the tests and even before with the @JoinCollumn in a single model, it was no longer saving the user from the list. I followed the same steps as a video, but I was not successful, but thanks for the reply!!

1 answer

0


I was able to solve it after a little study of my application. The problem was not in the code itself, but in the way I sent the user reference. When I made the request to the server, I sent something like this:

{
    "user": 1,
    "products": [1,2
    ]
}

And in the save method, I use Yup to validate the data, and my validation was like this:

const schema = Yup.object().shape({
      user_id: Yup.number().required(),
      products: Yup.array(
        Yup.object().shape({
          id: Yup.number().required(),
        }),
      ),
    });

Therefore, my request went through validation because I was actually sending an integer number, which in this case is the user id. However, I realized that at the time of saving, it did not associate the user id to a database user:

const list = listRepository.create(data);

console.log(list); // aqui ele me mostrava que apenas os produtos eram associados

await listRepository.save(list);

return response.status(201).json(list); 

By all accounts, Typeorm expects an object when it comes to a foreign key (I haven’t found anything related to it, so if anyone has any links that they can read, I would be very grateful). So, solution line was to pass an object with the user id in instead of only the user id:

{
    "user": {
        "id": 1
    },
    "products": [1,2
    ]
}

Then I updated the Yup validation as well:

const schema = Yup.object().shape({
      user: Yup.object().shape({
        id: Yup.number().required(),
      }),
      products: Yup.array(
        Yup.object().shape({
          id: Yup.number().required(),
        }),
      ),
    });

And that’s it! Now it saves a new list already with the User Id and also saves the list products in the many to many table too :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.