Beginner’s Guide: Build & Deploy a Web App with Ruby on Rails

Beginner’s Guide: Build & Deploy a Web App with Ruby on Rails

Written by WWC Team

Tech Lifestyle

This post will cover the fundamentals of deploying a single web application as taught in a Women Who Code NYC workshop. Everything should be followed from start to finish through this post.

What we will do

The objective is for everyone to be able to create their own app, push the code to GitHub, and deploy the code to an app on Heroku. This is designed to focus more on concepts of the software development process, and less on the technical pieces of it (ie. coding, version control, etc). We will be building an “About Me” page, so everyone will be able to add to it later on.

Objectives

I can’t stress this part enough: we will be covering A. Lot. in this workshop. This post goes in order, so if you fall behind, you’ll be able to catch up. If you don’t understand a concept, that’s okay. The objective is to expose attendees to different development concepts and get you all familiar with tooling and have a finished product at the end.

Note: There’s a glossary at the end of this post for terms that we may gloss over, but may be helpful to keep in mind.

Prerequisites

  • Create an account on GitHub.
  • Create an account on Heroku with the same email address as your GitHub account. (No need to enter credit card information.)
  • Know what operating system your computer is running. (ie. Mac OS, Windows, etc.)
  • Terminal app and text editor app of your choice available to use on your device.

Install the Tools

You will need 2 command line tools for this workshop: git and heroku-cli. Each operating system will have different instructions as to how to install them.

The commands you are typing are the ones with$ before them.

Note: Scrolls down to Confirm installation of both, if you the tools output versions, you can skip the installation steps.

Install on Mac

I would suggest making installations using Homebrew. It’s a command line tool that will help you install and manage versions of development tools on a Mac computer.

  1. Open Terminal app
  2. Install XCode command line tools
$ xcode-select --install

3. Install brew and run doctor command to look for any issues

$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
$ brew doctor

4. Install git

$ brew install git

5. Install heroku-cli

$ brew tap heroku/brew
$ brew install heroku

Install on Windows

This link here has thorough documentation for installing git on a Windows machine. Additionally, install heroku-cli from this download page. Download the 64-bit installer and follow installation instructions.

Confirm installation of both

Once you have installed each tool, confirm by outputting which version you have of each tool from your Terminal app. Make sure to close any previous Terminals running (for installations) and open a new one.

$ git --version
git version 2.17.0
$ heroku -v
heroku/7.22.9 darwin-x64 node-v11.10.1

It’s okay if some of the versions don’t match up. Also, if you’re experiencing any issues with installation, don’t worry too much. The command line tools are meant to be developer tools, and they have browser equivalents for all the tasks we will perform.

Configure a git user

Using the same email address that you created a GitHub account with.

$ git config --global user.email username@youremail.com
$ git config --global user.name "Full Name"

Log in to Heroku

Using the command line, log in to Heroku. You’ll be prompted to type in the email and password that you registered an account for.

$ heroku login -i
Email: danielle.adams@heroku.com
Password: ******
Logging in... done
Logged in as danielle.adams@heroku.com

Forking a repository

The next part will be to start developing your app. We will be skipping some steps to avoid any issues with local development, but we will be sure to go over the topics.

Fork the original repo on GitHub

I’ve created a repo on GitHub, and you will need to fork the repo on GitHub before you pull it down locally. Visit the original repo here and fork it as shown in the screenshot below. Click the “Fork” button at the top, and fork from your own account.


Once the repo has been forked, clone the repository to your own computer. If you don’t already have a folder where you store code, create one.

$ mkdir ~/Code
$ cd ~/Code

Clone the repo to your local computer

Next, we will clone the repository that you’ve just forked to your local computer. Make sure you are cloning with the URL of your account’s fork.

$ git clone https://github.com/youraccount/wwc-app.git
$ cd wwc-app/

Go ahead and open the code in the text editor of your choice — the commands going forward will need to be in this folder.

The below diagram displays how the forking process happens on GitHub. The fork will live on your GitHub account, and you’ll be able to make modifications to your fork.


Diagram 1: Forking and cloning a repository

If it isn’t already, make sure the remote repository is set up on the local machine with git. Remote will point to your fork on GitHub, so when you’re ready to push code, your computer knows where to push the code to.

$ git remote add master https://github.com/youraccount/wwc-app.git

Confirm that the remote has been set.

$ git remote -v
origin https://github.com/youraccount/wwc-app.git (fetch)
origin https://github.com/youraccount/wwc-app.git (push)

Developing a web application

Now that you have your app locally, let’s go through some of the code! Usually, we would do this with the Rails generators, but due to time restrictions and for the purpose of this workshop, we will simply check out branches that already have application endpoints created for you.

Before we get started, I’d like to give a quick summary of the web application we will be building. We’re going to use the Ruby on Rails framework, which is the library that is used to start a web process and return a web request to any client making requests to the app (ie. browser).


Diagram 2: Web request

Ruby on Rails uses a concept called MVC — short for model, view, and controller. These abstractions describe the different parts of an application’s responsibilities when a web request is made. The models wrap around and interact with the database, the controllers handle the web requests, and the views are what the user sees.


Diagram 3: A web request lifecycle through Rails

In this workshop, we’re going to skip the model layer so we can get our application running quickly.

Create a controller

We’re going to check out to a branch with the controller and view created for your app.

$ git checkout 02-create-controller

We’ve just added our controller and we can create our routes. Your file should look like this:

# app/controllers/about_controller.rb
class AboutController < ApplicationController
end

Create a view

We’re going to add the view files to the app next.

$ git checkout 03-create-view

This will alter our routes file and add a view file for us to customize.

Next, we will need to define the route in the controller. We do this by adding an index method that returns a render of the view we have created. Do this by adding this to the controller:

# app/controllers/about_controller.rb
class AboutController < ApplicationController
  def index
    render :index
  end
end

Now, let’s change the information in our template. We’ll change the header and make some bullet points for fun facts about ourselves. You should change your view file to something like this:

# app/views/about/index.html.erb
<h1>About Me: Danielle</h1>
<ul>
  <li>I have a cat named Dennis.</li>
  <li>I live in Brooklyn.</li>
  <li>I like the card game Sushi Go.</li>
</ul>

Make sure that you use the <h1> tags, which are header tags and be identified as the title for your site. The ul tags create an unordered list, and the litags indicate each list item.

Create the root route

Let’s create the root route. We saw earlier, that a routes file had been altered in the last checkout. Before we move forward though, let’s break down the pieces of a request URL. We’ve all seen a URL in a browser, and each piece plays a role in the request.


Diagram 4: Parts of a web request URL

To put it simply, the host indicates what website, application, or location we are going to; the path will indicate our web application how and where the request will be handled; query params are used to pass data along with the request that is not included in the path.

By setting a root route, we are indicating to the app which route will be the default when a user visits the app. Change your routes file to look like the following:

Rails.application.routes.draw do
  root 'about#index'
  get 'about/index'
end

Check out a branch and commit your changes

Let’s check out a branch for your changes. First, we will create a branch, and then we will stage the changes with git:

$ git checkout -b add-about-me
$ git add app/controllers/about_controller.rb
$ git add app/views/about/index.html.erb
$ git add config/routes.rb

If you run git status, you will see that the changes will be highlighted green. Next, we will want to create a git message that describes the changes we’ve made.

$ git commit -m 'add about me description; add about me as root'

Push changes to GitHub

Now that you’ve committed your changes, you have made the first step in updating your code base. We make changes in a different branch in case something goes wrong and we have to reference the changes we made later. We’re ready to merge our changes to our master branch.

Let’s check back out to master.

$ git checkout master

Next, we will merge the changes from our add-about-me branch and specify a merge message. The -m flag lets us pass in a message (just as we did with our commit).

$ git merge add-about-me -m "Merge add-about-me"

We are now ready to push up to GitHub’s master branch.

$ git push origin master

Confirm that your changes have been pushed up by checking in GitHub. You should be able to see your new changes in the “commits” section.


Now our local and remote repositories are in sync, and we can test our changes in a development environment.

Deploying a web application

The next part will consist of creating resources in Heroku that we can deploy our code to.

Create app and setup git

First, we have to create our Heroku app.

$ heroku create
Creating app... done, ⬢ sleepy-thicket-68616
https://sleepy-thicket-68616.herokuapp.com/ | https://git.heroku.com/sleepy-thicket-68616.git

This has created an app in your Heroku account, as well as added a new remote to our git configuration. We can look at our remotes to see the new configuration:

$ git remote -v
heroku https://git.heroku.com/sleepy-thicket-68616.git (fetch)
heroku https://git.heroku.com/sleepy-thicket-68616.git (push)
origin https://github.com/danielleadams/wwc-app.git (fetch)
origin https://github.com/danielleadams/wwc-app.git (push)

Heroku will assign a unique app name for you — mine is sleepy-thicket-68616 — we’ll see why this is important in a bit.

Push your code to Heroku

Heroku uses git as a local deployment tool. You will be able to take a repository from your local device and push it up to Heroku, which will build and deploy your application to the cloud.

$ git push heroku master

This may take a few minutes as there will be a log of each step to your terminal.

remote: -----> Compressing...
remote:        Done: 41.6M
remote: -----> Launching...
remote:        Released v1
remote:        https://sleepy-thicket-68616.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.

Once your push logs have reached this line, your deployment is completed!

Create resources

We can think of our Heroku app as a grouping of all the resources we will need in order to run a web application (ie. web process, database, etc). We will now need to create a web dyno for our web server to run on.

$ heroku ps:scale web=1

Check out the logs

Let’s run the logs to see what state the app is in. Make sure to replace my app name with the one Heroku created for you.

$ heroku logs --tail -a sleepy-thicket-68616

The last few lines of the logs should look something like this:

2019-04-17T04:38:49.000000+00:00 app[api]: Build succeeded
2019-04-17T04:38:50.315173+00:00 heroku[web.1]: Starting process with command `bin/rails server -p 38802 -e production`
2019-04-17T04:38:56.931090+00:00 heroku[web.1]: State changed from starting to up

This indicates that the build succeeded and the app has booted up. You’re able to visit your app at a URL that will have yourwebsitename.herokuapp.com (ie. sleepy-thicket-68616.herokuapp.com). Visit the page, and you’ll see more logs output.

Congratulations — you have created and deployed your own app!

Understanding monitoring

I added this portion on here because I think it’s pretty cool. It is optional though, and I’m not sure if we will get to it in the workshop. It’s a combination of what Heroku outputs and the Rails app that has been deployed outputs to the logs. Make sure you are still running the logs.

$ heroku logs --tail -a sleepy-thicket-68616
  1. Visit your site URL.
  2. Find the first line that says STARTED "/about/index". This is the line the request starts.
2019-04-17T04:39:09.711205+00:00 app[web.1]: I, [2019-04-17T04:39:09.711037 #4]  INFO -- : [f5243aeb-cab6-471c-8791-e1c47e0cbd1a] Started GET "/about/index" for 71.167.150.23 at 2019-04-17 04:39:09 +0000

3. On the next line (below), we will see that our controller has been accessed and we are hitting the index route that we defined.

2019-04-17T04:39:09.712513+00:00 app[web.1]: I, [2019-04-17T04:39:09.712448 #4]  INFO -- : [f5243aeb-cab6-471c-8791-e1c47e0cbd1a] Processing by AboutController#index as HTML

4. After that, we see that the view is rendered and the request is complete.

2019-04-17T04:39:09.726285+00:00 app[web.1]: I, [2019-04-17T04:39:09.726221 #4]  INFO -- : [f5243aeb-cab6-471c-8791-e1c47e0cbd1a]   Rendered about/index.html.erb within layouts/application (0.7ms)
2019-04-17T04:39:09.728874+00:00 app[web.1]: I, [2019-04-17T04:39:09.728805 #4]  INFO -- : [f5243aeb-cab6-471c-8791-e1c47e0cbd1a] Completed 200 OK in 16ms (Views: 6.2ms)

5. The line after that is different — this is the routing layer that returns the request. As we saw in Diagram 2, a web request is made to the app, but an app can have 10s or 100s of processes. The Heroku router will decide which process handles the request and return the response.


Final thoughts

Hopefully, this workshop was helpful. It’s a lot of new concepts, but exposure to these topics over time will make them easier to digest. You’ve now learned some of the foundational pieces of what goes into the software development process and the tools to learn more in-depth about each step.


Glossary

  • deploy: take compiled code and other artifacts, copy them to a service space and execute them.
  • dyno: a container in a Heroku app that runs code.
  • git: a version management tool that includes working off of branches and merging to a “master” branch.
  • GitHub: a platform that uses git to manage multiple contributors to a code base that is hosted in the cloud.
  • Heroku: a platform that allows developers to build and deploy their own applications with little overhead.
  • master (or master branch): the branch name that is usually used to indicate the current state of a code base that developers create branches off of.
  • push: name of the method git uses to sync up a local repository (ie. on your computer) with a remote repository (ie. on GitHub).
  • Rails: a web application framework built with Ruby that provides abstractions for the database, a web service, and web page views (or data responses).
  • Ruby: a general-purpose, object-oriented language that was created to focus on simplicity and productivity.
  • route: the URL path that comes after the host (ie. heroku.com) that tells the web application which controller and method the request should be handled.

Original post published on Medium here