-
How can I create something akin to a "user rating" feature? I.e., each user can create and edit their own row for each article, either as a many-to-many relationship I couldn't find a way to constrain the [article_id, user_id] pair to be unique. Is something like a composite key unique constraint possible? Also, how would I display the 5-stars widget for the current user to be able to rate the article in the admin edit page? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
@vibl You could create a To make them unique you could create a hidden field (set it to unique in the config) and use a beforeValidate hook to generate the value for that field by concatenating the userID and the articleID. To display it on an article page within the admin panel, you could create a custom How does that sound to you? |
Beta Was this translation helpful? Give feedback.
-
I'd approach it this way:
Something like this: const ProductsCollection: CollectionConfig = {
slug: 'products-for-rating',
labels: { plural: 'Products' },
admin: {
group: 'Rating',
useAsTitle: 'productName'
},
fields: [
{
name: 'productName',
type: 'text',
}
],
} const RatingsCollection: CollectionConfig = {
slug: 'ratings',
admin: {
group: 'Rating',
},
fields: [
{
name: 'product',
type: 'relationship',
relationTo: 'products-for-rating',
validate: async (val, { user }) => {
const query = qs.stringify({
where: {
and: [
{
product: { equals: val }
},
{
user: { equals: user.id }
}
]
}
}, { addQueryPrefix: true })
const response = await fetch(`http://localhost:3000/api/ratings${query}`)
const sameRating = await response.json()
if (!sameRating.totalDocs) {
return true;
}
return 'You have already rated this product.';
},
},
{
name: 'rating',
type: 'number',
min: 1, max: 5,
// admin: {
// components: {
// Field: FiveStarsField
// }
// }
},
{
name: 'user',
type: 'relationship',
relationTo: 'users',
admin: {
readOnly: true
},
},
],
access: {
read: ({ req: { user }, id }) => {
return {
user: {
equals: user.id
}
}
}
},
hooks: {
beforeChange: [async ({
data,
req,
}) => {
data.user = req.user.id
return data;
}]
}
} To show the 5-stars field you can provide a custom Field Component to the If I understand your problem correctly, this work for me, but I'm curious to know if there's a better approach. |
Beta Was this translation helpful? Give feedback.
I'd approach it this way:
beforeChange
hook onRatingCollection
to save the user who is rating in a readonly or disabled fieldaccess:read
function to show the user only his own ratingsvalidate
function on theproduct
relation to check the uniqueness of the [user, products] ratingSomething like this: