Building a Rails app. Part 1: Installation, Setup and Deploy
Tags: ruby, rails
Published: 2018-10-29 22:37:34

---
title: Building a Rails app. Part 1: Installation, Setup and Deploy
published: true
description: First article to learn how to use Rails to make a application
tags: ruby, rails
---

# Introduction

In this article series, we will make, step by step, a fully functioning web application to learn Ruby on Rails. I always found it more helpful to make something "real" while learning something new. This series' goal is to do just that: help me (and you, if you end up reading it) learn Rails faster and better. So, now that we know why I'm trying this, here comes the question: what do we create?

I chose to make an online shop. This application will sell sneakers. I've almost created something along those lines in the past, in a different stack, but it ended up as a missed opportunity. This time, it's just for the sake of learning how to use Rails. Let's jump right into it!


# Installation

Before we start writing some code, we need to make sure we have all the tools at our disposal. To get started, we will need three things: *Ruby* ( the language behind the Rails framework ), *Rails* ( well, obviously...) and *git* ( to deploy our application and keep track of our changes ).

If you know you already have those tools, you can skip this and go to the **Setup** section.

## Installing Ruby

### Windows

For windows users, you can visit the following <a href="https://rubyinstaller.org/" target="_blank">link</a>. Click the download button and chose the first link under **WITH DEVKIT**. Download, follow the steps and open a terminal window to check your ruby version:

```
>ruby -v
ruby 2.5.3p105 (2018-10-18 revision 65156) [x64-mingw32]
```

### MacOS

On MacOS, depending on the one you have, you probably have Ruby installed already. Check in your terminal with `ruby -v`. If that's not the case, install <a href="https://brew.sh/" target="_blank">Homebrew</a> and run `brew install ruby` in your terminal.  After that, run `ruby -v` and you should see something resembling this:

```
>ruby -v
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin17]
```


## Installing Rails

Now that we have Ruby, we need to get the Rails framework. In Ruby, we call a package a *gem*. To install a gem, you use the command *gem install [packageName]*.  The gem command is provided by the package manager *RubyGems*. So, in our case, open a terminal window and run: *gem install rails*. Just like before with Ruby, you can check if Rails has been installed by checking its version:
  
```
rails -v
Rails 5.2.1
```
  
*Note: For the rest of the series, I will use this Rails version*
  
## Installing Git
  
  Finally, we need to install *git*. Git is a popular version control system (VCS). A VCS makes it easy to collaborate with others, share and backup your code.
  
### On Windows
  
  For Windows users, you can download Git from this <a href="https://git-scm.com/downloads" target="_blank">page</a>. Install and follow the steps with the defaults and all should be good. After that, run the command `git` in your terminal and you should see something like this:
  
  ```
  >git
usage: git [--version] [--help] [-C <path>] [-c <name>=<value>]
           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]
           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
           <command> [<args>]

These are common Git commands used in various situations:

start a working area (see also: git help tutorial)
   clone      Clone a repository into a new directory
   init       Create an empty Git repository or reinitialize an existing one

work on the current change (see also: git help everyday)
   add        Add file contents to the index
   mv         Move or rename a file, a directory, or a symlink
   reset      Reset current HEAD to the specified state
   rm         Remove files from the working tree and from the index

examine the history and state (see also: git help revisions)
   bisect     Use binary search to find the commit that introduced a bug
   grep       Print lines matching a pattern
   log        Show commit logs
   show       Show various types of objects
   status     Show the working tree status

grow, mark and tweak your common history
   branch     List, create, or delete branches
   checkout   Switch branches or restore working tree files
   commit     Record changes to the repository
   diff       Show changes between commits, commit and working tree, etc
   merge      Join two or more development histories together
   rebase     Reapply commits on top of another base tip
   tag        Create, list, delete or verify a tag object signed with GPG

collaborate (see also: git help workflows)
   fetch      Download objects and refs from another repository
   pull       Fetch from and integrate with another repository or a local branch
   push       Update remote refs along with associated objects

'git help -a' and 'git help -g' list available subcommands and some
concept guides. See 'git help <command>' or 'git help <concept>'
to read about a specific subcommand or concept.
  ```
  
### On MacOS
  
  On MacOS, we can use *Homebrew* to install Git. We already installed it because we needed it to install Ruby. So, we can run `brew install git` to install the VCS. You should see the same text above when you run `git` in a terminal command.
  
  
# Setup
  
  Now that we have all the tools we need, we can start setting up our new application. In this section, we will create a new bare Rails application and quickly explore what we have to work with. To create a new Rails app, we use the `rails new myAppName` command. So, move to a directory where you want to create your app and run `rails new sneakers_store`.  After creating a whole bunch of new files, you should see something like:
  
  ```
  Bundle complete! 16 Gemfile dependencies, 77 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
  ```
  Now, you can move into the Rails application directory with `cd sneakers_store` and open it in your favorite editor to take a peak!
  
