'Define a prisma schema for twitter's like feed
i'm currently working on a twitter clone with express / prisma / postgreSQL for my backend.
I'm struggling to imitate twitter's feed.
Here's my current prisma Schema
model User {
id String @id @default(cuid())
email String @unique
username String @unique
profilename String?
password String
bio String?
image String?
createdAt DateTime @default(now())
isAdmin Boolean @default(false)
tweets Tweet[]
retweets Retweet[]
likes Like[]
followers Follows[] @relation("follower")
following Follows[] @relation("following")
}
model Follows {
follower User @relation("following", fields: [followerId], references: [id])
followerId String
following User @relation("follower", fields: [followingId], references: [id])
followingId String
createdAt DateTime @default(now())
@@id([followerId, followingId])
}
model Tweet {
id String @id @default(cuid())
content String
createdAt DateTime @default(now())
deleted Boolean @default(false)
media String[]
author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
authorId String
originalTweet Tweet? @relation("replies", fields: [originalTweetId], references: [id], onDelete: Cascade)
originalTweetId String?
responses Tweet[] @relation("replies")
likes Like[]
retweets Retweet[]
hashtags Hashtag[]
}
model Hashtag {
id String @id @default(cuid())
name String @unique
createdAt DateTime @default(now())
tweets Tweet[]
}
model Retweet {
id String @id @default(cuid())
tweet Tweet @relation(fields: [tweetId], references: [id], onDelete: Cascade)
tweetId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
userId String
createdAt DateTime @default(now())
}
model Like {
id String @id @default(cuid())
tweet Tweet @relation(fields: [tweetId], references: [id], onDelete: Cascade)
tweetId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
userId String
createdAt DateTime @default(now())
}
and my current function to get user feed
exports.getUserFeed = async (userId, options = {}) => {
try {
const user = await prisma.user.findUnique({
where: { id: userId },
include: { following: true },
})
if (user.following.length === 0) {
return prisma.tweet.findMany({
orderBy: {
createdAt: "desc",
},
...options,
})
}
return prisma.tweet.findMany({
where: {
OR: [
{
author: {
followers: {
some: {
followerId: userId,
},
},
},
},
{
likes: {
some: {
user: {
followers: {
some: {
followerId: userId,
},
},
},
},
},
},
{
retweets: {
some: {
user: {
followers: {
some: {
followerId: userId,
},
},
},
},
},
},
],
},
orderBy: {
createdAt: "desc",
},
...options,
})
} catch (err) {
throw new Error(err)
}
}
With this i get tweets posted by user i follow, liked by user i follow and retweeted by user i follow but order by tweet's created at not by the "event" created at.
To solve this i thought about creating a new model called Event or Status with optionnal feed like:
- isRetweet ?
- isLike ?
- etc
and then retrieve this instead of tweet model.
But it seems messy and complex for no reason. Is there a way to actually define a better schema or do a better query ?
Thanks a lot.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
