0

In Prisma, I'd like to model the following but I'm not really sure how.

type Event {
  id: ID! @unique
  players: [User]! @relation(name: "EventPlayers")
  teams: [Team]! @relation(name: "EventTeams")
  ...
}

type User {
  id: ID! @unique
  eventsPlayed: [Event]! @relation(name: "EventPlayers")
  ...
}

type Team {
  id: ID! @unique
  event: Event! @relation(name: "EventTeams")
  members: [User]! @relation(name: ?????)
  ...
}

Constraints

  1. Each team member must be in the Event.players
  2. Each Event.player can only be assigned to one (or none) teams

Question

I have a feeling I need a many-to-many relationship here, but I'm struggling to figure this out. What do I relate Team.members to ?????. Am I even approaching this correctly?

More info (in case it's helpful)

I intend to create a drag-n-drop interface for creating teams. Those listed in Events.players but who have not yet been assigned as a Team.member will be in an unassigned bucket. Dragging them to a team, will assign them as a Team.member. But, I will want to query all players as events { players { id }} and events { teams { members { id }}}

Update

After giving this more thought, I'm thinking about a different way to solve this problem. Here's an updated schema I'd love your thoughts/input on.

type Event {
  id: ID! @unique
  users: [EventUser!]!
  teams: [Team!]!
  title: string
}

type EventUser {
  event: Event!
  user: User!
  role: EventRole!
}

type User {
  id: ID! @unique
  events: [EventUser!]!
  name: string
}

type Team {
  event: Event!
  members: [EventUser!]!
  name: string
}

enum EventRole {
  ADMIN
  COORDINATOR
  JUDGE
  PLAYER
  REVIEWER
  SPONSOR
}
Chris Geirman
  • 9,474
  • 5
  • 37
  • 70

1 Answers1

1

Most of your model is accurate. There are a few minor changes you need to do:

  1. Use of @relation directive: You need it only when a relationship is ambiguous. Example, self-relationship. You don't need it in your case. That is a traditional way of ORM thinking.
  2. Nullability in relationships: Consider players: [User]! relationship. It says that players field cannot be null. It has to be a list. But it makes User as optional which means you can have players = [user1, null, user2]. You may not want this. This is applicable to almost all the to-many relationships.
  3. User type should have a team field which is optional. There will be some users who will not be members of any team.

With the above adjustment, your schema will look like:

type Event {
    id: ID! @unique

    # Note DOUBLE EXCLAMATION
    # Ensure that User, as well as players, are not null.
    players: [User!]!

    # Note DOUBLE EXCLAMATION
    # Ensure that Team and teams are not null.
    teams: [Team!]!
}


type User {
    id: ID! @unique

    eventsPlayed: [Event!]!
    team: Team
}


type Team {
    id: ID! @unique

    event: Event!
    members: [User!]!

    # Added an extra key for keeping track of past events if required
    pastEvents: [Event!]!
}
Harshal Patil
  • 17,838
  • 14
  • 60
  • 126
  • thank you for your reply, and for explaining the double exclamation. I was thinking about that wrong for sure. The problem is, each `Team` would only exist for a single event, so it wouldn't make sense to show past events as part of the team type. Users can belong to many teams. I've added a new schema. I'd love your thoughts. – Chris Geirman Jan 02 '19 at 21:59
  • @ChrisGeirman, It looks pretty good. Also, if you don't need `EventRole`, then you can get rid of `EventUser` model. And, you are missing ID for `Team`. Otherwise, it is perfect. – Harshal Patil Jan 07 '19 at 04:25
  • Thx! I've been playing with it and it's working out well so far. – Chris Geirman Jan 07 '19 at 08:07