adminjs-prisma icon indicating copy to clipboard operation
adminjs-prisma copied to clipboard

non primary foreign keys

Open joshraymo opened this issue 3 years ago • 1 comments

We were having issues with our foreignKey references when they were pointing to columns that were not primary keys. This patch allowed us to use foreignKeys without them having to be primary keys.

This error was encountered in the following versions: adminJS 6.0.0 @adminJs/Prisma 2.0.0

We were getting this error

Error: 
Invalid `this.manager.findMany()` invocation in
node_modules/@adminjs/prisma/lib/Resource.js:88:48

   85 const idProperty = this.properties().find((property) => property.isId());
   86 if (!idProperty)
   87     return [];
→  88 const results = yield this.manager.findMany({
        where: {
          id: {
            in: [
              '[email protected]'
            ]
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~
          }
        }
      })

Argument in: Got invalid value 
[
  '[email protected]'
]
on prisma.findManyuser. Provided List<String>, expected List<Int>.
    at Document.validate (/node_modules/@prisma/client/runtime/index.js:47823:20)
    at PrismaClient._executeRequest (/node_modules/@prisma/client/runtime/index.js:49972:17)
    at consumer (/node_modules/@prisma/client/runtime/index.js:49916:23)
    at /node_modules/@prisma/client/runtime/index.js:49920:76
    at runInChildSpan (/node_modules/@prisma/client/runtime/index.js:49133:12)
    at /node_modules/@prisma/client/runtime/index.js:49920:20
    at AsyncResource.runInAsyncScope (node:async_hooks:199:9)
    at PrismaClient._request (/node_modules/@prisma/client/runtime/index.js:49919:86)
    at /node_modules/@prisma/client/runtime/index.js:46474:25
    at _callback (/node_modules/@prisma/client/runtime/index.js:46233:52)

The changes below were our solution

adminjs patch

index dad1696..83620d2 100644
--- a/node_modules/adminjs/lib/backend/utils/populator/populate-property.js
+++ b/node_modules/adminjs/lib/backend/utils/populator/populate-property.js
@@ -30,6 +30,7 @@ async function populateProperty(records, property) {
   }
 
   const referencedResource = property.reference();
+  const referencedProperty = property;
 
   if (!referencedResource) {
     throw new Error([`There is no reference resource named: "${property.property.reference}"`, `for property: "${decoratedResource.id()}.properties.${property.propertyPath}"`].join('\n'));
@@ -70,7 +71,7 @@ async function populateProperty(records, property) {
   } // now find all referenced records: all users
 
 
-  const referenceRecords = await referencedResource.findMany(uniqueExternalIds); // even if record has value for this reference - it might not have the referenced record itself
+  const referenceRecords = await referencedResource.findMany(uniqueExternalIds, referencedProperty); // even if record has value for this reference - it might not have the referenced record itself
   // this happens quite often in mongodb where there are no constrains on the database
 
   if (!referenceRecords || !referenceRecords.length) {

@adminjs/prisma patch

diff --git a/node_modules/@adminjs/prisma/lib/Resource.js b/node_modules/@adminjs/prisma/lib/Resource.js
index 4e7edb2..7523add 100644
--- a/node_modules/@adminjs/prisma/lib/Resource.js
+++ b/node_modules/@adminjs/prisma/lib/Resource.js
@@ -80,14 +80,15 @@ class Resource extends adminjs_1.BaseResource {
             return new adminjs_1.BaseRecord(this.prepareReturnValues(result), this);
         });
     }
-    findMany(ids) {
+    findMany(ids, refPath = null) {
         return __awaiter(this, void 0, void 0, function* () {
-            const idProperty = this.properties().find((property) => property.isId());
+            const idProperty  = this.properties().find((property) => refPath ? refPath.propertyPath === property.propertyPath : property.isId())
+
             if (!idProperty)
                 return [];
             const results = yield this.manager.findMany({
                 where: {
-                    [idProperty.path()]: {
+                    [idProperty.propertyPath]: {
                         in: ids.map((id) => (0, converters_1.convertParam)(idProperty, this.model.fields, id)),
                     },
                 },

joshraymo avatar Jul 14 '22 15:07 joshraymo

Hello, we are also facing a similar issue where we have some resources referencing some non primary foreign keys, which broke the corresponding resource pages, your solution seems to fix our issue as well thanks for the solution, I still don't know how might we apply this to a dockerized solution.

emirhanyuce avatar Dec 09 '22 11:12 emirhanyuce