CodeDredd / pinia-orm

The Pinia plugin to enable Object-Relational Mapping access to the Pinia Store.
https://pinia-orm.codedredd.de/
MIT License
444 stars 38 forks source link

Wrong mapping with belongsTo when using composite primary keys #1903

Closed AntoninRousset closed 2 months ago

AntoninRousset commented 2 months ago

Environment

v1.9.2

Reproduction

https://pinia-orm-play.codedredd.de/#N4IgDghgxg1hDmBTAziAXAbVAOwgW0XRADcBXRAWgBNE8BLEAGhGQHtSAnKQtEU7MDHhMQNZFA50wAFzqtsRAGrkABABFadFQAoAFhAA2AMxV1sKgGIdE2KLoCUp5CogqaxRAdZgz8FaVkDOmkATxcDLwB3ZxD2FWlWFUjJaUQVAFVsOg8OZEMVZTSAGToAIw4ISRQVI1YOAtUAJhUAMhUAZhFOAyJdaWkwZDQAemH+QXgAOihWPGGyShp6YaDS4bMaAA9JvAArVABfRhx8HhAAAQXSZERh5H1rKhE2Tm4icaERMQkpWXkiADKD0QVAaiHSN38gWCdBQky6HB6vD6AyGow+Uxmc0u5Gut3ulRB5wArJMAAyTACM62wW0mKDwk32ICOJwIRBxiDxwxm1me7C4ZwxXxQPxkcgUvAAwqwIogoH9zKwTCgbthZPlCioZXgwKxkDD5BlobIUAikSAUYMRmMBEJprNhpzubzECTyVSaXSGUzDscQLh2bxOcN3AlZcgKBAfPzXkK7cJmN9JOL-rwAJLqxAVBVJYK6eK6NJasOsCM1DizQtpSBIc29frW9EJh3YhahxDEcMGSPRujnABsk0antWwwZXsQ22ZrIDpyIPiyEFjgveCZF4hTiqIAAUzHRl8xug3UTaMa3houD+cR5TJgPQ3RkNJL-uIPTkHgKOVWNFs76WX9QMznOK8IAoOo5mwSDDDoAAvDgVzeXhhSTUUtwlXc3xUAB5AAlABZFRoI4PBYIQ+tkUbNFbQmC9QLfCDSOGEiyKCBDzjvAB2clH2fSdtj2P02TOXBoLoKgWPkCgbigThCGYF5VxQ9c0M3X5MN4AA5CBxKeI9ERPJtaPtLEWN01gJPOAAWD0ySk7AZPleSBIA2dgIXRjIKQ+MJg3MVt14Pcl1wwjKMtaizxbMywKYvBOMmHj7KoJ8Xw2KcdhnABdZgjDoAwzTQUAAEEwDASYFnQUBUl1AwIFSIgAB4UuIAAdcwVHgSQqAAXlakAAD8aiiCgZgMTrowoaz+valQVDAOruD6kAZizdVRpsVJ6mCWhI24LMOBmjrdGWzdEBsI65tqdVlrweRWEulQAD5ZpUZrshUKA6uQZBbrMChIgoDB2jJMkwE2LL+pejq5sam4CtzYgKDumgDGWvEOABTx5WkfrPu+37+rwUoKAADhUUovFgeaQgoEdiXmzYKDJJIKCMUgIniKdpBkvAuc2HmuogWniVBin4AoaQKmwZBIGsdUKbqGgOGZxWOGV786bVjWhdpxoxejMBEEqXTuAoaDsDSKhKhgNBUgFihdamsXrY4W3SiV7NHYqWmuLF2o5KGdhpCCS3zfkNIA+uNBJGwCWWajoYPfVr2nf1lmjezKHXrm2HvEVFQ0GIQxyGW7AOYMPH4ZxkEnq0iPGuGfOJWh3Pc8a5ujSR2oOHRm5tvMDHkDxouS8QPv-wkkeYEQEIJ44SYp5AJ7gGAfx+8mYCVAOA5G877BW-bu5sYVQ-YYx0bKlBJG6CMU6T9SKg1HqiAR669gwHvhHH+f6R33f0gYAR4Yy-jXJ+L8R4JCoPqUBCoQS-3fFA-UeNzjWDuh4AAKqwaBy00GsEwdgh6IAVDDDPm9FqKgkaeEhF9CAP0-qOV0EDdootwaQ2Xo3Fqh9OHZGhjw4gT1ngBSIHQXUdRpAqDXtYIwjBPqzDAAEEE28KxVgAOQLFUe1UReoOASLXniPCiA9TKKMJWPmqjYqQU0VkMRujJE0CMBADmEi6EZH7rIgA4pWQBBwVHmMmMMCE-59jWO0eIlQWDoF+JUKogJkTWC+lCbYiR1s-7RNiaGF+iStHJPXtmKUV90kBIxgU9WFVyDWPaqtZ8nVvFgEMcYnqeSGmsG0F4j+9gqnyBqRjFpKgmkGKMa0oJHBOm2G6RIpBfSBk3BadoeJYyukywkRjLG39+kqGkdocuERFlxzqS0yYeQPDaFSf-OpyAxm9KGUciAJyzmTCHns6pKz+7OCaViBRj9tDaEcD1J6eSOCHMiPmbQqikHIFUfYSYILpC6G0P1ABQCQDQqQNIX5zyJkqGrnA8BaSPnyMUVQH5fyAVDwqmPSYeVaTaAxv0slG8JL9J6jM7MaycYUoMOQewmLlmbNoPgxA8SNnaAkqSyRr0pk3LEFLVgIRRVUDGQcQCfB+6lKoOUng1VaALXqmcd6xB8Z0MJiAQG7NOZkSZoDT84sAa6B2ps9gtIQQUAMH4ZOyttapx9nTMWBJoGAzwKCV27sJZO1Ji7G2aAPXeuFhQP2ZJs4w3IR9Wh9D+pGAKpsYaU5RqylMDVPam1szzRJpSRNy8c5tzeqIvwaaTXEwoO0VmjRrIqCYa2x1-AaBUDZhXbF+gA2uvgCPZAXB56TDuS-Dg6Y8DwHSIiEehhpATuAkm6t7ddAM3rbdMt-MeabHGtdHmBAUqkD5vbQWPqACcka3Z225nanaUNV6AqpXQXI0gdIEG3rvYYW6yFtzhpAcwO7+qXt5vu72cbRYsxDQ+h2TtrKgxffoje30v2nF-Y3WWulAPt1w6Bgmy0IM2og48CgsG3BRvIy62DqHakf03lhneOGQP4fPuNG+d9+oY0mBCvGYHTVTXJqRvmx7kYgjoOeqDTtb0s1KBLSI9rUhdudb2t1Xr6gxpVmnO9oboO+309Gz2umfUDmMxB5Tz7K3Jo3bDIIRr03gD1ozKarNzXjR09+LThnfVwajd5p2FmE5ZoLbtDaB08bdzqCRwhphB4bwE8QtAM857gcIYvKg677O5eA7pJzJrM25vfpEBjSD+PBAKthu47Gq25aA6UAICRzDnC+nQWAuCBUEOgdoCrYrBPEf6mYUOlBKasGpmAIGpM2FqZ7baijyGK0cYa0B5AxA61DctEDSkjRZuAwwLtth0XYSRB3OI5aLMWa7ZULt6L2YDTyGWneSkeNNh4AMDLZaVobSRD+zC9okw6jwGGOney62R22dW9D9uo2VCbEpM9vGIREf9UpK9kA9WYfY82I0Z7GOVAhDx2jx62OyfYtlTPZalNoAwFJ+TmHz5KwzwBhJOFy1Gj9VIVjhnDmzBpAR0j4hKOhc895xu3H+PkfE5AOj+n4vctM9YFT-qNPYDy4VxupXLOQVUHZ-1TnIBud2fJzhjbK28vDCa-0eQFuj5BBW43DmZD+F8MfAIoRW4RG5LQ4gPpvjTFqMsaRSpzrqWIB3JWQY2hgCvSRWgXCpRdg40YK9DGCecJJ5T5KwhQwVDFQ4D7dqBxeU1M0BIppDj+cAFF6DSGQNoDAqi8E9dYKorKpeJEt6FfFppCrxWx46uXsF3f4mqNkQN7AyqjiiCycyIqIAaq6oarwT3vwiBTh0SkxAjjnESo6kivPGAq2D43RJBPlJU8m+AgnxFdTbv9Sv23I4J+sfn5UI0J-1ab8qDvx-D-j+VaBwr0OUaebyCex+yap+1a7+l+WOSK6YVAF+X+bcP+qiAAUqwLoNgAANLj5Y5Tp-wzpzoLoGAJ6qJWg0R0CTBgAVDFxEHTBQDDAgxkgAD8taPUxIXE+BJueUn636iA5BmB2BPBG6GGAh5BeBKBucEKEBYu0BuWsgIcghMSAIgC2Yoh9mL+Juc0Ch9mShBU5BMosomhG62hG6oBya5hucehc07+n+8BdSiBCeDh1+pwQhukiAagphuchBlQs686iI5BlBNo1BtBfhC8UATBLB7Bc6PU1kxIPhV0H6z4EhMS6BnhSRKg4h7hMSagrAiAWRshKgkBuWth1aBhKhqiWozaT4bgEcWRc01hG65RbclR5BhiBUdCaQWkpAAsHQjR280hbcrRMhVWVRxUVAoIz4pARgRggxzRuclhz+IBxeKqIyAEC+S+dUK+IAa+Mg3uW+kiKgBE2CngJiZiMSweeASSRxwqge-iww8S2S2A7Um+4S9aKg7SgCKg3MNgVAzgpxqM++c0z49UHWvx6owQYQTSqih+1ioJf8sgUA80kgZEHAIQOBs8Gyx+IAS8kMrxHUYJyJNQsIBgAJvyIJuc1g0gnA5g5R7+cKT4jyEkvywxxEuRTJyARyUsvgYKUK0hwBHUQpQpbxmwRxDiTiBgEinxIyvxAs-xgJZx400BxJEJm00JGyqiQ8oeiJ4JKJeUngFJjgehNJdJVJbcjJ9q3JpArJ9g7JP+XJPJsc8A-J9pBB9B-hJBQRhYzJTOfJqiApWOfBqRnJ1pzpAZQZJuCBSBvp3J9UUs2yFc7p0ZdSCeTppQng8g8AyAWCbSdSsiuJMZ-UHe7JORBA6Z4Z-pccbp7JxRTp+gyABEuk8q8Ssi2p-ciBUZKxwpaxM+zx8+2qtUeqRA+x0ghx4Sa8QJ5xAelxFiXkIe7UYpEpO+UpMpBMES8WfxtISpwJqpSJ6pUJoQWpEKupFO+ppJRpDeJpVaZpHA9Jb+sZTptpxKKZG67RcZEZNZgZb51aGMzhn5CZHASZuygpr0IpLIO8QAA

Describe the bug

Using an array of strings as foreignKey in belongsTo results in incorrectly mapped objects.

In the reproduction link, I have added a group to each user (one-to-many) given by the foreignKey groupId. It works well for simple primary keys, but as soon as I use composite keys the group of the user is incorrectly mapped. This seems to happen whatever the amount of fields part of the composite primary and foreign keys, as long as it is an array.

Additional context

No response

Logs

No response

AntoninRousset commented 2 months ago

It seems to only happen when making a query returning many objects. Here is a corresponding test:

diff --git a/packages/pinia-orm/tests/feature/relations/belongs_to_retrieve_composite.spec.ts b/packages/pinia-orm/tests/feature/relations/belongs_to_retrieve_composite.spec.ts
index 8b378b0..61e6043 100644
--- a/packages/pinia-orm/tests/feature/relations/belongs_to_retrieve_composite.spec.ts
+++ b/packages/pinia-orm/tests/feature/relations/belongs_to_retrieve_composite.spec.ts
@@ -32,7 +32,7 @@ describe('feature/relations/belongs_to_retrieve_composite', () => {
     const postsRepo = useRepo(Post)

     userRepo.save({ id: 1, secondId: 1, name: 'John Doe' })
-    userRepo.save({ id: 1, secondId: 1, name: 'John Doe' })
+    userRepo.save({ id: 1, secondId: 2, name: 'Jane Doe' })
     postsRepo.save({ id: 1, userId: 1, userSecondId: 1, title: 'Title 01' })

     const post = postsRepo.with('author').first()
@@ -48,6 +48,32 @@ describe('feature/relations/belongs_to_retrieve_composite', () => {
     })
   })

