hello everyone. I'm fairly new to prisma and had a...
# orm-help
i
hello everyone. I'm fairly new to prisma and had a question about many-to-many relationships. I am trying to represent a following/follower relation between users, where each relation has a boolean blocked field. Here is an excerpt from datamodel.prisma:
Copy code
type User {
  id: ID! @id
  username: String! @unique
  email: String! @unique
  phoneNum: String @unique
  firstName: String!
  lastName: String!
  password: String!
  profilePicture: String
  status: Status! @default(value: ACTIVE)
  followers: [User!]!
  following: [User!]!
  createdAt: DateTime! @createdAt
  updatedAt: DateTime! @updatedAt
}

type Following {
  id: ID! @id
  follower: User!
  followed: User!
  blocked: Boolean! @default(value: false)
  createdAt: DateTime! @createdAt
  updatedAt: DateTime! @updatedAt
}
When I run
prisma deploy
, I get an error saying that the relations
followers
,
following
(on
User
),
follower
,
followed
(on
Following
) don't have names. If anyone could help me with figuring this issue out, I would be forever grateful as I have been struggling with this for a couple of weeks now. My current workaround is that I deleted the
followers
and
following
fields on
User
and instead wrote resolvers for them as computed fields and named the
followed
and
follower
relations on `Following`:
Copy code
// resolvers/User.ts
    t.list.field("followers", {
      type: "User",
      resolve: async ({ id }, args, ctx) => {
      const fragment = `
        fragment FollowerUserInfo on User {
          follower {
            username
            email
            firstName
            lastName
            profilePicture
            id
          }
        }
      `;

        const rows: User[] = await ctx.prisma.followings({ where: { AND: [{ followed: { id } }, { blocked: false } ] } }).$fragment(fragment);
        const followers = rows.map((elm: any) => elm.follower);
        return followers;
      }
    });

// datamodel.prisma
type Following {
  id: ID! @id
  follower: User! @relation(name: "Follower")
  followed: User! @relation(name: "Followed")
  blocked: Boolean! @default(value: false)
  createdAt: DateTime! @createdAt
  updatedAt: DateTime! @updatedAt
}
Moreover, I am using the following versions of Prisma-related dependencies:
Copy code
"dependencies": {
    "apollo-server-express": "^2.9.3",
    "express": "^4.17.1",
    "graphql": "^14.5.4",
    "graphql-middleware": "^4.0.1",
    "graphql-shield": "^6.1.0",
    "nexus-prisma": "^0.3.8",
    "prisma-client-lib": "^1.34.8"
  },
  "devDependencies": {
    "@types/express": "^4.17.1",
    "@types/graphql": "^14.5.0",
    "@types/jest": "^24.0.18",
    "@types/node": "^12.7.4",
    "@typescript-eslint/parser": "^2.3.0",
    "apollo-server-testing": "^2.9.3",
    "jest": "^24.9.0",
    "ts-node": "^8.3.0",
    "ts-node-dev": "^1.0.0-pre.42",
    "typescript": "^3.4.5"
  }
Please let me know if this makes sense or not or if there's a more efficient way of doing things. Thanks!
s
This may help answer some of your questions. If I understand your question correctly, Prisma will require you to name your relations when they are ambiguous. https://www.prisma.io/docs/datamodel-and-migrations/datamodel-MYSQL-knul/#relations
r
As @Spencer Olsen has mentioned, hopefully that’s all you need, the
name
param. From the linked page:
Copy code
author: User @relation(name: "StoriesByUser")
i
Thanks guys for the prompt response. It's been extremely helpful. Although, I'm using Postgres and apparently when I select it from the right-hand dropdown, the relations section of the docs disappears??
r
the syntax is the same
.. it should be ..
i
Unfortunately, I'm still struggling with this. I have updated my datamodel to look like:
Copy code
type User {
  id: ID! @id
  username: String! @unique
  email: String! @unique
  phoneNum: String @unique
  firstName: String!
  lastName: String!
  password: String!
  profilePicture: String
  status: Status! @default(value: ACTIVE)
  followers: [User!]! @relation(name: "Following")
  following: [User!]! @relation(name: "Following")
  createdAt: DateTime! @createdAt
  updatedAt: DateTime! @updatedAt
}

type Following {
  id: ID! @id
  follower: User! @relation(name: "Follower")
  followed: User! @relation(name: "Followed")
  blocked: Boolean! @default(value: false)
  createdAt: DateTime! @createdAt
  updatedAt: DateTime! @updatedAt
}
When I query a User to look up its
followers
or
following
field, the array is always empty 😞
j
I think you need different relation names here:
Copy code
followers: [User!]! @relation(name: "Following")
  following: [User!]! @relation(name: "Following")
Perhaps like this:
Copy code
followers: [Following!]! @relation(name: "Follower")
following: [Following!]! @relation(name: "Followed")
i
@Josef Henryson Thanks for the help! However, I tried changing the relation names and I got these errors when running `prisma deploy`: 😕
j
I think it is because you refer to [User] in your User type, but then you have a Following type.
Maybe you could have just a User-User relation and then a list of blocked followers on the User type?
i
@Josef Henryson That's a pretty good idea, thank you. But also, what if I wanted to know when a user follows another? That's one of the reasons why I wrote a
Following
type as well to have the
createdAt
field.
j
Well, I’m not really a data model guy. If you really need to keep track of more details on the followinng I guess an extra type/object is to prefer for that relation. But then you also need to express that in your schema. It looked like you wrote [User] on your User.following instead of [Following]