Created
August 17, 2018 17:53
-
-
Save Veraclins/f71feef3c3736d9a38b9aa8750c61097 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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