boolean-uk / team-dev-server

3 stars 12 forks source link

As a user, so I can show my appreciation for posts, I want to be able to like them#41 #242

Closed ning905 closed 1 year ago

ning905 commented 1 year ago

1- Create a Like model and link with the User and Post models. https://www.prisma.io/docs/concepts/components/prisma-schema/relations/one-to-many-relations Screenshot 2022-09-20 at 11 41 59

2- Modify the getAll function in the “/posts” route to include the likes. https://www.prisma.io/docs/concepts/components/prisma-client/crud

3- When a user clicks the like button, it sends a POST or DELETE request to “/post/:id/like”, depending on the status of whether the post is liked by the user or not.

4- The server receives the request, and runs the validateAuthentication check first. If fails, return error message respectively.

5- If the request passes the validation state, the request object should have a user property, where we could know the userId.

6- Meanwhile, the postId is sent through the request params. Try to find the post object in DB, including likes. If not found, send error 404, “Post with the provided id does not exist”.

7- Check if the like already exists by looking into the array of likes, and see if any is made by the user. -- If the like does not exist and the server receives a POST request, create a new like in the DB. -- If the like exists and the server receives a DELETE request, delete the like in the DB. -- Otherwise, return error 409. https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses https://www.prisma.io/docs/concepts/components/prisma-client/crud

8- Finally, find all the likes with the given postId, including user and profile information. Send response to the client with the status code 201 and the likes.

vherus commented 1 year ago

Are you sure about the relation?

A user can like many posts, a post can be liked by many users. Though it's technically possible by using a one-to-many, you'll have to do some extra work to make sure a user is only able to like the same post one time - this is more easily accomplished by using prisma's Many-to-Many models.

By making Like a many-to-many join table, each records ID will be constructed using the user's ID and the post's ID to create a unique ID. This automatically enforces a user only being able to like a post one time

ning905 commented 1 year ago

Are you sure about the relation?

A user can like many posts, a post can be liked by many users. Though it's technically possible by using a one-to-many, you'll have to do some extra work to make sure a user is only able to like the same post one time - this is more easily accomplished by using prisma's Many-to-Many models.

By making Like a many-to-many join table, each records ID will be constructed using the user's ID and the post's ID to create a unique ID. This automatically enforces a user only being able to like a post one time

Do you mean building an implicit many-to-many relationship between the User and the Post? Like this:

model User {
  id           Int           @id @default(autoincrement())
  email        String        @unique
  password     String        @db.VarChar(250)
  role         Role          @default(STUDENT)
  profile      Profile?
  cohortId     Int?
  cohort       Cohort?       @relation(fields: [cohortId], references: [id])
  posts        Post[]        @relation("userWrittenPosts")
  deliveryLogs DeliveryLog[]
  likedPosts   Post[]        @relation("userLikePosts")
}

model Post {
  id        Int       @id @default(autoincrement())
  content   String
  user      User      @relation("userWrittenPosts", fields: [userId], references: [id])
  userId    Int
  createdAt DateTime  @default(now())
  updatedAt DateTime? @updatedAt
  likedBy   User[]    @relation("userLikePosts")
}
vherus commented 1 year ago

Yeah, that would certainly work and makes your implementation a little easier.

An explicit many-to-many will give you more control and enable you to extend the "like" functionality to include more types of reactions (love, celebrate, etc.) down the line. Depending on how far ahead you want to think, take that into account.

I'm happy for you to go ahead with the current solution if you choose!