In this part we will install Rails, RSpec and Rubocop. Then we will set up docker-compose to run the postgresql databases.

Here we go.

Ensure the basics are installed

I'm going to make a few assumptions. You can navigate the command line. You have Ruby installed. You have some familiarity with Rails. You either have PostgreSQL installed on your system, or you are comfortable using Docker and docker-compose.

If you need to install Ruby, have a look at the official documentation. It often pays off to use a version manager, such as rbenv, RVM, or asdf-vm. Lately I have preferred asdf-vm.

As of this writing, I have ruby 2.7.1, gem 3.1.2, and bundler 2.1.4.

I also have docker 19.03.8 and docker-compose 1.24.1. Most of these versions won't matter too much. I'm putting them here for reference.

gem install rails

At this time, I have installed Rails 6.0.3.1.


What are we going to build?

Have you ever tried to cook or order food for a group of people, and had to manage a combination of preferences and dietary requirements? For this example application, I want to build a program for managing groups of users' food preferences. This can be helpful for building grocery lists, recipes, or ordering meals. It also seems like a good representation of a generic set of requirements. There can be many users, one or more administrators, and a collection of user-input data that needs to be viewed, updated, and displayed in various ways. Let's call it FavoriteFoods.


Create a new Rails api-only application

I like to put all my code projects in one place, like $HOME/code/, or in this case $HOME/code/rails/. Go to the directory you want to create this project inside of.

rails new favorite-foods -T -d postgresql --api

The -T is for no-tests. Instead of using the default test library, minitest, we will install RSpec (below).
The -d postgresql indicates our database preference (default is SQLite).
And most importantly, the --api tells rails to only provide the parts of the default application structure that are required for an api-only build. I don't want any html template or view layer stuff (except for mailers). I will build one or more front-end clients later.

cd favorite-foods
git add .
git commit -m 'initial commit'

I'll be adding git commits along the way. That might help you follow along on my github repo. It will help me to keep track of what I've been doing.


Install RSpec

RSpec is a fantastic testing library with a lot of features to take advantage of. Let's add rspec-rails to our Gemfile:

# ...

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

# ...
Gemfile

save, and run:

bundle install
rails generate rspec:install

I also like to sanity check with:

rails spec

just to make sure nothing blows up.


Install Rubocop

Rubocop enforces proper code style and helps prevent many typos and other bugs. I like the rubocop-rails_config gem. Edit the Gemfile:

# ...

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'rspec-rails', '~> 4.0.0'
  gem 'rubocop-rails_config'
end

# ...
Gemfile
bundle install
rails generate rubocop_rails_config:install

And sanity test with:

bundle exec rubocop

(you should see rubocop complaining about "offenses found" but you should not have any general errors getting rubocop to run)

Rubocop can be tweaked and configured endlessly, but I'm going to leave it alone for now and trust the defaults until I get annoyed.

Now would be a good time to check out how to integrate rubocop with your text editor. I'm using VisualStudo Code with the 'ruby' and the 'ruby-rubocop' extensions enabled.

You can tell rubocop to autocorrect any offenses that it can:

bundle exec rubocop -a

This made 53 corrections for me. I'll commit all those changes:

git add .
git commit -m 'rubocop corrections'
git push

Install pry

Rails comes with a debugging tool already, It's called byebug and it's great. But I like to add pry-byebug as well to get some nice features like better stack navigation and syntax highlighting within the debugger. Additionally, the pry-rails gem will make it so calling rails console or rails c uses a pry session as its default.

# ...

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'pry-byebug'
  gem 'rspec-rails', '~> 4.0.0'
  gem 'rubocop-rails_config'
end

# ...

# at the bottom of the Gemfile, outside of and "group"
gem "pry-rails"
Gemfile
bundle install

Set up Postgres with Docker

I always run my local databases within docker containers. This way I don't have to fuss with whatever operating system or package management situation might exist on any given computer. Also it's quite easy and can easily be wiped out and replaced, or even run multiple versions and so on. Having installed and configured postgresql system-wide on so many versions of linux and MacOS, I'm hopeful that I will never do that again.

Here's my docker-compose.yml file:

version: '3'

services:
  db:
    image: 'postgres'
    environment:
      POSTGRES_PASSWORD: somethingrandom
    ports:
      - 5432:5432
    volumes:
      - dbdata:/var/lib/postgresql/data

  adminer:
    image: adminer
    ports:
      - 8080:8080

volumes:
  dbdata:
docker-compose.yml

I include adminer as a bonus. It's a handy interface for viewing and editing your data, as an alternative of the more complex but also very useful pgadmin. You can still use pgadmin because your postgres database is exposed at localhost:5432 and can be connected to whatever client you prefer.

In one terminal I now run:

docker-compose up

and let that terminal window be a feed of whatever the database service wants to print out.

Before we can create the database itself, a few lines need to be added to the config/database.rb file:

# ...
#
default: &default
  adapter: postgresql
  encoding: unicode
  # For details on connection pooling, see Rails configuration guide
  # https://guides.rubyonrails.org/configuring.html#database-pooling
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: postgres
  password: somethingrandom
  host: localhost
  port: 5432
  
development:
# ...
config/database.yml

Now rails knows how to connect to the dockerized postgres instance. You can change the username, password, or port here if it suits you. Just be sure it matches with the docker-compose.yml file.

Now in a new terminal window you can run:

rails db:create

You should see:

Created database 'favorite_foods_development'
Created database 'favorite_foods_test'

Now you can actually start rails:

rails server

and verify by visiting localhost:3000.

Check out my github repo for this project to follow along:

ballPointPenguin/favorite-foods-api
A Rails 6 example API. Contribute to ballPointPenguin/favorite-foods-api development by creating an account on GitHub.