
Join the Conversation!
Subscribing gives you access to the comments so you can share your ideas, ask questions, and connect with others.
"Please login to view comments"
Subscribing gives you access to the comments so you can share your ideas, ask questions, and connect with others.
Let's start by creating a new server action that will allow us to create a new Review in the database. We will create a new file called reviews.ts in the directory.
// import our generated Prisma Client
import { prisma } from "@/lib/prisma";
reviews.ts;
("use server");
export async function createReview() {
// TODO: create a new Review in the database
}
To flesh out the createReview function, we will use the Prisma Client to create a new Review in the database. We will use the method provided by the Prisma Client to create a new Review. Before we can create a new Review, we need to determine what data we need to provide to create a new Review. In this case, we need to provide the following data:
How do we know what data we need to provide to create a new Review? We can refer to the Prisma schema to determine what fields are required to create a new Review. Let's take a close look at the Prisma schema to determine what fields are required to create a new Review.
schema.prisma
model Review {
id Int @id @default(autoincrement())
name String
rating Int
content String
product Product @relation(fields: [productId], references: [id])
productId Int
}
Any fields that aren't either marked as optional or have a default value are required. In this case, the , , , and fields are required to create a new Review.
Meaning the function needs to take in an argument with a type like this:
interface CreateReviewInput {
name: string;
content: string;
rating: number;
productId: number;
}
export async function createReview(input: CreateReviewInput) {
// create a new Review in the database
}
Now that we know what data we need to provide to create a new Review, we can use the Prisma Client to create a new Review in the database.
// import our generated Prisma Client
import { prisma } from "@/lib/prisma";
Reviews.ts;
("use server");
interface CreateReviewInput {
name: string;
content: string;
rating: number;
productId: number;
}
export async function createReview(input: CreateReviewInput) {
// create a new Review in the database
const newReview = await prisma.review.create({
data: {
name: input.name,
content: input.content,
rating: input.rating,
},
});
return newReview;
}
What we're missing here is the field. We need to associate the Review with a Product. We can do this by providing the to the field in the object.
This is how we can associate different models in Prisma. We can use the field to associate a Review with a Product.
//
export async function createReview(input: CreateReviewInput) {
// create a new Review in the database
const newReview = await prisma.review.create({
data: {
name: input.name,
content: input.content,
rating: input.rating,
product: {
connect: {
id: input.productId,
},
},
},
});
return newReview;
}
Because our schema has a relation between the and models, we can use the field to associate a Review with a Product.
Just like any other function, we need to handle errors that might occur when creating a new Review. We can use a try-catch block to catch any errors that might occur when creating a new Review.
//
export async function createReview(input: CreateReviewInput) {
try {
const newReview = await prisma.review.create({
data: {
name: input.name,
content: input.content,
rating: input.rating,
product: {
connect: {
id: input.productId,
},
},
},
});
return true;
} catch (error) {
console.error("Error creating product:", error);
return false;
}
}
Let's take a look at the "AddReview" form. We can find it in: file.
This is the submit handler for the "AddReview" form:
//
const handleSubmit = (event: any) => {
event.preventDefault();
console.log({ name, rating, review });
};
Just like before, we'll need to modify this function to call the action we just created.
//
const handleSubmit = async (event: any) => {
event.preventDefault();
const success = await createReview({
name,
rating,
content: review,
});
if (success) {
console.log("Review created successfully");
} else {
console.log("Failed to create review");
}
};
Now we're sending the name, rating, and content to our server action. But we're missing the field. We need to pass the to the action.
This component doesn't currently have access to the field. We need to pass the to the component.
If you head over to the page that renders the component, you'll see that the is a prop we get from our params.
We can pass the prop to the component.
Open up and pass the prop to the component.
page.tsx
...
<div classname="md:col-span-2">
<AddReview id={id} />
</div>
Now that we have access to the in the component, we can pass it to the action.
AddReview.tsx
export default function Component({ id }: { id: string }) {
...
const handleSubmit = async (event: any) => {
event.preventDefault();
const success = await createReview({
name,
rating,
content: review,
productId: parseInt(id),
});
if (success) {
console.log("Review created successfully");
} else {
console.log("Failed to create review");
}
};
}
You've done it! You've successfully created a new Review in the database. But what about the caching?
In a previous lesson, I mentioned that we can revalidate the cache after creating a new Review. This will let us see the new Review immediately after creating it, and it will even update our average rating in real-time.
Since we've already set up the server actions to use and given it a tag, we can use the same tag to revalidate the cache after creating a new Review.
reviews.ts;
export async function createReview(input: CreateReviewInput) {
try {
const newReview = await prisma.review.create({
data: {
name: input.name,
content: input.content,
rating: input.rating,
product: {
connect: {
id: input.productId,
},
},
},
});
// simply revalidate our product cache, and
// we'll refetch the product with the new review
revalidateTag("Product");
return newReview;
} catch (error) {
console.error("Error creating product:", error);
throw new Error("Error creating product");
}
}
Now, after creating a new Review, the cache will be revalidated, and we'll see the new Review immediately.
In this lesson, we created a new server action to create a new Review in the database. We used the Prisma Client to create a new Review and associated it with a Product. We also handled errors that might occur when creating a new Review and revalidated the cache after creating a new Review.