Skip to content

Instantly share code, notes, and snippets.

@Veraclins
Created August 17, 2018 17:53
Show Gist options
  • Save Veraclins/f71feef3c3736d9a38b9aa8750c61097 to your computer and use it in GitHub Desktop.
Save Veraclins/f71feef3c3736d9a38b9aa8750c61097 to your computer and use it in GitHub Desktop.
import models from '../models';
const { Article, Rating } = models;
/**
* This class contains all the methods responsible for rating
* articles on the app
* It is made up static methods which can be called from anywhere in the app.
*/
export default class articleRatingController {
/**
* Prepares the the information needed to rate the article. It also checks that
* a user does not rate his/her own article
* @param {object} req the request object
* @param {object} res the response object
*/
static prepRating(req, res) {
const { id: userId, username } = req.user;
const { slug, rating, author } = req.params;
if (username === author) {
return res.status(403).send({
status: 'error',
errors: 'You cannot rate your own article',
});
}
let value = rating < 1 ? 1 : rating;
value = value > 5 ? 5 : value;
return {
userId, slug, value
};
}
/**
* Rate an article and return the rating (number of stars).
* @param {object} req the request object
* @param {object} res the response object
*/
static rateArticle(req, res) {
const ratingInfo = articleRatingController.prepRating(req, res);
const { slug } = ratingInfo;
if (!slug) return;
Article.findOne({
where: { slug },
attributes: ['id'],
})
.then((article) => {
if (!article) {
return res.status(404).send({
status: 'error',
errors: {
article: ['No article with the given URL. Please check the URL again']
}
});
}
const { id: articleId } = article.dataValues;
articleRatingController.processTheRating(articleId, ratingInfo, res);
});
}
/**
* Rate an article and return the rating (number of stars).
* @param {object} req the request object
* @param {object} res the response object
*/
static processTheRating(articleId, ratingInfo, res) {
const { userId, value } = ratingInfo;
Rating.findOne({ where: { articleId, userId } })
.then((rating) => {
if (!rating) {
return Rating.create({ userId, articleId, value })
.then(newRating => articleRatingController.ratingResponse(newRating, res));
}
return Rating.update({ value }, {
returning: true,
where: { articleId, userId },
})
.then(([, [updatedRating]]) => {
articleRatingController.ratingResponse(updatedRating, res, true);
});
});
}
/**
* Prepares the response to be sent to the user.
* @param {object} rating the rating object returned from the database
* @param {object} res the response object
* @param {boolean} updated a boolean that indicates if it is a new rating or an
* updated rating (used to set the appropriate status code)
*/
static ratingResponse(rating, res, updated = false) {
const statusCode = updated ? 200 : 201;
return res.status(statusCode).send({
status: 'success',
message: `rating ${updated ? 'updated' : 'created'} successfully`,
ratings: {
id: rating.id,
userId: rating.userId,
value: rating.value,
articleId: rating.articleId,
},
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment