Chapter 9. Other Techniques 2. Other tools in Rails

This chapter introduces some used tools in Rails.

HTML, CSS, JAVASCRIPT

No special mention in this book.

It is desirable to be able to write somewhat without Googling. The frontend in Rails is explained in later chapters.

Development Environment

Docker

Recently, docker is becoming the standard for Rails development.

If you have a docker execution environment, you can build an environment with a single command. Also, since members use the same OS, it is much easier to avoid environment-dependent errors such as bundle install errors only on certain devices or environments.

I didn't understand the advantages of docker at first, but I came to understand them after joining to some projects. If there are people who feel that "docker is full of errors" or "docker takes a long time to start up and has a little advantages", it is most likely not because of docker itself, but because the docker configuration or usage in the project is not suitable.

docker-compose

Manages multiple docker containers. The basic containers in Rails are the following.

  • Rails: Application
  • MySQL: RDB
  • Redis: For session management

The following containers are likely to be added depending on the feature.

  • Selenium: For system specs
  • Sidekiq: For background jobs
  • MinIO: For Amazon S3 file uploading
  • Swagger: For APIs management

Mac / Windows

Mac is the mainstream, in line with the server is linux.

However, with the tools availability such as Docker and WLS2 (and the increase in average PC specs) for windows, it is now possible to create a Linux virtual environment and develop easily.

Personally, I recommend developing on a Mac, because there seems to be more information on Rails for Mac than for Windows but Windows is not a bad choice for your budget.

M1 Mac, M2 Mac

M1 Mac uses a different CPU from Intel and is not good with docker in the following.

  • Cannot use chrome's docker image, so difficult to build system spec
  • yarn install is slow.

It is not impossible to use it if use FireFox for system spec and yarn install wont be executed every time.

There is not much information about M2 Mac yet, but note that it may also be incompatible with Docker.

Refactoring

What is refactoring?

Refactoring is that change the code to better without changing its behavior. It may include the table structure changes, and If it is large scale, it should be called replacement.

As a restate, this is my article on basic refactoring.

dev.to - Refactoring Guide for Rails Beginners

DRY / Abstraction

DRY is an abbreviation for "Don't repeat yourself". It's not a problem if you think of them as "refactoring into a small class/method". You don't have to think about something literally difficult like "replace with an abstract entity".

Debugging

rails console

I think Ease of debugging == Executable immediately with rails console. By using rails console on development, it will be able to easily debug code and get into the habit of creating compact methods.

byebug

The gem byebug by default will be able to use breakpoints.

A quite good tool for code reading and RSpec debugging. Almost required on Rails development. While it is convenient, the code tends to be larger and more cluttered than using rails console.

web-console

The gem web-console by default.

If there is a runtime error in the browser, rails console will be automatically launched at the error code. Almost required.

bullet

The gem bullet detects N+1.

Since it is difficult to detect N+1 perfectly by oneself, this is highly recommended. Almost required.

Github - bullet

scaffold / rails generator

File generation commands that reduce copy and paste and enable speedy development.

It is even better if you can use options and customize. When use a frontend framework, it should be customized to generate suitable files if possible.

Some useful git/github commands and usage

It will be assumed that you know basic git commands.

git add --all as soon as it works

Make it staged status. This is recommended to reduce the cases like "it worked before, but it doesn't work again".

git add -p / git checkout -p

Only selected parts can be add or checkout.

git cherry-pick

can pick up commits from other branches to the current to create a clean PR.

git stash commands.

  • git stash save --include-untracked Temporarily saves modifications with comment.
  • git stash show -p -1 Show the latest stashed changes.
  • git stash list List stashes.
  • git stash apply Revert latest stashed changes; stash will not be deleted.
  • git stash pop Revert latest stashed changes; stash will be deleted.

Huge files

Use Git LFS.

There don't seem to be any strict rules, but it is better to use it for files larger than about 10MB.

Secure files

Do not manage with git, but use other way.

hub commands

Pull Requests can be created with ASSIGNEES, REVIEWERS, and LABELS from the command line, which is faster than creating them on the screen.

Slack / Discord

Slack is recommended if you want to receive github notifications. Since Discord currently does not have keyword notifications, notification customizing is a little difficult.

CI

Github Actions / Circle CI / Jenkins, etc.

If your project is using Github, Github Actions is probably the good choice unless you have any reason. There are a few free slots available and some information is already available (although it is a relatively new service).

Rubocop

The gem rubocop is a static code analyzer and formatter. This is almost standard in Rails. In addition, rubocop-rspec can be added rules related RSpec.

It is not necessary to be too strict, but it can be a good opportunity to think of better code by a little strict check. It would be a good idea to start out by making the following rules a little strict, and then loosen them when you feel they are too strict.

  • MethodLength
  • LineLength
  • AbcSize
  • CyclomaticComplexity

As an example, I was on a project with a MethodLength of 5 (i.e., only 5 lines of writing per method). Even then, I obviously thought that 5 was too few, but through that experience I learned how to suitable divide methods.

It is difficult to notice own code improvements without such external pointers. Even if there was a reviewer or mentor, it is difficult to see and point out all, and if rubocop does not point it out, it may end up as no problem.

Automatic fix

rubocop -a or rubocop -A will automatically modify the better code. I recommend to use this with RSpec.

Dependabot

It is a Github feature that automatically notifies the gem updates and even creates a PR for your repository will be able to avoid using old version.

Github Blog - Keep all your packages up to date with Dependabot

