Flatiron Phase 2: Sinatra CRUD Project — FlatironHub

Charles Angelo Lai
8 min readJan 10, 2021

The final stretch of Phase 2 in Flatiron’s Software Engineering Bootcamp will have you create a full-stack CRUD application using Sinatra, Active Record, Sqlite3 or PostgreSQL. At this point, you would have gone through and learned how to use Sqlite3, Sinatra (MVC & Forms), Sessions, Active Record, and a bit of HTML & CSS. As I said from my Phase 1 post, make sure to touch up on those modules before and as you tackle this project and don’t forget to ask your cohort-lead for any questions if you’re stuck on something! :)

I’ll be walking you through a step-by-step guide on how I built my project from scratch. Hopefully this guide will be useful to any students currently in Phase 2, upcoming students in Phase 1, or anyone interested in enrolling in Flatiron’s Software Engineering Bootcamp.

Prerequisite Dependencies from Phase 1:

  • Git/GitHub
  • Bundler

What is FlatironHub?

FlatironHub is a Sinatra CRUD application where users will be able to Create, Read, Update, and Delete projects Flatiron students have built throughout the five phases in Flatiron’s Software Engineering Bootcamp. Users will be able to see the students that are currently registered within their cohort, and users will be able to Read, but not Update or Delete another user’s project.

Getting Started

  1. Open your terminal and gem install Corneal
$ gem install corneal

2. Let’s generate the structure of our app using corneal

$ corneal new flatironhub

3. After corneal is done generating our app, run bundle install in our app’s directory.

$ cd flatironhub
$ bundle install

You should have a directory that looks like this:

4. Create a GitHub repository and connect the new GitHub repository to our local repository.

5. Let’s stage, commit, and push our new files into our GitHub repository.

$ git add .
$ git commit -m "initial commit"
$ git push origin master

6. After successfully running everything above without any errors, refresh the page for your GitHub repository and double-check to see that our files have been successfully uploaded into GitHub.

Coding Time!

Creating our Models and Database

We’ll be using corneal to create our models, views and controllers, and database migration files. Our models files and database will handle how the data is stored in our application, and how we associate the data between different models.

The tables and attributes we’re going to need for this project are as follows:

users

  • id (integer)
  • username (string)
  • password_digest (string)
  • f_name (string)
  • l_name (string)
  • email (string)
  • cohort_id (string)

projects

  • id (integer)
  • name (string)
  • description (string)
  • phase_num (integer)
  • website_link (string)
  • github_link (string)
  • blog_link (string)
  • video_link (string)
  • user_id (integer)

cohorts

  • id (integer)
  • cohort_name (string)
  • program (string)
  • time (string)

By default, corneal creates a primary key id of type integer that is auto-incremented for us and assigns the data type of a passed in attribute to a string. To specify the datatype for our attributes, we will have to add attribute:<datatype>.

  1. Run corneal model to create our models and databases.
$ corneal model user username password_digest f_name l_name email cohort_name cohort_id:integer$ corneal model project name description phase_num:integer website_link github_link blog_link video_link user_id:integer$ corneal model cohort cohort_name program time

This should create our models template and have them inherit from ActiveRecord::Base, and create our database migration files and have them inherit from ActiveRecord::Migration.

Now, let’s associate our databases through our models, add some input validations, and password hashing using the methods we have inherited from ActiveRecord.

User

  • has many projects
  • belongs to a cohort
  • validates presence for all attributes

Project

  • belongs to a user
  • validates presence for all attributes
  • checks for uniqueness of username and email

Cohort

  • has many users

2. Run rake db:migrate to create our development database and schema. We should get the file below if everything runs successfully.

3. Create the seeds.rb file which will contain the data we want preloaded into our database when we run our server.

4. Run rake db:seed to load our seed data into our server.

Creating our Views and Controllers

Our controllers will be in charge of handling the HTTP requests from the client and the appropriate responses from server through our RESTful routes.

We will be using the following HTTP verbs:

post

The Create of our CRUD. This method will be utilized to store the data we gather from our forms into post variables.

get

The Read of our CRUD. This method will be utilized to retrieve resources/data from our application, redirecting to the appropriate route and/or retrieving data from our database.

patch

The Update of our CRUD. This method will be utilized to update/modify resources/data we have stored within our database.

delete

The Delete of our CRUD. This method will be utilized (obviously) to delete resources/data from stored within our database.

Run corneal controller with the following arguments.

$ corneal controller users
$ corneal controller projects
$ corneal controller cohorts

This should create our controllers template, have them inherit from Sinatra::Base, create the .html.erb files for each controller, and insert our controllers in our config.ru.

Let’s also add use Rack::MethodOverride into our config.ru. This will allow us to override our forms methods by passing it a hidden input of _method with a value of patch or delete. This is how we will be implementing our Update and Delete requests.