+  it('can eager load belongs to relation for many', () => {
+    const userRepo = useRepo(User)
+    const postsRepo = useRepo(Post)
+
+    userRepo.save({ id: 1, secondId: 1, name: 'John Doe' })
+    userRepo.save({ id: 1, secondId: 2, name: 'Jane Doe' })
+    postsRepo.save({ id: 1, userId: 1, userSecondId: 1, title: 'Title 01' })
+    postsRepo.save({ id: 2, userId: 1, userSecondId: 2, title: 'Title 02' })
+
+    const posts = postsRepo.with('author').orderBy('id').get()
+
+    expect(posts).toEqual([{
+      id: 1,
+      userId: 1,
+      userSecondId: 1,
+      title: 'Title 01',
+      author: { id: 1, secondId: 1, name: 'John Doe' },
+    }, {
+      id: 2,
+      userId: 1,
+      userSecondId: 2,
+      title: 'Title 02',
+      author: { id: 1, secondId: 2, name: 'Jane Doe' },
+    }])
+  })
+
   it('can eager load missing relation as `null`', () => {
     const postsRepo = useRepo(Post)
CodeDredd commented 2 months ago

Hey @AntoninRousset , thank you for reporting this bug and writing not just a reproduction but an unit test. That helps a lot and speeds up bugfixing! 🚀 Looking into it to give you feedback.

CodeDredd commented 2 months ago

You can test the fix on the edge channel.

AntoninRousset commented 2 months ago

Fantastic, it works ! :v: