Create a movie rating social network (Node.js/PostgreSQL)
Today I will show you how you can create a user based social network where you can add movies with titles and description and with the ability to like/unlike or dislike/undislike movies of other users.
Here you can find the code in a public repository in case you want to watch the final result. I have included detailed installation instructions if you want to run this code locally. You just need a postgreSQL running on your system and node js.
In this tutorial I will not show you how the structure of this application has to be(you can find the details you want in the repository) but I will give you the main concepts you have to grasp to create this kind of implementation.
First of all when you build an application It is necessary to seperate the requirements to different components in order to solve one problem at a time.
When you have a clear approach then you have clear thinking and clean code
According to this approach we have to think the three basic components:
- What Database we will use and why
- What will be the structure of the models
- What authentication mechanism we will use and how to relate It to the Database
Database
I have used postgreSQL because I will have data points that relate to each other. I have also used sequelize for ORM.
We have to create our models to understand the relations between them.
One way to create the models and to understand the relation between other models is to create a logical sentence such as:
A User is able to create a movie and like or dislike other movies. From this sentence we have three models:
A User model that has many movies and a movie model that belongs to User and Rating model that is unique per user and movie.
You can see the models here:
User’s model, Movie model, Rating model
and the lines of code in models/index.js that declares the association between them:
db.movie = require("./movie.js")(sequelize, Sequelize);db.user = require("./user.js")(sequelize, Sequelize);db.rating = require("./rating.js")(sequelize, Sequelize);
//user to moviesdb.user.hasMany(db.movie, { as: "movies" });
//moviesdb.movie.belongsTo(db.user, {foreignKey: "user_id",as: "user"});
Authentication
Now that we have our models in order and especially User Model we can proceed to the authentication part.
For this app I have used passport and specifically passport-github. This module simply lets you authenticate using Github.
You can not find many tutorials on how to authenticate with a third party library and relate It with a database.
The code for the main logic exists in the config/passport.js file and the main logic exists in the lines below:
passport.use(new GitHubStrategy({clientID: GITHUB_CLIENT_ID,clientSecret: GITHUB_CLIENT_SECRET,callbackURL: "/auth/github/callback"}, (accessToken, refreshToken, profile, done) => {
/* Match user */User.findOne({where: {username: profile.username,}}).then(function (user) {
if (user) {return done(null, profile.username);} else {var data ={email: profile.emails[0].value,username: profile.username,};User.create(data).then(function (newUser, created) {if (!newUser) {return done(null, false);}if (newUser) {console.log("newUser", newUser)return done(null, newUser.username);}});}}).catch(function (error) {console.log(">> Error on passport strategy: " + error);});}));
What that code does is that simply checks if the User exists in the database, if not then creates a record to db with username and email taken from his/her github account.
Rating Logic
A very interesting part for this app is the implementation of rating logic and you can find It here.
As you can see there are a lot of things going on but the main logic is that:
if a user has already rated that movie then
check if clicks like (true/false) or dislike(true/false)
check the value of previous record and compare It to the user's value (we need this because we have to know if like will become unlike etc)
update rating and subtract or sum to like_counts and hate_counts in movies table accordinglyelse
create a rating
add +1 if like to like_counts column in movie table or add +1 to hate_counts if not
Final Words
As I have said the main purpose is to represent the main logic and the components of this application. Also this application gives you a skeleton with authentication, sequelize and postgreSQL if you want to create something similar.
If you are more curious about the structure of this application or you want to propose better solution don’t hesitate to create an issue or add It to the comment section here.
Thank you