For minor updates, once you have confirmed that the CI has passed, you can merge it in. It is not guaranteed to work, so you need to check manually to some extent for major updates.

Can use for npm as well as gem.

command

@dependabot rebase or @dependabot recreate on PR comment.

Redis

It is a KVS (Key-Value Store), which can be thought of as "a tool that is good at storing large data in key/value like json".

It has a variety of uses, but the most common use in Rails is as a session store. It is also used for functions that need to manage large key-value data and for queue management for background jobs.

Deploy

The gem capistrano is major.

Since There is a lot of information on capistrano, I will not explain it in this book. It is relatively easy to build if you don't try anything difficult.

Github - capistrano

If you have never done the whole process from rails new to deployment, you might want to give it a try. You can learn about production environment behavior (such as credentials, building the frontend, caching, and so on). In that case, you might be able to use AWS with a free slot.

Selection criteria for gems and tools

The following criteria would be used to determine.

  • Has a lot of recent information on the Web.
  • If there is a github, one that has a lot of Watch and Star counts.
  • Beware of gems that have not been updated for more than a year, even if famous gems.
  • For development gems, it can be relatively loose, but the larger impact range, the more you need to ask the team to make a decision.

Security things to keep in mind

  • If the implementation is as Rails expected, it can handle many vulnerabilities in web applications. Therefore, be sure to check for security errors and warnings, and don't ignore them.
  • Vulnerabilities can be handled by updating the gem. Update gems regularly by Dependabot.
    • bundler-audit and brakeman are highly recommended to to detect vulnerabilities.
    • For more secure, use an external vulnerability diagnosis  services.
  • Use filter_parameters to prevent sensitive information from outputting into the logs.
  • Development URLs (such as /sidekiq, /letter_opener) are not made public.
  • Use a allowlist(whitelist) for input parameters (e.g., params.permit)
  • Use a allowlist(whitelist) for output items (Do not implement an automatic increase in output items when table columns are added ).

Major security gems

  • brakeman Static vulnerabilities analysis of Rails code
  • bundler-audit Vulnerability check of the gems in Gemfile.lock.

Github - brakeman

Github - bundler-audit

Note that even if your code or gems are caught by these checks, it does not unusable immediately. If it does not lead to vulnerabilities, there may be no problem using it (For example, if only one certain method is vulnerable and not used it).

If you are caught by the check, please check the message. Also, the latest version gem may have already addressed the vulnerability.

Other Rails features

Caching

It is not necessary to know all the caches, so it is good to understand that they exist somehow, and keep in mind that if a problem occurs, you should suspect the cache as one of the causes.

Rails Guides - Caching

Introduce one of the most familiar.

SQL Cache (Query Cache)

Rails Guides - Caching#sql-caching

If the same query is called multiple times within one request, the second query is not executed, and the development.log outputs CACHE (0.0ms) . However, even when this can be used, it is often explicitly cached using a variable.

Autoload

It seems that Autoload is used in various places in Rails. It can be able to load a class just by placing ( e.g. just place a Model in app/models can be use it immediately).

The gem zeitwerk is used by default, but you will not need to know it in detail unless you want to do something special. The following is what you should remember.

  • Appropriate Class name must be given according to its file name and directory.
  • Files under app directory are automatically loaded even if added a new directory.
  • Files not under app directory are not loaded such as lib directory, The files are needed to load with require or add the autoload_paths.

Putting together places to require

Have you ever seen require 'csv' written in various places? By putting require in one place such as config/application.rb, you don't have to worry about whether it is required or not.

Environment variables (env)

The gem dotenv is a major to manage env easier.

Github - dotenv

Using ENV['{feature name}'] is recommended instead of Rails.env.{environment name}? to control behavior on each environment. There are two main advantages.

  • No more code like if !Rails.env.development? && !Rails.env.test?
  • Minimize changes for testing

For example, if you use Rails.env.staging? or Rails.env.production?, you need to rewrite it to Rails.env.development? for testing. If it is used in some places, it may be troublesome to rewrite them, or there is a omission possibility. For the problem, ENV is used to control the behavior with minimal changes.

Note that this does not mean that you must not use Rails.env.{env name}? absolutely. In case that ENV is enough, it can also be used.

If use docker-compose, env can be written in docker-compose.yml, so put code that wont be changed frequently there and seperate from ENV to better overviewing.

Credentials

Since ENV can't hide secure constants (e.g. id/pass), use credentials to manage them. What you need to know is the following about credentials.

  • A key ( like config/master.key) will be needed to refer to or edit.
  • The key is created only at the first time of credentials creation and is managed in a different way from git.
  • To refer to or edit Credentials,
    • you need to get the key from the system administrator and place it in the same directory as credentials.
    • use a command such as EDITOR="vi" bin/rails credentials:edit. The command will automatically encrypt and decrypt the credentials file.

Note that the secrets is the old version way, so new project should use credentials instead of it.

Features included in Rails but not often used

These are included by default and can be removed if not used. They can also be optionally disabled during rails new.

Rails Guides - The Rails Command Line#rails-new

Provides features to speed up screen transitions with Javacript. Since it is a little difficult to use and has little advantage, it is safe to remove it.

I have not investigated the direct relationship, but similar gem turbo-rails is installed by default instead in Rails7.

Action Mailbox

Provides features to handle incoming mail. (Not Action Mailer.)

Action Text

Provides features to use rich text.

Action Cable

Provides features for WebSocket. app/channels directory is created by this. You can delete it if not need.