Lesson Weekend

Creating a Rails Application


Let's rebuild our record store application using Rails. First, we'll run the following command to install the Rails gem onto our machines:

$ gem install rails -v 5.2.0

Then, we'll run this next command to create a new Rails application:

$ rails new rails_record_store  -d postgresql -T

This will create a new Rails app called rails_record_store. The -d postgresql portion tells Rails to use Postgres for the database, and -T instructs it not to install its testing tools. (By default, it uses a library called test-unit, whereas we use RSpec.)

When naming your own projects, make sure to use a unique name that won't be used for classes in your project. Because Rails and ActiveRecord automatically generate classes and methods for us based on the names we use in our project, we need to be very careful about naming. If your project has the same name as one of your classes, you might run into errors.

Setting Default Configurations

To make this the default configuration, create a file called .railsrc in your home directory (using the text editor of your choice) and add the line -d postgresql -T, like this:

~/.railsrc
-d postgresql -T

When we run $ rails new your_app_name in the future, it will use this configuration by default. This is how the Epicodus computers are set up.

Project Directory

After running the $ rails new rails_record_store -d postgresql -T command, Rails will create a folder called rails_record_store with a skeleton of all the folders and files required for our new app.

Let's cd into our new rails_record_store folder and open the project in our text editor. We'll quickly go through the directories and new files here. Before we do, a quick note: we will mostly work with the app, config, and db directories. Specifically, we'll spend the vast majority of our time working with the app folder. If all these directories seem overwhelming, keep that in mind.

Let's take a look at our new directories:

  • app: We will do most of our work in the app directory. This directory holds many subdirectories. We will cover only the subdirectories we plan to use at Epicodus:

    • assets: This is where we store any CSS and JS code.
    • controllers: This is where our controllers are stored.
    • helpers: We can create "helper" methods to DRY up our view and controller code.
    • models: Our models will contain all business logic dealing with the database.
    • views: Rails uses .erb files and our views will look very similar to how they've looked in the past.
  • bin: This holds a link to the Rails server and a few other common commands. We won't touch this folder.

  • config: Just like in Sinatra, we use config/database.yml to store our database configuration. The pre-populated configuration looks a little different from what you're used to, but in fact, will achieve the same results. There are also other configuration files here, but we won't use them much.

  • db: This folder will hold migrations (more on this later) and our database schema. It also holds a seeds.rb file that we can use to put default values in your database.

  • lib: We won't use the lib folder much. We can store custom Rake tasks here.

  • log: Our web server will store its logs here.

  • public: Static files for error messages go here.

  • tmp: This is where the web server's temporary files go.

  • vendor: Gems can be installed here in some cases (but not any cases we'll deal with).

Gemfile

When we generate a new Rails application, it will automatically generate a Gemfile for you. Here's what it will look like assuming that we're using Epicodus computers (Ruby version 2.4.1 and Rails version 5.2.0):

Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.6.5'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.2.0'
# Use postgresql as the database for Active Record
gem 'pg', '>= 0.18', '< 2.0'
# 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
  # 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


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

Note that the Gemfile includes several commented-out gems as well as comments about gem functionality. Some developers don't like the clutter of these additional comments and remove them. There are even custom Rake tasks to automatically remove comments from the Gemfile.

Updating the Gemfile

We'll also update the Gemfile to add additional gems. First, let's add jQuery to our application:

Gemfile
gem 'jquery-rails'

group :development, :test do

Note the gem should be added in the top section of our Gemfile because we want it for all environments, including production. In the snippet above, we show it as being just above the beginning of the block for :development and :test.

Next, we'll add some gems to group :development, :test do:

Gemfile
group :development, :test do
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'rspec-rails'
  gem 'launchy'
  gem 'pry'
end

group :development do
  ...

We've added three new gems to our test environment. Rails automatically includes byebug. byebug is similar to pry and allows you to add breakpoints in your code with either the debugger or byebug command. It's the Rails-approved way of debugging because it has more functionality than pry. pry should get the job done for any debugging you need to do in a Rails application, but you're also encouraged to explore byebug further on your own. Its basic functionality is very similar to pry.

Let's run $ bundle install to get our Gemfile.lock file and bundle all of our gems.

Supplying a Postgres Password

If you need to supply a password to access your Postgres server, like some Windows users do, you'll have to edit the config/database.yml, by adding new password keys. The following code snippet shows the new keys, but with the many comments from Rails omitted.

...
development:
  <<: *default
  database: rails_record_store_development
  password: epicodus  # new code!

...

test:
  <<: *default
  database: rails_record_store_test
  password: epicodus  # new code!
...

Note that there's also a section for production, but we won't be using it.

As we know, it's not secure to put passwords directly into our application's source code. To resolve this issue, we'll use the dotenv gem, just like we did with Sinatra. However, the configurations will be slightly different.

First, we'll add the dotenv-rails gem to the group :development, :test of our Gemfile:

Gemfile
group :development, :test do
  # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
  gem "debug", platforms: %i[ mri mingw x64_mingw ]
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'rspec-rails'
  gem 'launchy'
  gem 'pry'
  gem 'dotenv-rails'
end

Next, bundle your code!

Then, add .env to your .gitignore:

.gitignore
.env

Next, commit .gitignore to your Git history.

Then, create the .env file and add your environment variable:

.env
DATABASE_PASS=epicodus

Then, in config/database.yml, update the password value to <%= ENV["DATABASE_PASS"] %>, like so:

development:
  <<: *default
  database: rails_record_store_development
  password: <%= ENV["DATABASE_PASS"] %>

...

test:
  <<: *default
  database: rails_record_store_test
  password: <%= ENV["DATABASE_PASS"] %>

Setting Up Rspec

Let's set up RSpec as well:

$ bundle exec rails generate rspec:install

While this command usually works even without bundle exec, it's a best practice to append bundle exec to ensure that RSpec looks for the correct version of the gem specified in your local Rails project instead of looking at globally installed gems.

This creates our familiar spec folder, a rails_helper.rb, and a spec_helper.rb.

Our Rails projects are going to rely on structure and convention. We cannot even start our server and view the default entry page until the database is set up. In the next lesson, we will use built-in Rake tasks to create our database quickly!

Lesson 3 of 34
Last updated August 7, 2022