Sinatra Project Movie-Review

Posted by Juny McArdle on August 17, 2019

I really enjoyed completing this project and felt I learned more than our initial project with CLI. I also felt more comfortable because I had a better grasp and understanding of what was necessary to finish it. It’s a simple application and I was able to accomplish it with the requirements listed below:

 - MVC(Model View Controller)
 - RESTful routes
 - ActiveRecord(Models, Associations)
 - A sqlite database
 - Login/Logout

This project is building a simple Content Management System (CMS) utilizing the tools we’ve learned so far. The application is capable of alllowing users to register/sign up with a username and password. Once they have registered an account they are able to create, edit, or delete their own movie review posts. They can modify their own entries, but are limited to viewing other user’s posts.

The code below was used to set this application up:

Setting Up

Structure

I had to create all the files and folders from scratch. Here’s what MVC structure looks like:

 
├── app
│   ├── controllers
│   │   └── application_controller.rb
│   │   └── movies_controller.rb
│   │   └── reviews_controller.rb
│   │   └── users_controller.rb
│   ├── models
│   │   └── movie_review.rb
│   │   └── movie.rb
│   │   └── user.rb
│   └── views
│          ├── movies
│          │   └── index.erb
│          │   └── show.erb
│          ├── reviews
│          │   └── edit.erb
│          │   └── index.erb
│          │   └── new.erb
│          ├── users
│          │   └── home.erb
│          │   └── login.erb
│          │   └── signup.erb
│          ├── error.erb
│          ├── index.erb
│          └── layout.erb
├── config
│   └── environment.rb
├── db
│   ├── migrate
│   └── seeds.rb
├── public
│   └── css
│   └── style.css
├── config.ru
├── Gemfile
├── README.md
├── Rakefile
└── spec.md

Gemfile

Add all these required gems for the application below and simply type bundle install in your terminal then it will install all the gems including the Gemfile.lock.

source 'http://rubygems.org'

gem 'sinatra'
gem 'activerecord', '~> 4.2', '>= 4.2.6', :require => 'active_record'
gem 'sinatra-activerecord', :require => 'sinatra/activerecord'
gem 'rake'
gem 'require_all'
gem 'sqlite3', '~> 1.3.6'
gem 'thin'
gem 'shotgun'
gem 'pry'
gem 'bcrypt'
gem 'tux'

group :test do
  gem 'rspec'
  gem 'capybara'
  gem 'rack-test'
  gem 'database_cleaner', git: 'https://github.com/bmabey/database_cleaner.git'
end

MVC (Model View Controller)

Model : The logic of a web application

The model is where data is managed. Models represent the data required for an application to work using ActiveRecord. The User class has write and edit permissions to the MovieReview class. The Movie class contains all the reviews that end-users write. The User and Movie class is related with the MovieReview class through the has_many ActiveRecord association. MovieReview belongs to User and Movie. These associations work and successfully runs applications by using ActiveRecord making it very convenient.

 class MovieReview < ActiveRecord::Base
    belongs_to :user
    belongs_to :movie
end

class Movie < ActiveRecord::Base
    has_many :movie_reviews
    has_many :users, through: :movie_reviews
end

class User < ActiveRecord::Base
    has_secure_password
    has_many :movie_reviews
    has_many :movies, through: :movie_reviews
end

View : The ‘front-end’, user-facing part of a web application

The front-end or user-facing portion of an application is where the end-user interacts directly with an application. Views are generally made of HTML and CSS code. Sinatra uses erb files (Embedded Ruby) to dynamically create html web pages and serve requested content through the browser. The Views correspond to the routes/actions in the associated controllers so there are Views for showing movie lists/reviews, displaying sign-up or login forms etc.

<form method="post" action="/reviews">
   Movie Name : <input type="text" name="movie_name">
   <br><br>
   Review : <textarea name="review" id="review" cols="30" rows="5"></textarea>
   <br><br>
   Rate : 1<input type="radio" name="rate" value="1">
          2<input type="radio" name="rate" value="2">
          3<input type="radio" name="rate" value="3">
          4<input type="radio" name="rate" value="4">
          5<input type="radio" name="rate" value="5">
   <br><br>
   <input type="submit" value="Submit">
   <br>
   <p> <a href="/home">Home</a> </p>
</form>

Controller : The go-between for models and views.

The controller bridges data between the application and the browser. Separated controllers for each model help organize all the different routes and actions an application can use.The users_controller controls signup/login and home routes. The movie_controller focuses on the movie list and individual movie reviews. The reviews_controller handles the most of the applications functionality to include, CRUD or the posting, editing, and deleting review functions. The application_controller inherits the configure , helpers and other methods so they do not need to be repeated in every controller.

require "./config/environment"

class ApplicationController < Sinatra::Base

    configure do
        set :views, 'app/views'
        set :public_folder, 'public'
        enable :sessions
        set :session_secret, "password_security"
    end

    helpers do
      def logged_in?
         !!session[:user_id]
      end

      def current_user
			   User.find_by(id: session[:user_id])
      end

     def authorize
         if !logged_in? || current_user.nil?
             redirect '/login'
         end
     end

     def clean(text)
         Rack::Utils.escape_html(text)
     end
		     
   end

    get '/' do
        erb :index
    end

    not_found do
        @msg = "This resource was not found."
        status 404
        erb :error
    end

end

Environment

config.ru

In order to run the application successfully it would require me to have all the files and code, but also ensure that the environment is set up correctly.

require './config/environment'

if ActiveRecord::Migrator.needs_migration?
  raise 'Migrations are pending. Run `rake db:migrate` to resolve the issue.'
end

use Rack::MethodOverride
use ReviewsController
use MoviesController
use UsersController
run ApplicationController

After everything is set up correctly I run the application by typing the following command:

 > shotgun

This summarizes the main part of the Sinatra project.

Conclusion

Using ActiveRecord made this project incredibly easier to complete because of things like RESTful route that make data manipulation easier. At times I was confused, but towards the end of the project all the concepts seemed to come together and make more sense. I have to admit that coding in itself is definitely a challenge combined with the language barrier makes everything more of a struggle, but it also makes completing something that more satisfying. With each struggle and overcoming each obstacle I am getting closer and closer to my end goal of becoming a developer.