Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@moonwave99
Copy link

This PR addresses various issues regarding implicit many to many relationships, as reported in #1237 for instance.

I added a new entity Comment entity related to Post like:

model Post {
  id        Int       @id @default(autoincrement())
  title     String    @unique @db.VarChar(255)
  createdAt DateTime  @default(now())
  imprint   String    @default(uuid())
  author    User      @relation(fields: [authorId], references: [id])
  authorId  Int
  blog      Blog      @relation(fields: [blogId], references: [id], onDelete: Cascade)
  blogId    Int
  comments  Comment[]
}

model Comment {
  id    Int    @id @default(autoincrement())
  body  String @db.VarChar(255)
  posts Post[]
}

and added relevant coverage for both create and update cases.

The RelationshipStore class

The current mock client was not building intermediate cross tables for implicit relationships, so I did implement an helper for that, that is initialised in createPrismock.

I derived that an implicit relationship appears twice in the relationship list, both times with empty relationFromFields and relationToFields.

A check has been injected in create.ts, update.ts and find.ts like:

const relation = relationshipStore.findRelationship(schema.relationName);
if (relation) {
  subArgs = Object.assign(Object.assign({}, subArgs), {
    where: Object.assign(Object.assign({}, (subArgs as any).where), {
      id: {
        in: relationshipStore.getRelationshipIds(schema.relationName, schema.type, args.where?.id as FindWhereArgs),
      },
    }),
  });
} else {
  ...
}

This populates the where with the ids stored with the connect operations. Before it was just passing { undefined: undefined }, leading to the retrieval of all available records and not just the connected ones.

Symmetrical implicit relationships

i.e. a friendship relation over the User table. Although an explicit relationship allows for metadata (date of addition, id of the user who initiated the request, etc.), there is also the implicit case.

In the test I updated the schema as:

model User {
  ...
  connections            User[]         @relation("Connections")
  symmetricalConnections User[]         @relation("Connections")
}

(I chose connections over friends because the field was already existing). The other hand side of the connection (symmetricalConnections) is needed just to satisfy the Prisma constraint, as suggested here.

Some adjustments in the connected ids were needed in the relationship store, see the extractSymmetricalValues method.

Usage

The RelationshipStore singleton is exported from client.ts for cleanup and debugging purposes in your actual application tests:

To clean the relationship cache between test runs:

import { relationsStore } from "prismock/build/main/lib/client";

beforeEach(() => relationshipStore.resetValues());

To debug the current relationship state:

import { relationsStore } from "prismock/build/main/lib/client";

describe("connect stuff function", () => {
  it("connects stuff", async () => {
     await prisma.user.createMany({ data: ... });
     await connectUsers(1, 2);

     console.log(relationsStore.getRelationships());

     // expect user 1 to appear in user 2 connected list and vice versa
  });
});

You'll get the following log:

[
  {
    Connections: {
      name: "Connections",
      values: [
        { a: 2, b: 1 },
        { a: 1, b: 2 },
      ],
      a: { name: "connections", type: "User" },
      b: { name: "symmetricalConnections", type: "User" },
    },
  },
  ...
];

Open problems

It would be great not to expose the relationship store singleton, but to add methods to directly the Prismock client. I was facing some circular reference issue, I'll see if I can solve the issue.

While I managed to support some none / some case, there are still uncovered scenarios.

Hope this helps!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant