Deploy Ruby on Rails on Heroku
Tags: heroku, ruby, rails
Published: 2021-01-31 20:55:02

My first deployment with Heroku did not go as smoothly as I anticipated. I decided to document and share my Heroku journey. I can only share some of the hurdles from my [Plan My MD Visit](https://dev.to/codinghall/plan-my-md-visit-c0l) app. Previously, the project was built and completed by running '[http://localhost:3000/](http://localhost:3000/)'. My recommendation to fellow developers would be to deploy early and debug as you progress through the project. It is more time efficient than discovering a large number of glitches near the end of the project.

### **First things first**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qryg5a4i471z361fyw4t.png)

Sign Up with [Heroku](https://signup.heroku.com/). 

It provides free cloud services for developers to run their applications. Make sure you read their [provisions](https://www.heroku.com/free) for their free platform services.

### **SQLite > PostgreSQL**

If your application is currently running on SQLite database, there are two action items:

`Gemfile` and *SQL query in PostgreSQL*.

Gem `sqlite3` will be decommissioned, and replaced by gem `pg`. 

```ruby
# gem 'sqlite3', '~> 1.4'
gem 'pg'
```

Run `bundle install`. 

We will circle back to *SQL query in PostgreSQL*.

### **Update `config/database.yml`**

This file was created by default when we initiated the Rails app with `$ rails new app-name`. Rails provides a database with `sqlite3` adapter, and its pre-built code as follows:

```ruby
# SQLite. Versions 3.8.0 and up are supported.
#   gem install sqlite3
#
#   Ensure the SQLite 3 gem is defined in your Gemfile
#   gem 'sqlite3'
#
default: &default
  adapter: sqlite3
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  timeout: 5000

development:
  <<: *default
  database: db/development.sqlite3

# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
  <<: *default
  database: db/test.sqlite3

production:
  <<: *default
  database: db/production.sqlite3
```

We need to adjust it for `postgresql`. While perusing [Heroku documentation](https://devcenter.heroku.com/articles/rails-database-connection-behavior) and [GitHub gist](https://gist.github.com/jwo/4512764), I was able to revise my code in `config/database.yml`.

```ruby
# PostgreSQL. Versions 8.2 and up are supported.
#
# Install the pg driver:
#   gem install pg
# On Mac OS X with macports:
#   gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config
# On Windows:
#   gem install pg
#       Choose the win32 build.
#       Install PostgreSQL and put its /bin directory on your path.
#
# Configure Using Gemfile
# gem 'pg'
#
development:
  adapter: postgresql
  encoding: unicode
  database: app-name_development
  pool: 5
  username: your_username
  password:

  # Connect on a TCP socket. Omitted by default since the client uses a
  # domain socket that doesn't need configuration. Windows does not have
  # domain sockets, so uncomment these lines.
  #host: localhost
  #port: 5432

  # Schema search path. The server defaults to $user,public
  #schema_search_path: myapp,sharedapp,public

  # Minimum log levels, in increasing order:
  #   debug5, debug4, debug3, debug2, debug1,
  #   log, notice, warning, error, fatal, and panic
  # The server defaults to notice.
  #min_messages: warning

# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
  adapter: postgresql
  encoding: unicode
  database: app-name_test
  pool: 5
  username: your_username
  password:
```

**This is important.** `git push`, and always try to maintain latest repo files in your GitHub account.

### **Heroku CLI**

Follow the initial [Heroku CLI setup](https://devcenter.heroku.com/articles/heroku-cli#download-and-install). Once installed, you can type `$ heroku login` on the terminal. You will receive a return feedback as displayed below.

```ruby
$ heroku login
$ heroku: Press any key to open up the browser to login or q to exit:
$ Opening browser to https://cli-auth.heroku.com/auth/cli/browser/...?requestor=...
$ Logging in... done
$ Logged in as your_email@email.com
$ ...
```

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/72do04f2n7z1or27a1pn.png)

It will then navigate you to Heroku web browser to log in. You may close the web page after you successfully log in, and return to VSCode terminal. With `heroku` command prompt, you will see Heroku Command Line Interface.

```ruby
$ heroku 
	CLI to interact with Heroku
	
	VERSION
	  heroku/7.47.11 darwin-x64 node-v12.16.2
	
	USAGE
	  $ heroku [COMMAND]
	
	COMMANDS
	  access          manage user access to apps
	  addons          tools and services for developing, extending, and operating your app
	  apps            manage apps on Heroku
	  auth            check 2fa status
	  authorizations  OAuth authorizations
	  autocomplete    display autocomplete installation instructions
	  buildpacks      scripts used to compile apps
	  certs           a topic for the ssl plugin
	  ci              run an application test suite on Heroku
	  clients         OAuth clients on the platform
	  config          environment variables of apps
	  container       Use containers to build and deploy Heroku apps
	  domains         custom domains for apps
	  drains          forward logs to syslog or HTTPS
	  features        add/remove app features
	  git             manage local git repository for app
	  help            display help for heroku
	  keys            add/remove account ssh keys
	  labs            add/remove experimental features
	  local           run Heroku app locally
	  logs            display recent log output
	  maintenance     enable/disable access to app
	  members         manage organization members
	  notifications   display notifications
	  orgs            manage organizations
	  pg              manage postgresql databases
	  pipelines       manage pipelines
	  plugins         list installed plugins
	  ps              Client tools for Heroku Exec
	  psql            open a psql shell to the database
	  redis           manage heroku redis instances
	  regions         list available regions for deployment
	  releases        display the releases for an app
	  reviewapps      manage reviewapps in pipelines
	  run             run a one-off process inside a Heroku dyno
	  sessions        OAuth sessions
	  spaces          manage heroku private spaces
	  status          status of the Heroku platform
	  teams           manage teams
	  update          update the Heroku CLI
	  webhooks        list webhooks on an app
```

There are a few ways to create a Heroku app, either from Heroku CLI or web browser. With the CLI, you can create a new Heroku app with `$ heroku create`. This prompt gives you the default [Heroku-20 stack](https://devcenter.heroku.com/articles/heroku-20-stack). It depends on your Ruby buildpack, and Heroku-20 did not align with my project build. I reviewed [Heroku stacks documentation](https://devcenter.heroku.com/categories/stacks), and found [Heroku-18](https://devcenter.heroku.com/articles/heroku-18-stack) stack worked with my Ruby version 2.6.1.

### **Heroku Database**

Once Heroku app is successfully created, we can push the code to the Heroku server with command line `$ git push heroku master`. At this point, if you still hit a snag, I highly recommend Google search — lots of Stack Overflow and tutorials from other devs. For my project, it successfully deployed.

```ruby
$ heroku run rails db:migrate
$ heroku run rails db:seed
```

As we are migrating our database to Heroku's PostgreSQL, we need to initiate the command lines above. `heroku run rails db:seed` is necessary when you have seeding data, either fetching API data or manual `seeds.rb`.

### **PostgreSQL - JOIN clause**

Circling back to *SQL query in PostgreSQL*, this part frustrates me the most. At one point, I hit an impasse, and thought my deployment process was fully corrupted. My application was up and running. However, as I was navigating all links and forms, I was not able to proceed with a few form selections. Heroku's error notification did not provide with enough detailed information to understand what was wrong.

> We're sorry, but something went wrong.
If you are the application owner check the logs for more information.

I gave up that night, slept and continued debugging the next day. 😥

After spending a few hours on Stack Overflow, I learned that my SQL query on helper methods needed refactoring following PostgreSQL. I suggest reviewing all query statements to [PostgreSQL query documentation](https://www.postgresql.org/docs/8.3/tutorial-join.html). One debugging example for the `JOIN` query. 

```ruby
# SQLite query on JOIN
def self.doctors 
  joins(:doctor).where("user_id")
end

# PostgreSQL query on JOIN
def self.doctors 
  joins(:doctor)
end
```

### **Authentication**

Last hurdle was on migrating `PROVIDER_CLIENT_ID` and `PROVIDER_SECRET` from `.env` to Heroku. In Heroku browser, you can navigate to your *app > Settings > Config Vars > Reveal Config Vars*. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/knr6pqkabcisfxxh21u8.png)

This concludes the journey of my first RoR deployment with Heroku.

I intend to exploring future project builds with Heroku, and share my experience with other devs. Thank you, Heroku. 👾

### **Drum roll.... 🥁**

Below is my first Ruby on Rails deployment on Heroku!

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/j5szx8gapeu9l7f5tc7c.gif)

***
<center>[**fentybit**](https://fentybit.me/) | [GitHub](https://github.com/fentybit) | [Twitter](https://twitter.com/fentybit) | [LinkedIn](https://www.linkedin.com/in/fentybit/)</center>