Now, let’s make some modifications to our views and controllers files!

First, let’s modify all of our .html.erb files and change them into .erb files.

For this project, will be using MaterializeCSS as our front-end framework, as well as Font Awesome 4.7, so make sure to add the following lines inside the <head> tag in your layout.erb file.

<!-- MaterializeCSS -->
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<!-- Compiled and minified JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>

<!-- Font Awesome 4.7 -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">

application_controller.rb

Let’s setup our application_controller.rb file with the following code.

users (views & controller)

Let’s add the following code into the respective files inside our views/users folder.

And let’s add this code into our users_controller.rb file.

projects (views & controller)

Let’s add the code below to the respective files inside our views/projects folder.

And let’s add the code below into our projects_controller.rb file.

cohorts (views & controller)

Add the code below to it’s respective files inside our views/cohorts folder.

And add the code below to our cohort_controller.rb file.

And we’re done with the coding!

RESTful Routes and CRUD Flow

In this section, I will breakdown the flow of our RESTful Routes starting from the initial visit to the index page, creating a new user, logging in, viewing your profile, making updates to your profile, creating a new project, making updates to your project, deleting a project, navigating to the cohorts page, viewing the students within each cohort, and viewing the profile and projects of a selected student.

  1. Upon visiting our website, the browser will send a get request with the route of ‘/’. Our server will then render our our index.erb file and send it as a response to the browser.
  2. Upon clicking on “Sign Up” (which should be available in our index page), the browser then sends another get request with the route of ‘/signup’. Our server will then render our signup.erb file and send it as a response to the browser. Once we have successfully submitted a signup form, the browser will then send a post request to the route ‘/signup’. Our controller will then create a user using the post variables from the form, create and save the new user into our database table users, and render our index.erb file with a session stored in the browser which should log us in automatically. If for any reason the user does not save, our controller will then redirect the browser back to the signup page.
  3. At this point, our index page should have a new interface for us and our navigation bar should now have a “Home”, “Profile”, “Projects”, “Cohort”, and “Log Out” option. Upon navigating to the “Profile” page, the client’s browser will send a get request with the route of ‘/profile’ which will render our profile.erb file located within our users folder inside our views. This page should then display our profile information with the option to edit/update our profile.
  4. If we were to press on the “EDIT” button, the browser will send a get request with a route of ‘profile/edit’. This should render our edit.erb file located within our users folder inside our views with each of the input fields filled-in with its current values. If we were to change any values and click on “Update”, the browser will then send a post request which we will be overriding to a patch request with the route of ‘/profile/:username’ and update users attributes located in our users table. If for any reason, the user does not update, the browser will then be redirected back to the edit page.
  5. Upon navigating to the “Projects” page, the browser will send a get request with a route of ‘/projects’. This should render our list.erb file located within our projects folder in our views and should display a list of projects (if there are any).
  6. If we were to press on the “CREATE NEW PROJECT” button, the browser will send a get request with the route of ‘/projects/new’ which should render our new.erb file located within our projects folder in our views. Upon filling up the form and submitting it, the browser will then send a post request with a route of ‘/projects’. Our controller will then create a new instance of a project and store it within our database table projects and redirect us back to our projects with a get request, and render our list.erb page again, listing our newly created project. If for any reason we are not able to submit the form to create a new project successfully, the browser will then redirect us back to ‘/projects/new’.
  7. If we were to decide to edit a selected project, the browser will then send a get request with the route of ‘/project/:id/edit’ and render our edit.erb file located within our projects folder inside our views with the input fields filled-in with its current values. If we were to change any values and submit the form, the browser will then send a post request which we will be overriding to a patch request, update our database with the new values, and redirect us back to ‘projects/show’. This page should display the projects information along with its updated attributes. If for any reason our form to edit does not successfully submit, the browser will then be redirected back to the route ‘/projects/:id/edit’.
  8. If we were to decide to delete a selected project, the browser will then send a post request which we will be overriding to a delete request with the route of ‘/projects/:id’. Our controller will then destroy/delete the project from our database and redirect us back to ‘/projects’.
  9. Upon navigating to our Cohorts page, the browser will then send a get request with the route of ‘/cohorts’. The browser will then render our list.erb file located within our cohorts folder in views, and display a list of the cohorts that are stored inside our database table cohorts. If we were to select a cohort, the browser will then send another get request with the route of ‘/cohorts/:cohort_name’, render our students.erb file located within our cohorts folder in our views, and display a list of students currently registered within that cohort. If we were to select a student within that list, the browser will then send a get request with the route of ‘/profile/:username’ and display that students user information, along with a list of projects they have created.

Click Here for a video walk-through/demonstration of how our website is going to look like and work!

--

--