사진의 설명의 해쉬태그 기능까지 구현한다.
model을 생성할 때 같은 module에 넣을 지 다른 module에 넣을지 모델들간의 의존성에 따라 판단한다.
//schema.prisma
model Photo {
id Int @id @default(autoincrement())
user User @relation(fields: [userId], references: [id])
userId Int
file String
caption String?
hashtags Hashtag[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Hashtag {
id Int @id @default(autoincrement())
hashtag String @unique
photos Photo[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
정규표현식을 이용하여 #태그들을 구해준다.
구한 #태그들을 connectOrCreate로 존재하면 연결하고 없으면 추가해서 연결한다.
// uploadPhoto.resolvers.js
const resolverFn = async (_, { file, caption }, { loggendInUser }) => {
let hashtagObjs = [];
if (caption) {
const hashtags = caption.match(/#[ㄱ-ㅎ|ㅏ-ㅣ|가-힣|\w]+/g);
hashtagObjs = hashtags.map((hashtag) => ({
where: { hashtag },
create: { hashtag }
}));
}
return client.photo.create({
data: {
file,
caption,
user: {
connect: {
id: loggendInUser.id
}
},
...(hashtagObjs.length > 0 && {
hashtags: {
connectOrCreate: hashtagObjs
}
}),
}
});
};
// seePhoto.resolvers.js
import client from "../../client";
export default {
Query: {
seePhoto: (_, { id }) => client.photo.findUnique({ where: { id } })
}
};
computed field도 다른 Mutaion이나 Query의 field처럼 resolve할 때 인자들을 불러올 수 있다.
//photos.resolvers.js
import client from "../client";
export default {
Photo: {
user: ({ userId }) => {
return client.user.findUnique({ where: { userId } });
},
hashtags: ({ id }) => client.hashtag.findMany({
where: {
photos: {
some: {
id
}
}
}
})
},
Hashtag: {
photos: ({ id }, { lastId }) => {
return client.hashtag, findUnique({ where: { id } }).photos({
take: 5,
skip: lastId ? 1 : 0,
...(lastId && { cursor: { id: lastId } })
});
},
totalPhotos: ({ id }) => client.photo.count({
where: {
hashtags: {
some: {
id
}
}
}
})
}
};
사진을 수정할 때 caption만 수정되게 한다. caption이 수정되면 photo의 hashtag들도 수정되게 해야한다.
// editPhoto.resolvers.js
const resolverFn = async (_, { id, caption }, { loggedInUser }) => {
const oldPhoto = await client.photo.findFirst({
where: { id, userId: loggedInUser.id,},
include: { hashtags: { select: { hashtag: true, } } }
});
if (!oldPhoto) {
return {
ok: false,
error: "Photo not found.",
};
}
await client.photo.update({
where: { id, },
data: {
caption,
hashtags: {//과거의 #태그는 지워주고 새로운 #태그를 남긴다.
disconnect: oldPhoto.hashtags,
connectOrCreate: processHashtags(caption),
}
},
});
return {
ok: true,
};
};
unique를 한번에 설정할 수 있다.
//schema.prisma
model Like {
id Int @id @default(autoincrement())
photo Photo @relation(fields: [photoId], references: [id])
user User @relation(fields: [userId], references: [id])
photoId Int
userId Int
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([photoId, userId])
}