## Exploring the application
  
  As you can see, there are a LOT of files and folders there. We won't go into the details of each one right now, because it's not necessary. We'll tackle them when we will need them. But you already have a functional application ( that doesn't do much yet ;) )  Let see some of the files and folders we have:
  
  
### Gemfile
  
  One of the files you will find in this application in called *Gemfile*. If you come from Javascript, this is like a package.json. It lists the package requirements for this application. As you can see, there are already quite a few *gem* required for our little application. You'll notice that there is a strange operand in the file *~>*. It tells the bundler ( in charge of loading the required gems ) which gem versions he is allowed to load. For instance, I have:
  
  `gem 'rails', '~> 5.2.1'`
  
  This means that my app is allowed to use a Rails version superior to 5.2.1 but inferior to 5.3.0. Basically, it will only get minor patches for this gem. If you want an exact version, you can remove the *~>*.
  
### app/ directory
  
  The *app* directory contains the core application code: models, views, controllers and helpers. There is a *assets/* folder inside of it that contains the application's assets such as CSS, images or Javascript.
  
### config/ directory
  
  The *config* directory contains the application configuration. This is where you are going to find our router for example.
  
### test/ directory
  
  No surprises here, this is where our application's tests will be written.
  
## Bundler
  
  *Bundler* is the tool that manages your application's gems. Earlier, I explained that the *~>* syntax in your Gemfile is about what gem versions we allow in our app. Well, *Bundler* handles managing those dependencies to make sure our development environment is stable. *Bundler* will install the exact gem versions we need to make sure our application runs smoothly.
  
  When you run *rails new*, the command `bundle install` is run automatically. Each time you make changes to your Gemfile ( adding a new gem, changing a gem's version ), make sure to run `bundle install` to take the changes into account.
  
  For the sake of argument, let's just say that I want my rails version to be **exactly** 5.2.1. I don't wan't any minor patches updates. So, I'll replace the following line in my Gemfile:
  
  `gem 'rails', '~> 5.2.1'`
  
  by:
  
  `gem 'rails', '5.2.1'`
  
  You remove the *~>* and that indicates you wish an exact version for the gem.  Another syntax you might encounter is the following: `gem 'rails', '>= 5.2.1'`.

  *>=* means: take the latest version of this gem, as long as this version is greater or equal than the version number provided. In our case, we ask bundle to get the latest rails gem version, as long as the gem version is greater or equal to 5.2.1.
  
  Now, run `bundle install`. *Bundle* will install new gems and/or update gems if necessary. It's possible that you are asked to run `bundle update` first. If that's the case, run `bundle update` then `bundle install`.
  
  So, whenever we are making a change to our Gemfile, make sure to run `bundle install`.
  

### rails server

Because we ran `rails new`, we already have a application we can run. We run a Rails application with `rails server`. Something like this should appear in your terminal:

```
 > rails server
=> Booting Puma
=> Rails 5.2.1 application starting in development
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.12.0 (ruby 2.5.1-p57), codename: Llamas in Pajamas
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop
```
 Great! Your application is running on port 3000 now. If you visit http://localhost:3000 in your browser, you will see:
 
 <img src="https://thepracticaldev.s3.amazonaws.com/i/0z6feea2y9x12ak2w5ke.png" />
 
 Awesome, everything is ready for us to start coding. But before that, we'll go though a little more of high level theory to understand Rails better.
 
## An MVC tale
 
 The Rails framework follows  the model-view-controller architectural pattern. The *model* is responsible for the application's data and its logic. The model represents the the universe in which the application lives. It defines what the user informations are for example, or updates the database. The *view* is what you see on the browser. The view uses the model and display an interface. Finally, the *controller* acts as an intermediary between the view and the model. It handles the user's actions and changes the model and view's data.
 
 When you load localhost:3000, a request is sent. That request is sent to the controller. Depending on the code written, the controller might immediately render a view, or interact with a model. After interacting with the model, which can fetch data from the database from example, the controller renders a view with the data gathered.
 
 This calls for a very simplistic schematic representation:
 
 <img src="https://thepracticaldev.s3.amazonaws.com/i/y86puz7rxorjgph3a7gj.png"/>
 
 As you can see, the controller sits in the middle of everything. If you look inside tour app/ folder, you have the distinctions between the three types of modules ( controllers/, models/, and views/ ). Let's create our first controller.
 
## Our first controller
 
 To follow the ancient traditions of our people, we have to create an application that say "Hello World!" at some point. Let's do just that. In our controllers folder, let's create a new file called *firstcontroller_controller.rb*. Let's put the following code inside:
 
 ```ruby
class WelcomeController < ApplicationController
	protect_from_forgery with: :exception

	def greeting
		render html: "Hello World!"
	end
end

```
**Note:** Controllers file names should end with *_controllers.rb* and classes end with *Controller*.

Don't worry to much about the syntax right now. We created a class called WelcomeController that inherits from the ApplicationController. Inside a controller, you can define actions. An action is a public method on the controller, and it is automatically accessible to the web server. Here, I just created an action called *greeting*. Because Ruby reads almost like English, you can guess what this action does: it renders some HTML: "Hello World!". But that is not enough yet to render our HTML string to a view. For that, we need to modify the router.

### Modify the router

The router can be found in *config/routes.rb*. Open that up and replace the file's content with the following:

```ruby
Rails.application.routes.draw do
	# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
	root "welcome#greeting"
end
```

We want to make sure the root route uses our new controller. If you follow the link above, you can see the documentation to configure the root route. The syntax is the following:

`root controller_name#action_name`

Our controller name is *welcome* and our action name is *greeting*. Save the file and refresh your browser:


<img src="https://thepracticaldev.s3.amazonaws.com/i/vx8l2gn8jy7rfyj7nhky.png" />

 Great! This is a good start. Now, let's deploy our application!
 
# Deploy
 
 The first thing we need to do is to create our git repository. Navigate to the root of the sneakers_store directory and run `git init`. You should see something like:
 
 ```
 ➜  sneakers_store git:(master) ✗ git init
Reinitialized existing Git repository in /Users/Damien/Desktop/ruby/sneakers_store/.git/
 ```
 
 Now, run `git add .` followed by `git commit -m 'first commit'`. The first command will add all the current files to your repository and place them in a *staging area*. This is pretty much pending changes, the second command indicates the we are sure we want to keep the changes, so we commit them, with a message.
 
 We are going to deploy our application with Heroku. This step is optional but I find it easier to deploy early and often.
 
## Heroku setup
 
 Heroku uses the PostgresQL database. So, this means that we can't use the default sqlite3 we have at the moment. This means we need to change our Gemfile. Here is how it should look like:
 
 ```ruby
 source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.5.1'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.2.1'
# Use Puma as the app server
gem 'puma', '~> 3.11'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'mini_racer', platforms: :ruby

# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.2'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.5'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use ActiveStorage variant
# gem 'mini_magick', '~> 4.8'

# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.1.0', require: false

group :development, :test do
	gem 'sqlite3'
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '>= 3.0.5', '< 3.2'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end

group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '>= 2.15'
  gem 'selenium-webdriver'
  # Easy installation and use of chromedriver to run system tests with Chrome
  gem 'chromedriver-helper'
end

group :production do
 gem 'pg'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

 ```
  
  Notice that we removed the sqlite3 gem from the first list to include it in the *group :development, :test*. The gem *pg* ( for PostgresQL ) is included in the *:production group*. Rails lets you specify which gems you need for the different environments. The first list being the gems that are always loaded in each environment.
  
  Now, because we changed our Gemfile, we need to run Bundle again. But, this time, we will add a flag to prevent the installation of the production gems in our local environment:
  
  `bundle install --without production`
  
  This will not install the *pg* gem.
  
  Lets re-run `git add .` . Then run `git commit -m 'Updated Gemfile for production'`.
  
## Heroku CLI
  
  Now, you can <a href="https://signup.heroku.com/login" target="_blank">sign up</a> for Heroku. Next, download the <a href="https://devcenter.heroku.com/articles/heroku-cli" target="_blank">Heroku CLI</a>. When that is done, check that you have Heroku installed by running `heroku --version` in a terminal.
  
  ```
  ➜  sneakers_store git:(master) ✗ heroku --version
heroku/7.0.52 darwin-x64 node-v10.1.0
  ```
  
  Next, run `heroku login` and enter your credentials. Then, run `heroku keys:add`.
  
  Now, we can create a place on Heroku for our application by running`heroku create`.
  
  ```
  ➜  sneakers_store git:(master) ✗ heroku create
Creating app... done, ⬢ aqueous-peak-82306
https://aqueous-peak-82306.herokuapp.com/ | https://git.heroku.com/aqueous-peak-82306.git
  ```
  
  This is the subdomain just for your application. Of course, it will have a different name than mine.
  
## Deployment on Heroku
  
  To deploy on Heroku, run `git push heroku master`. You'll see a bunch of stuff appear in your terminal. When it is done, you can go to your Heroku account dashboard and see your application's subdomain name. Click on it, then click *Open app* on the top right. And this is what you'll see:
  
  <img src="https://thepracticaldev.s3.amazonaws.com/i/vxmdqniap6zhfwuo5yvp.png" />
  
  
  Congratulations! You just deployed your first Rails application on Heroku and you learned how to make your first controller!