Create a movie rating social network (Node.js/PostgreSQL)
By: Theodore Monk
Tags: Postgresql, Nodejs, Postgres, Github, Technology

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 movies db.user.hasMany(db.movie, { as: "movies" });

//movies db.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 accordingly else

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