Implicit relationship ManyToMany triggering error in Forest - NestJs

Feature(s) impacted

Displaying many to many relation with no primary id in the dashboard.
I do understand the error, I just want to find a solution that won’t force me to modify the database to get it work. Please can you tell me if there is one ?
PS : by the way, where can we find the whole documentation for NestJs.

Observed behavior

I can not reach the data : the message display in the backend is
This collection has no primary key

I am using Forest Admin with NestJs

Expected behavior

I want to be able to reach the data and add Tags to Event in my case (see screenshot)

Failure Logs

 This collection has no primary key 

Error: This collection has no primary key
    at Function.packId (/home/wghanem/repo/silencio-backoffice/node_modules/@forestadmin/agent/src/agent/utils/id.ts:20:13)
    at Object.beforeSerialize (/home/wghanem/repo/silencio-backoffice/node_modules/@forestadmin/agent/src/agent/services/serializer.ts:83:33)
    at JSONAPISerializer.serializeResource (/home/wghanem/repo/silencio-backoffice/node_modules/json-api-serializer/lib/JSONAPISerializer.js:565:22)
    at /home/wghanem/repo/silencio-backoffice/node_modules/json-api-serializer/lib/JSONAPISerializer.js:560:14
    at Array.map (<anonymous>)
    at JSONAPISerializer.serializeResource (/home/wghanem/repo/silencio-backoffice/node_modules/json-api-serializer/lib/JSONAPISerializer.js:559:19)
    at JSONAPISerializer.serialize (/home/wghanem/repo/silencio-backoffice/node_modules/json-api-serializer/lib/JSONAPISerializer.js:110:27)
    at Serializer.serialize (/home/wghanem/repo/silencio-backoffice/node_modules/@forestadmin/agent/src/agent/services/serializer.ts:19:51)
    at Serializer.serializeWithSearchMetadata (/home/wghanem/repo/silencio-backoffice/node_modules/@forestadmin/agent/src/agent/services/serializer.ts:34:26)
    at ListRelatedRoute.handleListRelated (/home/wghanem/repo/silencio-backoffice/node_modules/@forestadmin/agent/src/agent/routes/access/list-related.ts:38:54)

Context

  • Project name: Silencio
  • Team name: Silencio
  • Environment name: Production
  • Agent type & version: Liana Version 1.0.0-beta.58

Hi @walidthebest

Can you give me the structure of the tables which are being used here so that I have a better understanding of the issue?

The documentation about many to many relationships is here: To multiple records - [Beta] Developer guide

Here it is (simplified model):

model Tag {
    id Int               @id @default(autoincrement())
}

model Event {
    id Int          @id @default(autoincrement())
}

model _TagToEvent {
   tagId     Int 
   eventId Int 

  @index([tagId,eventId])
  @unique([tagId,eventId])
}

There is no easy way to fix that…
ForestAdmin needs a PK to be able to address the _TagToEvent table, and that’s a hard requirement.

As you have a unique index, the easier way would be to hook into the database introspection step, and tell forest admin to use [tagId, eventId] as a PK (composite pks are supported), but their is no way to do that right now.

If you don’t need this to work right now, we have a pull request which is currently in review which was implemented so that customers can cache the result of the database introspection (that would allow faster startup times for the agent).

Once merged this would allow you to do something like this.

import { createSqlDataSource, introspect } from '@forestadmin/datasource-sql';

const uri = 'postgres://...';
const introspection = await introspect(uri);

// Change the output of the introspection so that forest thinks tagId
// and eventId are primary keys
introspection
  .find(t => t.name === '_TagToEvent')
  .columns
  .forEach(c => { c.primaryKey = c.name.endsWith('Id') });

createAgent(options)
  .addDataSource(createSqlDataSource(uri, { introspection }))

Would that be OK for you?

I’ll add an id to relations :slight_smile: thank you

Just to be clear, there is no need to add a new column.

You can simply mark both keys as pks