We use cookies to offer you a better browsing experience, analyze site traffic, and serve targeted advertisements. If you continue to use this site, you consent to our use of cookies.
Accept

If you are looking for the cover to cover tutorial on Ruby on Rails Security Best Practices, you have come to the right place.

In this comprehensive guide, I describe

So if you are looking to join the club of those who are better safe than sorry in their secure Ruby on Rails development, read on.

Table of contents

Let's dive neck-deep into the Ruby on Rails security world.

Ruby on Rails Out Of The Box Security Measures

Ruby on Rails, among the other highly popular, open-sourced software development frameworks such as Django or Laravel, is said to be highly secure.

There are quite a few reasons that make this statement true

Addressing the last point, Ruby on Rails takes web security as serious as it gets - to the point where you can make money improving it.

Ruby on Rails Security Bounties on HackerOne
Ruby on Rails Security Bounties on HackerOne

Let's now see through the Ruby on Rails process on dealing with security vulnerabilities.

Ruby on Rails Security Policy

The way Ruby on Rails team has it covered leaves nothing to a chance, here's the short outline

Here's the first step to ensure the security of your Ruby on Rails application.

The best way to receive all the security announcements is to subscribe to the Rails Security mailing list. The mailing list is very low traffic, and it receives the public notifications the moment the embargo is lifted.

Ruby on Rails "Security Policy"

After visiting the provided link, simply Join the group as you can see below

Ruby on Rails Security Google Group
Ruby on Rails Security Google Group

With this simple thing in place, you can rest assured that information on any security vulnerability in the Ruby on Rails itself will be sent to you as soon as it is fixed.

It is especially worth keeping an eye on this list every time Ruby on Rails releases the new mayor version, as that's when big changes occur in the framework's core itself.

Big changes come with big risks, and as you can see on the screenshot above, the most recent security vulnerability in Ruby on Rails was patched not so long ago, on March 19th - which is almost a year after the initial Ruby on Rails 6.0.0 stable release.

Ruby on Rails Built-in Security Measures

Ruby on Rails has been around the block for quite a while - since April 2008 - and has seen its fair share of security vulnerabilities.

Being maintained by very responsible people, it implements a whole lot of security measures out of the box to prevent developers from making mistakes.

Ruby on Rails Security HTTP Headers

At this point, you have most likely heard about the HTTP security headers.

Let's see what headers does Ruby on Rails equip each request with by default.

Those settings belong to the underlying ActionDispatch module, a huge part of the Rails core, responsible for routing the requests to controllers.

lib/action_dispatch/railtie.rb

config.action_dispatch.default_headers = {
  "X-Frame-Options" => "SAMEORIGIN",
  "X-XSS-Protection" => "1; mode=block",
  "X-Content-Type-Options" => "nosniff",
  "X-Download-Options" => "noopen",
  "X-Permitted-Cross-Domain-Policies" => "none",
  "Referrer-Policy" => "strict-origin-when-cross-origin"
}

There's a bunch, provided settings ensure some security measures that in most cases don't need tampering with.

If you do need to change them, it's doable in either config/application.rb or dedicated environment configuration files.

Do notice, that this way you can add any header you'd like to your requests.

Let's now see what are those responsible for exactly.

Ruby on Rails X-Frame-Options Security Header

X-Frame-Options header with a secure SAMEORIGIN value instructs the web browser that it should only open URL addresses linking to the same domain in the <iframe /> tags.

Ruby on Rails X-XSS-Protection Security Header

X-XSS-Protection with value 1; mode=block enables the built-in Cross-Site Scripting filter. The first part, 1, simply turns the option on.

In the second part, mode=block prevents browsers from rendering pages if a potential XSS reflection attack is detected.

Ruby on Rails X-Content-Type-Options Security Header

X-Content-Type-Options with value nosniff is responsible for blocking a request if its destination is of either style or script types and their MIMIE types do not match.

Ruby on Rails X-Download-Options Security Header

X-Download-Options is a header specific to Internet Explorer 8. Its functionality is to block the browser from executing the downloaded HTML file in the context of the website.

Ruby on Rails X-Permitted-Cross-Domain-Policies Security Header

X-Permitted-Cross-Domain-Policies with value none instructs clients such as AdobeAcrobat and Flash to avoid accessing any data from your domain.

Ruby on Rails Referrer-Policy Security Header

Referrer-Policy is responsible for controlling how much information should be sent in the Referrer header. The strict-origin-when-cross-origin value:

Now that we've met the defaults, let's see what else is there.

Ruby on Rails Content-Security-Policy Security Header

On top of setting the sane defaults for us, Ruby on Rails covers yet another security header, called Content Security Policy.

Content Security Policy (CSP) is an HTTP response header that restricts the browser to loading external assets such as scripts, styles or media from a wide variety of sources — as well as inline scripts.

sqreen.com

As usual, a well-known at this point configuration DSL allows us to configure it globally

config/initializers/content_security_policy.rb

# frozen_string_literal: true

Rails.application.config.content_security_policy do |policy|
  policy.default_src :self, :https
  policy.font_src    :self, :https, :data
  policy.img_src     :self, :https, :data
  policy.object_src  :none
  policy.script_src  :self, :https
  policy.style_src   :self, :https
  policy.report_uri '/csp-violated'
end

Rails.application.config.content_security_policy_report_only = false

as well as a per-controller basis, using the content_security_policy block

Ruby on Rails Feature-Policy Security Header

Feature-Policy header is another security header that Ruby on Rails let us configure, despite still being in the experimental state.

The Feature-Policy  header is still in an experimental state, and is subject to change at any time. Be wary of this when implementing Feature Policy on your website.

MDN "Feature-Policy"

Its code in the ActionDispatch module is very similar to the CSP one, and the header can be configured in the same manner

# frozen_string_literal: true

Rails.application.config.feature_policy do |policy|
  policy.fullscreen :fullscreen
  policy.geolocation :geolocation
  policy.gyroscope :gyroscope
end

There's also a link to the full list of available features in the Ruby on Rails source code.

I guess Ruby on Rails does not document it yet in their official guides because the header is still experimental.

Ruby on Rails SQL Injection Prevention

One of the most frequently occurring attacks, both in Ruby on Rails and in the web development in general, is SQL Injection.

XKCD SQL Injection Classic Exploits of a Mom
XKCD classic - Exploits of a Mom

Ruby on Rails does not fully prevent it yet still equips its ActiveRecord ORM in methods that allow you to write the code that's impossible to carry on the SQL Injection attack.

There's a great resource on the subject, the Rails SQLI

This page lists many query methods and options in ActiveRecord which do not sanitize raw SQL arguments and are not intended to be called with unsafe user input. Careless use of these methods can open up code to SQL Injection exploits.

rails-sqli.org

And it is full of easy to understand examples of how the attack can be carried out.

It is good to take a moment to review them but worry not - there are tools further down this tutorial that audit your Ruby on Rails code in the SQL Injection context.

Ruby on Rails Data Sanitization

There are multiple different attacks that can be carried out via the Ruby on Rails View layer.

That said, Ruby on Rails comes prepared for those security vulnerabilities, with its awesome ActionView::Helpers::SanitizeHelper module, that in total exposes four different methods that allow you to render anything safely.

Those are

With the sanitize being the most used one

Sanitizes HTML input, stripping all but known-safe tags and attributes. It also strips href / src attributes with unsafe protocols like javascript:, while also protecting against attempts to use Unicode, ASCII, and hex character references to work around these protocol filters. All special characters will be escaped.

Sanitize Helper documentation

Whenever you render anything that is submitted to your Ruby on Rails application via users, such as for example comments, remember to sanitize it via dedicated helper provided in the framework.

Ruby on Rails Cross-Site Request Forgery

That's the one that's prevented by Ruby on Rails fully out of the box if you follow its conventions, but let's see what it actually means.

Here's how the attack happens:

  1. Hacker links to your application on his website, by for example placing the malicious link in the <img src="http://myrails.com/resource/1/destroy" height=0 width=0 />
  2. Hacker's website visitor executes the code that otherwise requires authorization - as long as his session on myrails.com did not expire.

With Rails' default CSRF tokens in place, nothing gets executed. Those tokens are sent from the frontend to the backend layer with every form submission.

If they don't match the expected ones's the request fails. Simple, yet effective.

Ruby on Rails Sessions Security

Ruby on Rails comes super-prepared for securing the users' sessions and covers it in great detail in its Security Guide.

They have a dedicated chapter on how to properly configure and manage sessions, that cover

There's a lot happening out of the box, but whenever configuring it, use the official guidelines as your implementation reference, as those attacks are super-dangerous.

Ruby on Rails HTTPS Configuration

One thing that goes without saying in the present state of the Internet, the same as it should in the secure Ruby on Rails application, is the secure HTTP protocol, HTTPS.

It, for good reasons, became so popular, that there are multiple trusted providers with whom you can simply obtain the SSL Certificate completely for free - such as for example Let's Encrypt.

Once you do that, setting up the Ruby on Rails to use the secure HTTPS protocol is as easy as it gets.

config/environments/production.rb

# frozen_string_literal: true

Rails.application.configure do
  # other config
  config.force_ssl = true
end

With this single line of code in place, you get:

In most cases, excluding internal services communication, this is a very much desired behavior in the secure Ruby on Rails application.

Ruby on Rails Secure Users Authentication

Now that we have reviewed what comes security-wise out of the box in Ruby on Rails, let us see what does not, yet is still universally implementable for almost any web application.

One such thing is the users' authentication.

Authentication is the act of proving an assertion, such as the identity of a computer system user.

wikipedia.org

Nowadays most of the web applications provide a way for anybody to sign up to them, and in turn, become him or herself in its domain.

Here's where the hard part comes.

As opposed to the real world where we can physically look at somebody at the counter, in the virtual world it is very easy to impersonate someone else and do something more or less harmful on his or her behalf.

Here's where the Ruby on Rails authentication security comes into play.

If you are looking for a short answer to this massive subject, it breaks down to one simple advice.

Despite what they say, do use Devise.

If you are building your first Rails application, we recommend you do not use Devise.

Devise README.md

Yes, it is good to understand all that happens under the hood, but learning by doing beats implementing it yourself.

However, if you are working on a solution that is supposed to work on an actual production environment, it is good to start with some other resources first, in order to fully understand the complex authentication process

Take your time, visit those links.

This will hopefully make you understand how complex is the process of implementing the authentication in general, as well as in Ruby on Rails.

If you are a junior developer who has just started a new job and got the task of implementing the authentication all by yourself, start looking for a new one.

If you are a senior developer looking for a resource to send for a junior developer tasked by you to implement the authentication all by himself, please, change the industry.

I mean it.

With those first two high-level security measures in place, let's move on to those that you can implement in the actual code.

Ruby on Rails has_secure_password

One of the measures that are a must-have for Ruby on Rails secure user authentication is not storing an actual password in the database.

With help comes the ActiveModel::Validations#has_secure_password.

Adds methods to set and authenticate against a BCrypt password. This mechanism requires you to have a XXX_digest attribute. Where XXX is the attribute name of your desired password.

ActiveModel::Validations#has_secure_password documentation

It requires the bcrypt gem to work and as you can see an additional database column for whatever AR model you want to authenticate.

bcrypt() is a sophisticated and secure hash algorithm designed by The OpenBSD project for hashing passwords. The bcrypt Ruby gem provides a simple wrapper for safely handling passwords.

rubygems.org bcrypt

As often in Ruby on Rails, a semi-complex problem is easily solved with a single line of code.

Ruby on Rails Secure Devise Authentication

The most popular choice for handling a complex Ruby on Rails authentication process in a secure manner is the aforementioned Devise gem.

Ruby on Rails secure Devise authentication
Devise gem for Ruby on Rails authentication

Devise is a very sophisticated solution that is composed of ten modules. You can pick and choose those that fit your use-case.

Let's focus on those that are designed to increase the security of your Ruby on Rails application.

The first module, Trackable, is responsible for tracking all the sign-in activity.

In case of any security breach, this information can help you or even your users to review if their latest activity in your Ruby on Rails application was, in fact, theirs, and not someone else's.

The next super important module that helps to prevent impersonating users of your Ruby on Rails application is called Timeoutable and it handles sessions expiration time.

The last one, Lockable, allows us to lock an account after a given amount of unsuccessful login attempts. It is later possible to unlock it via an email, or after a specified time period.

On top of those, you can extend the default Devise behavior via the dedicated initializer.

config/initializers/devise.rb

Devise.setup do |config|
  config.send_email_changed_notification = true
  config.send_password_change_notification = true
end

This way users of your Ruby on Rails application get notified anytime their account's email or password is changed.

If you want to be super equipped for debugging of potential security breaches, you can consider using AuthTrail on top of Trackable.

This gem creates a new ActiveRecord model, called LoginActivity, that describes in a great detail every login attempt via your Ruby on Rails application users.

Having it in place, you can achieve functionality similar to this one provided by Google, among many

Google Login History
Google Login History

This gives your users an overview of their login history, which can potentially alert them on any unexpected activity on their accounts.

One last thing worth considering for an even more increased users' account security is using the CAPTCHAs.

reCAPTCHA human verification
reCAPTCHA human verification

It is an effective mechanism that helps to determine if any of the requests are generated by a bot or a human.

As usual in the Ruby world, there is a ready to use solution, a ReCaptcha gem, that integrates nicely with the Devise, as described here.

Ruby on Rails Devise Alternatives

Devise gem is not the only one available for authentication in the Ruby on Rails world, yet it is truly the most popular one.

That said, it is worth checking out what alternatives for safe and secure authentication options an open-sourced world gives us for the Ruby on Rails framework.

In order to not repeat something that's already doing a great job with comparing those libraries, I encourage you to visit the Awesome Ruby Devise alternatives listing.

There is a total of 15 solutions for the secure Ruby on Rails authentication and users' accounts management.

Ruby on Rails Authorization and Access Control

Before we get to the matter of secure Ruby on Rails authorization techniques, it is important to understand the difference between Authentication and Authorization.

Authentication checks if users are in fact who they claim they are.

Authorization checks if the authenticated user has permission to perform specific actions.

Let's have some examples of the authorization:

Those are simple, high-level examples of entities being authorized to perform actions in the defined domains.

Ruby on Rails authorization security vulnerabilities might cause

Those are potentially very, very dangerous for your business and for any system in general.

In order to keep it extra safe, the common security measures worth having in place for a good authorization system are:

That said, as usually in the so-far secure Rails world, there are ready to use, battle-tested solutions to get the job done.

Ruby on Rails Pundit Authorization Management

The most popular authorization solution for a secure Ruby on Rails is a Pundit gem.

Pundit provides a set of helpers which guide you in leveraging regular Ruby classes and object oriented design patterns to build a simple, robust and scalable authorization system.

Pundit README.md

It uses simple Ruby objects, called Policies, that reside in the app/policies directory of your Ruby on Rails application.

PolicyObjects names strictly correlate with ActiveRecord models, which makes the whole approach super simple and easy to understand.

Ruby on Rails CanCanCan Authorization Management

The second most popular solution for secure management of the authorization flow in the Ruby on Rails is a CanCanCan gem.

CanCanCan is an authorization library for Ruby and Ruby on Rails which restricts what resources a given user is allowed to access.

All permissions can be defined in one or multiple ability files and not duplicated across controllers, views, and database queries, keeping your permissions logic in one place for easy maintenance and testing.

CanCan README.md

It equips Ruby on Rails application with a special DSL that mostly based on, you guessed it, the "can" word.

Basically, you define Ability classes that define the access and can use super-simple helpers in your views, controllers and other classes via new ActiveRecord models methods.

Ruby on Rails Authorization Best Practices

Let us take a quick look at the high-level authorization best practices in Ruby on Rails.

Before putting the work into implementing the secure authorization system of the next Ruby on Rails application, make sure you fully understand those.

Ruby on Rails API Security

Ruby on Rails API security involves whatever's applicable from other parts of this article, with one addition - the authentication part.

In most cases, API authentication in the Ruby on Rails is token-based, which is an alternative to the session-based method.

Token-based authentication is stateless - it does not store anything on the server but creates a unique encoded token that gets checked every time a request is made.

"Token-based Authentication with Ruby on Rails 5 API" by Hristo Georgiev

It only makes sense to use this kind of solution, as standalone Ruby on Rails API does not necessarily create a session for various users.

The most popular solution for the token-based authentication in Ruby on Rails APIs and in general is JWT, standing for JSON Web Token.

JSON Web Token is an open standard - RFC 7519 - that defines a compact and self-contained way for securely transmitting information between parties as a JSON object.

jwt.io

Implementing JWT in Ruby on Rails is as easy as it gets, and there's a dedicated jwt gem for doing just that.

Ruby on Rails Request Blocking and Throttling

One common approach to preventing security breaches such as the Brute-Forcing Accounts attack is implementing the request throttling and blockage approach.

As usual in the Ruby on Rails world, there is a ready to use solution to do just that, the Rack::Attack gem.

Protect your Rails and Rack apps from bad clients. Rack::Attack lets you easily decide when to allowblock and throttle based on properties of the request.

Rack::Attack README.md

It is a drop-in solution for Ruby on Rails applications, enabled by default after the gem installation.

We are able to customize its setting via dedicated config/initializers/rack_attack.rb initializer.

The repository hosts some ready to use configuration solutions for real-world problems, such as

Rack::Attack is a middleware that is especially worth using in the Ruby on Rails applications that do not implement those security measures on the lower level, such as NGINX for example.

Ruby on Rails Security Audit Gems

We have some perspective on the Ruby on Rails Security Best Practices at this point.

I believe that at some point you've already encountered some of the security vulnerabilities and measurements mentioned in this article.

Keeping all of them constantly in mind is not an easy task to do, and depending on programmers memory alone is yet another security vulnerability, known as The Human Error.

Thankfully, there are measures to prevent it.

Let's see what automated audits for scanning the Ruby on Rails security are there.

Ruby on Rails Brakeman Security Audit Gems

The most popular community choice for auditing Ruby on Rails application against security vulnerabilities is the Brakeman gem.

Its maintainers are also authors of the Rails SQL Injection Examples website mentioned before.

Brakeman usage is as simple as executing the bundle exec brakeman command in the root of any Ruby on Rails application.

This is especially useful for hooking into the Continuous Integration suite. If you're interested in doing so, you can see how it's done in our Ruby on Rails tutorials:

However, there's more to it.

Brakeman by default does not run all the audits available, there are deliberately skipped, optional checks.

bundle exec brakeman --run-all-checks --rails6

If you find this version of the command too restrictive, or not really applicable to your use-case, use --no-exit-on-warn flag additionally in the CI instead of turning the --run-all-checks off.

This can be even further customized using the exact checks we want to run to the command in the dedicated configuration file.

Ruby on Rails Dawnscanner Security Audit

The second quite popular choice for Ruby on Rails security audit is the Dawnscanner gem.

Dawnscanner is a source code scanner designed to review your ruby code for security issues.

Dawnscanner README.md

Unfortunately at this point, the project is on hold and my mentioning it here is more for you to keep an eye on than to actually implement it in your Ruby on Rails projects.

It still does work, has a 100% code coverage and overall seems like a solid solution - I have tested it on some small-to-medium Ruby on Rails projects.

From the security perspective though, it might not be the best idea to use the unmaintained gem.

Nevertheless, keep your ear to the ground for the Dawnscanner gem, as it has a very promising base of security audits, that is tightly coupled with the Common Vulnerabilities Enumeration - you can see the planned work in the gem's repository issues.

Ruby on Rails Bundler-Audit

While the tools such as Brakeman and Dawscanner audit your Ruby on Rails code against any security vulnerabilities, the bundler-audit gem checks all the 3rd-party gems bundled into the Gemfile.lock.

In most cases, it should be used in the Continuous Integration suite without returning any error code and mostly as a context on the current situation, as otherwise, your jobs might start to fail unexpectedly.

The one thing worth keeping in mind with this one is to check for its updates, as it uses the second gem of the same maintainer, called Ruby Advisory DB.

In order to keep your 3rd parties' security scans up to date, keep the Bundler Audit gem up to date as well.

Ruby on Rails RuboCop Security Department

One last static code analysis tool that takes security into consideration is the most popular Ruby code listing tool, RuboCop.

In its core gem, it has a dedicated Security department with a modest number of 5 cops.

Don't be put off by this small amount though, as in total, with all its extensions hooked-up RuboCop can make your code potentially 1.5k times better - and better the code, better the security, too.

Read more about Ruby on Rails RuboCop configuration tutorial.

Ruby on Rails Security Audit Services

If you don't feel like hooking up all the security audits in the Continuous Integration suite yourself, you can always subscribe to the ready-to-use solutions.

Security Audits in the GitHub Marketplace

There's a good chance that you host your repository on Github, and if that's the case, the Github Marketplace has at this point a total of 112 solutions tagged as Security.

Eight of those are marked as Verified by GitHub.

GitHub Marketplace Security Solutions
GitHub Marketplace Security Solutions

Six of them are free to use:

Another one of the eight, BackHub, serves the sole purpose of the repository backup and its pricing starts from $12 / month for 10 repositories.

That leaves us with the last one, GuardRails, that despite its name supports not only Ruby on Rails security audits but a total of 10 programming languages.

It has 3 paid plans

This is only an overview, as those plans vary in other aspects such as for example queue priority.

DevSecOps Security on GitLab

The second most popular choice for hosting the code worldwide is GitLab, and it offers its custom security solution called DevSecOps.

GitLab DevSecOps
GitLab DevSecOps

This full-blown security audit solution was announced at the end of June 2019.

DevSecOps integrates security controls and best practices in the DevOps workflow. DevSecOps automates security and compliance workflows to create an adaptable process for your development and security teams.

GitLab answering "What is DevSecOps?" question

Do remember that GitLab itself uses Ruby on Rails internally, which means that their offer comes prepared exactly for this use-case.

Hakiri Secure Ruby Apps Shipment

The last option worth mentioning is Hakiri, a standalone security audit solution fully dedicated to Ruby.

Ruby on Rails Security Audit with Hakiri
Ruby on Rails Security Audit with Hakiri

That makes it also a great choice for auditing the security of Ruby on Rails projects.

Hakiri monitors Ruby apps for dependency and code security vulnerabilities.

hakiri.io

It breaks down to three functionalities:

Hakiri's pricing starts from $19.99 and goes up to $99.99 per month, depending on how many private repositories and people with access to the dashboard you need.

It integrates with GitHub out of the box and offers a 14-day free trial.

Sqreen Application Security Management

One of the most complex security solutions for Ruby on Rails applications is Sqreen.

Sqreen Application Security Management
Sqreen Application Security Management

Sqreen gives its users a real-time security monitoring dashboard. This is quite a unique approach, and the expensive one too - their Lite plan costs $499 per month.

Security built into every app. Everywhere.

sqreen.com

On top of that, they offer the Free starter plan for a single production application, under one condition - you have to display its badge on your website.

This is a great starting point for anybody interested in a full-blown, dedicated and a very complex solution to the Ruby on Rails security monitoring.

Hix on Rails Security Approach

The most security vulnerabilities in Ruby on Rails applications occur as a consequence of human error.

Hix on Rails is a solution that allows you to eliminate the possibility to make one at the earliest stages of the Ruby on Rails application lifespan - during its first initialization.

From its first release, Hix on Rails:

And those are just to start with, as there is much more coming, with this article serving as a guide for the further implementation in the package.

I cannot stress enough how big of an advantage is having Brakeman hooked up into the Continuous Integration suite or monitoring the errors and exceptions via a dedicated SaaS since the first commit.

On top of that, a whole lot of configuration that Hix on Rails starts every new Ruby on Rails project with is carefully tested.

If you care about the Ruby on Rails security, eliminate the human error from the earliest stages by using Hix on Rails.

Conclusion

As you most likely realize by now, security in Ruby on Rails and in general is not a piece of cake.

Despite Ruby on Rails implementing a lot of security measures out of the box, a responsible developer always keeps it in mind, especially when implementing solutions to problems related to sensitive data.

Thankfully, there are multiple open-sourced and paid solutions that serve the sole purpose of keeping the Ruby on Rails security in check automatically.

What is your take on Ruby on Rails Security Best Practices?

Please let me know in the comments!

Ruby on Rails is no doubt very popular, the framework itself is highly-recognizable among the programmers and receives steady contributions from their community.

But did you know that there is more than just Ruby on Rails?

If you started your adventure with the framework later than four years ago, as I did, there's a good chance that you didn't.

I was super surprised, in a good way, to discover those!

Over the years, with one major update after another, the Rails team carefully extracted some of its less-known parts into their own gems.

That by any means does not imply that those are forgotten - it's just that their use cases are far-less often occurring.

Yet still, it is very nice to have them in our development toolkit, and same as the whole Ruby on Rails framework - they are very easy and straightforward to use.

Table of contents

Let us explore this hidden path of the Rails Way.

A quick glance at the Ruby on Rails organization on Github

As you surely know by now, all the Ruby on Rails framework's code is available on Github, under the Ruby on Rails organization.

Ruby on Rails on Github
Ruby on Rails on Github

But there are 98 repositories in total, and some of them are truly golden solutions for a common, but not very often occurring problems.

If you care about implementing The Rails Way in your workflow and like to rely on stuff that simply works for certain scenarios, read on.

Ruby on Rails Observers

One of such scenarios that are not needed for every application is observing the changes occurring in your ActiveRecord and ActionController objects constantly, and acting on them accordingly.

Observer is a behavioral design pattern that lets you define a subscription mechanism to notify multiple objects about any events that happen to the object they’re observing.

refactoring.guru

If you're interested in the full explanation of its implementation, do take a look at the Design Patterns: Observer by the Refactoring Guru Raccoon.

The Observer design pattern is also known as:

Let's see some scenarios for using the pattern:

There's more, but those three are pretty self-explanatory.

This functionality, once native to the Rails framework, was extracted from it in the 4.0 version and lives its own life ever since as a rails-observers gem.

Ruby on Rails Rails Observers repository
Ruby on Rails Rails Observers repository

Its capabilities are pretty straightforward: you can hook up to any of the controllers and/or models callbacks, and execute the observer code whenever they occur.

Here's the full list of ActiveRecord callbacks:

  1. Create and update callbacks:
    • before_validation
    • after_validation
    • before_save
    • around_save
    • before_create or before_update
    • around_create or around_update
    • after_create or after_update
    • after_save
    • after_commit and after_rollback
  2. Destroy callbacks:
    • before_destroy
    • around_destroy
    • after_destroy
    • after_commit and after_rollback

And here are ActionController callbacks:

In order to observe them, first, we need to install the rails-observers gem. Add the following line to your Gemfile.

gem 'rails-observers'

and then execute bundle install from the command line.

Due to the gem's convention, observers are put next to the models and controllers they observe.

So, if you have app/models/user.rb, its observer will be in the app/models/user_observer.rb file.

That's one way to keep our models slim.

Let's now take a look at the Observer's DSL. Here's the simplest observer possible:

class UserObserver < ActiveRecord::Observer
  def after_create(user)
    user.logger.info("New user has been created: #{user.name}")
  end
end

As you can see, the DSL really straightforward.

For every callback we want to observe and act on, we simply create a correlated method in our observer class.

It accepts the related ApplicationRecord instance out of the box.

There's also one neat trick if you ever need it: we can create one observer for multiple models. Let's see:

class CleanupObserver < ActiveRecord::Observer
  observe :article, :review, :comment, :post
  
  def after_destroy(record)
    record.logger.info("A #{record.class.name} was just deleted")
  end
end

With this in place, using the special observe method, we instruct our Rails logger to inform as every time one of Article, Review, Comment or Post records are destroyed.

One last step for observers to work is registering them in the config/application.rb file.

config.active_record.observers = [:user_observer, :cleanup_observer]

Now that we've seen how to observe our models, let's take a look at the controllers.

Why would we even want to observe controllers in the first place?

In most cases, the answer is caching - and the Rails team knows that very well, so they've created ActionController::Caching::Sweeper.

Let's see what happens in an exact example from the gem's documentation.

class ListSweeper < ActionController::Caching::Sweeper
  observe List, Item

  def after_save(record)
    list = record.is_a?(List) ? record : record.list
    expire_page(controller: 'lists', action: %w[show public feed], id: list.id)
    expire_action(controller: 'lists', action: 'all')
    list.shares.each { |share| expire_page(controller: 'lists', action: 'show', id: share.url_key) }
  end
end

this code assumes a presence of two following models, List and Item

class List < ApplicationRecord
  has_many :items
end

and the second one

class Item < ApplicationRecord
  belongs_to :list
end

With that in place, let's use the observer's methods in our ListsController, as shown in the documentation example:

class ListsController < ApplicationController
  caches_action :index, :show, :public, :feed
  cache_sweeper :list_sweeper, only: [ :edit, :destroy, :share ]
end

As we can see, the controller assumes four read-only actions for the List resource, and instructs them to be cached. Those are index, show, public and feed.

Thanks to our previously defined sweeper, we can easily regenerate the cache anytime the cached Lists is either edited, destroyed or shared.

This makes a perfect sense, assuming that our lists' shares are displayed on all of its views.

Ruby on Rails: ActiveResource

The next awesome gem that's available next to the mighty Ruby on Rails framework and integrates with it smoothly is activeresource.

Ruby on Rails Active Resource repository
Ruby on Rails Active Resource repository

It allows us to fetch other REST APIs and map their resources to instances of classes very similar to those of ApplicationRecord.

Model classes are mapped to remote REST resources by Active Resource much the same way Active Record maps model classes to database tables. When a request is made to a remote resource, a REST JSON request is generated, transmitted, and the result received and serialized into a usable Ruby object.

ActiveResource README.md

So, let's assume for a second that there is a https://movies.com/api that exposes the following endpoints:

GET https://movies.com/api/actors.json
GET https://movies.com/api/actors/:id.json
POST https://movies.com/api/actors.json
PUT https://movies.com/api/actors/:id.json 
DELETE https://movies.com/api/actors/:id.json

Now, let's install the activeresource gem by adding it to the Gemfile, and then create the app/resources directory.

With those in place, let's create our new ActiveResources, the Actor in the corresponding app/resources/actor.rb file.

class Actor < ActiveResource::Base
  self.site = 'https://movies.com/api'
end

With only these 3 lines of code in place, we are free to use the full power of the ActiveResource magic, as long as the API we connect to follows the REST guidelines.

$ Actor.find(1)
=> {"first_name":"Edward","last_name":"Norton"}
$ Actor.find(1).destroy
$ Actor.find(1)
=> {}

The DSL is so similar to the ApplicationRecord that using it takes no learning curve at all for any Rails developer.

This goes much, much further - we can fetch associated resources and they're returned as nested, own objects, and act on them as well.

On top of all that, there's also an easy way of implementing all types of API authentication, if it's not public.

Ruby on Rails Country Select

One last little thing worth mentioning that got extracted from Ruby on Rails is a country_select gem.

Ruby on Rails forked Country Select repository
Ruby on Rails forked Country Select repository

It does not belong to the Rails organization anymore and got archived some time ago, but one of its forks is still maintained to this day.

The idea of it is pretty simple

Rails – Country Select: Provides a simple helper to get an HTML select list of countries using the ISO 3166-1 standard.

Country Select README.md

In some cases, this is super-helpful: hardly anybody wants to maintain the full list of world's countries, so keeping them in a dedicated gem maintained by the community makes perfect sense.

Its DSL is very similar to Rails' default form elements available in its Views.

<%= form_for User.new, url: root_url do |f| %>
  <%= f.country_select :country_code %>
<% end %>

On top of that, it exposes the ISO3166 module with a Country class that enables easy access to all the data on the backend.

Conclusion

As you can see there's something more besides all the goodies available in Ruby on Rails by default.

It's not a plethora of stuff, but still - it is worth knowing a full scope of options when encountering some more-specific problems in our day-to-day Ruby on Rails development workflow.

What is your take on it? Maybe you already had a chance to work with any of those and want to share some better options instead?

Or maybe reading this you're thinking "I wish I knew sooner" recollecting some custom implementation of similar patterns all by yourself?

Please let me know in the comments!

This is the ultimate tutorial to Ruby on Rails application monitoring in 2020.

In this comprehensive guide I'll cover:

So if you want to sleep through the night with your Ruby on Rails application monitoring in place, you are in the right place.

Table of contents

Let's do it.

Ruby on Rails Application Monitoring Basics

Out of the box, Ruby on Rails comes to us with a Rails.logger, an amazing tool that's both simple to use and easily extendable.

In its basic form, the Rails logger is writing the application output to the dedicated log file as well as to the running process' stdout

A name of the log file depends on the RAILS_ENV we are running the app in. In the default configuration in the log directory in the application root you will find:

On top of that, the logger is equipped in an ability to differentiate various events severity levels:

It's very useful for filtering, grouping and aggregating logs via third party services described in the next parts of this article.

Breakdown of Ruby on Rails Application Monitoring

As we know by this point, the dedicated Rails logger serves one purpose, and that's telling us exactly what happens in the domain of our Ruby on Rails application.

However, that's not even a tip of an iceberg when considering the full suite Ruby on Rails application - there's so much more to consider.

It all comes to asking ourselves - what exactly do we want to know about our Ruby on Rails application?

Let's break it down in order to answer this question.

Application Performance Monitoring

First things first: we want to know about our Ruby on Rails application's bottlenecks.

bottleneck is a point of congestion in a production system - such as an assembly line or a computer network - that occurs when workloads arrive too quickly for the production process to handle.

"Business Esentials" by Investopedia

This is the domain covered the most thoroughly by SaaS services, it even has its own shortcut, APM.

Let's break down the classic Ruby on Rails usage, MVC, into small parts that one wants to monitor in the performance perspective:

Whenever thinking about the performance, the information we want to obtain is the execution time of different parts of our application.

Remember, those are only basics - other things to compartmentalize in the performance perspective I can think of of the top of my head are:

It all depends on what your app does for a living. Let's take for example the processing of payments.

It is crucial for our customers not to wait for payments to be processed for 3 days or even 3 hours - and that's exactly the bottlenecks we want and need to know about.

With a correctly working APM in place, we are equipped to react quickly to the Rails application bottlenecks, which results in a better end-user experience.

Ruby logger: Error and Exception Monitoring

The next part is the scariest one, yet inevitable - we want to know when our Ruby on Rails application behaves unexpectedly.

Our Ruby on Rails logger comes to the rescue - by default, it logs all exceptions raised both into stdout and the dedicated file.

Rails neatly prints the thrown exceptions' stack trace, which allows us to pinpoint the exact line of code causing the error.

Rollbar's example of code line throwing an exception
Rollbar's example of code line throwing an exception

That said, even for small applications that's not enough to easily work with. Why?

That's where an awesome error and exception monitoring services come with a HUGE help.

When hooked up correctly, the amount of information on thrown exceptions provided is just enough for a developer to solve any problem in minutes.

On top of that, you can usually tweak them with even more helpful intel, such as for example:

Let's be honest with each other - there isn't any golden bullet solution to prevent all of our Ruby on Rails application crashes.

And its crashes are a piece of must-have knowledge for anybody responsible for maintaining a healthy system.

With a correctly hooked up exception monitoring in place, we are equipped in just the right tools to fix them as quickly as possible.

Thanks to no longer being blind to our Ruby on Rails application errors, our end-user gets exactly the experience we expect them to get by fixing anything that's out of place.

Server and System monitoring

Ruby on Rails by itself is just a simple process running on the system that launched it - nothing more, nothing less.

In order to obtain a full knowledge about our application, we want to have at least a basic intel about the system that runs our Ruby on Rails application.

In the simplest form, this breaks down to other processes that are essential for our application to work as expected:

It all comes down to what you use.

When planning your monitoring suite, try to break it down to those little pieces and think about each process without which your Ruby on Rails application will not work as expected.

Ruby logs monitoring

This one serves as an alternative both to the Ruby on Rails exception monitoring and the APM.

The idea is to hook up your logs with some other process that aggregates them.

Fragment of raw Rails logs
Fragment of raw Rails logs

It means that on top of errors and exceptions, you can extract additional data about anything that your Ruby on Rails logger tells you and break it down into both performance and exceptions reports.

That is especially useful when you use Rails logger extensively with the information and warning severities.

By customizing the tool of your choice a little, you can easily aggregate the data you need for almost any intel required to successfully maintain your Ruby on Rails application.

Some common use-cases are:

There are pros and cons of this solution.

On the one hand, you get the full, detailed overview of what you exactly need - no more, no less, just what you extract.

On the other hand, this usually is not a drop-in solution to all your problems, and costs you the actual implementation time - the more you want to know, the more work you gonna put in.

System Security monitoring

There is one metric that when tread too lightly can even put you in jail these days.

We're talking about information security.

This topic is easily overlooked at the beginning and costs more than its worth in the later stages of the Ruby on Rails application lifetime.

Cybersecurity breaks down to a multitude of aspects that both developers and business owners sadly don't bother much with on a daily basis.

The good part is that the day you implement at least minimal security measures into your application is the day when you become less likely a target of any security breach.

Most of the hackers do not waste time on difficult targets whenever there's an alternative in the low hanging fruit.

All that said, Ruby on Rails security monitoring is a very, very nice thing to have in place.

What are some common attacks that we want to monitor for?

Further down the article, I will present you with some examples of the tools we can use to monitor Ruby on Rails application security.

That said, in my opinion, an increased awareness combined with prevention in the security field comes a long way.

And there are tools to use in order to implement it.

Ruby on Rails Monitoring Tools and Services Comparison

In this part, we compare a multitude of logging and monitoring tools and services.

In order to effectively do so, we take the following features into consideration:

In order to fairly compare the costs, the 100k/m column is calculated from the break down of the Lowest metric into the monthly cost of 100k requests in the annual plan.

Stand aware that this is unfortunately not applicable to every single service available, as their plans vary.

One other thing worth noting: the order of those tools does not matter in this comparison, they are simply sorted lexically.

Ruby on Rails Application Performance Monitoring

Let's take a look at various APM options available for our Ruby on Rails application monitoring.

ToolFreeTrial100k/mLowestSince
AppNetayes*??$119* / ?2011
AppSignalno30 days$7.6$19 / 250k2012
Instrumentalnoother$340$0.0034 / metric/ day2012
New Relicyes14 days?$12.5 / month2007
RoR vs Wild< 100k14 days$0.8396 / 100k$41.98 / 5000k2017
Skylight< 100k30 days$2.23 / 100k$20 / 1000k2012

This is the one department of the market that thrives, which has its pros and cons.

On the other hand, the moment we can ignore the pricing is the moment when we can focus on selecting both the features that really matter to us and a UI that we are the most comfortable to work with on the daily basis.

Let's see what's available for Ruby on Rails Application Performance Monitoring.

AppNeta

AppNeta is a SaaS heavily focused on across-network performance monitoring.

Ruby on Rails Application Monitoring with AppNeta
FreeTrial100k/mLowestSince
yes*??$119* / ?2011

Addressing the * asterisk in the comparison table: their pricing page does not reveal any details, just the plans, but I've managed to track it on the HackersNews Tools of The Trade repository.

It comes in two available Cloud plans, Public and Private

In other words, it means that you can either use their public hosting for all the monitored data or keep it on your own premises.

To get the big picture, you need to see further. Your business doesn't happen within your walls as much as it used to.

appneta.com

All that could mean that offered solutions are carefully crafted to your specific needs - you can get a quote by providing some basic information and being called or emailed by their Sales Team.

AppNeta does not maintain any open sourced Ruby gem on their official GitHub organization website for integrating with them - there are either private gems or more likely their official API that you'd need to integrate with.

One way or another, implementation costs exist and it is probably not a drop-in solution for the Ruby on Rails Application Performance Monitoring.

Summing up, AppNeta is a complex solution and probably not the first choice. Its sales transparency has some room for improvement, as it is not easy to compare with other tools in order to pick the best one for us.

AppSignal

AppSignal is a dedicated solution for monitoring Ruby on Rails and Elixir applications.

Ruby on Rails Application Monitoring with AppSignal
FreeTrial100k/mLowestSince
no30 days$7.6$19 / 250k2012

This can potentially go a long way for your Ruby on Rails Application.

My reasoning is that the dedicated solution focused on the narrow niche such as Ruby on Rails applications might easily become the best tool for the job, providing unique flavors of the framework internals monitoring out of the box.

Catch errors, track performance, monitor hosts, detect anomalies — all in one tool.

appsignal.com

On their official Github organization website, AppSignal hosts an open-sourced appsignal-ruby gem dedicated to communicating with their cloud services.

On top of that, they offer advanced integration with your Github account.

All the reported data is available via the web browser, in the neatly crafted and what seems easy to use UI.

Summing up, AppSignal offers transparent and fair pricing completed with an open-sourced gem used for implementing it in your Ruby on Rails application.

Instrumental

Instrumental provides a solution for monitoring both Ruby on Rails applications and their infrastructure.

Ruby on Rails Application Monitoring with Instrumental
FreeTrial100k/mLowestSince
noother$340$0.0034 / metric/ day2012

Free Trial marked as other means that there is a free plan with up to 500 metrics with 3 hours of data visibility - a great option for development purposes.

Next to dedicated Ruby implementation, they support .NET, Java, Node.js, PHP and Python, to name a few.

By infrastructure monitoring, they mean drop-in solutions for AWS, Docker, MySQL, PostgreSQL, MongoDB, Redis and Memcached.

Instrumental helps you quickly get answers to complex questions - and you'll feel good doing it.

instrumentalapp.com

Instrumentalapp on their official Github account hosts an open-sourced instrumental_agent-ruby gem code for integrating with their monitoring cloud.

On top of a dedicated UI, they provide Instrumental Query Language that allows end-users to aggregate, transform and time-shift all the data gathered.

Summing up, Instrumentalapp offers a complex APM solution for Ruby on Rails application performance monitoring, as well as rich infrastructure monitoring options.

However, it comes with a price not suited for small starting projects but scales nicely for big enterprises.

New Relic

New Relic is one of the most popular choices for APM solutions world-wide.

Ruby on Rails Application Monitoring with New Relic
FreeTrial100k/mLowestSince
yes14 days?$12.5 / month2007

I did not manage to break down the cheapest plans costs into the price of 100k metrics a month - if you know how to do that, please leave me a comment.

Uptime is everything. That's why observability is so critical for today’s business infrastructure.

newrelic.com

The APM plan goes way beyond just Ruby on Rails monitoring, and it includes:

New Relic on their official Github organization account hosts an open-sourced newrelic_rpm gem that transmits any Ruby on Rails application metrics to their cloud for your real-time monitoring.

Summing up, New Relic is by far one of the most complex solutions on the market. Both wide-world usage and the big corporate structure speak in its favor.

Despite the lack of an actual pricing comparison data, it is worth mentioning that this solution is not recognized as cheap on the Internet.

RoR vs Wild

RoRvsWild is a dedicated Ruby on Rails application performance monitoring solution.

Ruby on Rails Application Monitoring with RoRvsWild
FreeTrial100k/mLowestSince
< 100k14 days$0.8396 / 100k$41.98 / 5000k2017

It is worth noting that the presented prices are converted from € to $ on the day when $1.08 is €1. The actual cheapest plan's price on their website is €39 / 5000k monthly.

Slow and unreliable websites lose customers. RoRvsWild monitors the performances and errors of your Ruby on Rails applications, and provides you with insights to optimize what matters.

rorvswild.com

Ruby on Rails versus Wild is one of the products created by the small web design & development studio Base Secrète from Geneva, Switzerland, that specializes in Ruby on Rails applications.

Strong sell points of the product are the fact, that its a dedicated Rails monitoring solution and ridiculously generous free tier.

On their official Github organization account, they host an open-sourced gem rorvswild dedicated to integrating with their cloud monitoring services.

Their web UI is slick, intuitive and very easy to catch up with, and I foresee a bright future for this product when combining this fact with their freemium scope.

Summing up, RoRvsWild despite being very young, seems very promising and prospectful.

I especially recommend using it for monitoring the performance of small, rising Ruby on Rails applications.

Skylight

Skylight is yet another APM service dedicated to Ruby on Rails application monitoring.

Ruby on Rails Application Monitoring with Skylight
FreeTrial100k/mLowestSince
< 100k30 days$2.23 / 100k$20 / 1000k2012

It heavily focuses on maintaining simplicity in its dashboards, which saves us a lot of time when analyzing our Ruby on Rails application performance.

Trends at a glance. Endpoints to improve. Questions answered. Just the essentials. Not a zillion charts you don’t need.

skylight.io

On their official Github organization website, they maintain an open-sourced skylight-ruby gem serving the sole purpose of communicating with their cloud servers.

Summing up, Skylight's offer is very transparent, easy to understand and generous.

That, combined with the fact that it is a dedicated Ruby on Rails monitoring solutions makes this service very attractive.

Poor Man's Choice: Rails Performance

Not only for those who decide not to pay for APM, but also a very nice solution to have bundled into you Ruby on Rails development process for a constant overview, is a rails_performance gem.

A self-hosted tool to monitor the performance of your Ruby on Rails application. This is simple and free alternative to the New Relic APM, Datadog or other similar services.

Rails Performance README.md

It is a relatively new project that has started in January 2020, so the features are limited - it only allows real-time monitoring, with a data-retention period equal to your Redis' TTL.

What I personally like to do in my Ruby on Rails projects is launching it in the development process and glance at the dashboard from time to time.

It is not a perfect solution, but still gives me some idea on how well the Ruby on Rails application performs, and can potentially point me in the right direction.

Ruby on Rails Error and Exception Monitoring

Now that we went through our options for the Ruby on Rails application performance monitoring, the next step is to get the right tool for error and exception logging and analytics.

ToolFreeTrial100k/mLowestSince
Airbrake< 7.5k30 days$59 / 100k$59 / 100k2008
Bugsnag< 7.5k14 days$39.34 / 100k$59 / 150k2012
Honeybadger< 12k15 days$26.23 / 100k$59 / 225k2012
Raygunno14 days$79 / 100k$19 / 1k2007
Rollbar< 5k14 days$83 / 100k$83 / 1000k2012
Sentry< 5k30 days$26 / 100k$26 / 1000k2012

That's another branch of the market that is very well suited, which has roughly the same pros and cons as the APM part.

Let's see what Ruby on Rails Error and Exception Monitoring options there are available.

AirBrake

AirBrake is one of the most popular choices not only for Ruby on Rails application monitoring but also for a wide range of other languages and frameworks.

Ruby on Rails Application Monitoring with Airbrake
FreeTrial100k/mLowestSince
< 7.5k30 days$59 / 100k$59 / 100k2008

It does not monitor only errors and exceptions raised in the Ruby on Rails application - just recently they've released a dedicated APM solution along with the main product.

On their official Github organization account, they maintain an open-sourced gem airbrake dedicated to sending errors straight to their API.

What's worth mentioning, the gem equips Ruby on Rails in a very straightforward generator, a command-line tool that sets everything up with a single execution - neat.

Airbrake's powerful error monitoring is lightweight and dead simple to set up so you can spend less time tracking down problems and more time developing.

airbrake.io

On top of that, it still is fully customizable - in its basic form it just reports uncaught exceptions, but you are free to send any other events you like.

Summing up, Airbrake is a solid choice for production-scale Ruby on Rails application errors and exceptions monitoring.

However, there are cheaper options to start with, what can be considered a flaw. Read on.

Bugsnag

Bugsnag is yet another widely used tool for Ruby on Rails application errors and exceptions monitoring.

Ruby on Rails Application Monitoring with Bugsnag
FreeTrial100k/mLowestSince
< 7.5k14 days$39.34 / 100k$59 / 150k2012

Like the previous one, it does not stop on Rails but is highly recognizable among other technologies, too - over 50 in total, as they say.

Bugsnag monitors application stability so you can make data-driven decisions on whether you should be building new features, or fixing bugs.

bugsnag.com

One nice thing about it is that we have a choice between using their servers and hosting it on our own premises.

On their official Github organization website, they host an open-sourced bugsnag-ruby gem responsible for communicating with their API.

Summing up, Bugsnag is a legit solution for whose quality speaks the fact that it supports many technologies.

Combined with reasonable pricing that scales nicely, it seems like a good fit for medium to enterprise applications.

Honeybadger

Honeybadger is Ruby on Rails application monitoring for exceptions born from the frustration of the author's own Ruby on Rails project error.

Ruby on Rails Application Monitoring with Honeybadger
FreeTrial100k/mLowestSince
< 12k15 days$26.23 / 100k$59 / 225k2012

Here's a little backstory, bear with me.

Honeybadger's authors used to use a tool called Hoptoad - now Airbrake - created by Thoughtbot and then sold.

When they got frustrated with its unreliability, they created Honeybadger, which is now officially bundled with one of the most popular open-source Rails Application Templates, Suspenders, authored by Thoughtbot.

History comes full circle.

On their official Github organization website, they host an open-sourced honeybadger-ruby gem dedicated to reporting errors to their API.

Zero-instrumentation, 360 degree coverage of errors, outages and service degradation. Deploy with confidence and be your team's devops hero.

honeybadger.io

Strong sell point of the tool is the fact that it started from Ruby on Rails application monitoring, and is created by Ruby on Rails developers.

They emphasize being dedicated to smaller teams, which is exactly the case most of the time - and also a very good reason to use it from your Ruby on Rails application's production day #1.

Raygun

Raygun is yet another platform that offers crash reporting for Ruby on Rails applications and other tools, among many other solutions.

Ruby on Rails Application Monitoring with Raygun
FreeTrial100k/mLowestSince
no14 days$79 / 100k$19 / 1k2007

Here I've departed from the rule of comparing the cheapest plan, as it would heavily misrepresent this tool - in the 100k/month column I've included their second-cheapest plan for a better overview.

This is one of those full-spectrum solutions, that provides a wide range of things - APM, users' sessions monitoring and even some basic SEO analysis.

Raygun gives you visibility into how users are really experiencing your software. Detect, diagnose and resolve issues with greater speed and accuracy.

raygun.com

One can easily see that this guy's agenda is so much more than simple errors and exceptions Ruby on Rails monitoring.

Take into consideration that they're a jack of all trades which probably results in being master of none.

It'd be hard to be the best in everything, so from the errors and exceptions monitoring perspective, the dedicated, single-purpose solution might work better for you - at least in the beginning.

On their official Github organization website, they host an open-sourced raygun4ruby gem dedicated to communicating with their API.

Summing up, Raygun is long-established on the market and definitely solid solution for Ruby on Rails application crashes monitoring.

Rollbar

Rollbar is one of two solutions for Ruby on Rails application monitoring we've decided to include in Hix on Rails right from the start.

Ruby on Rails Application Monitoring with Rollbar
FreeTrial100k/mLowestSince
< 5k14 days$83 / 100k$83 / 1000k2012

It was due to the fact that it is very popular among the Ruby community, easy to set up and you can start using it for free.

Spend less time worrying and more time on improving code. With Rollbar, you can feel safe knowing every error is reported in real-time.

rollbar.com

It's worth noting that its offer is even more generous - in the annual plan you also get the first two months for free.

On their official Github organization website, you can find an open-sourced rollbar-gem, and what's even better, you can follow our comprehensive, step by step tutorial on how to set up Rollbar as the Ruby on Rails application monitoring tool.

One thing I can tell from my own experience about Rollbar is that its Ruby gem, compared to its other open-source integrations, is just a little behind.

There are some options available in other languages, such as for example PHP, and unavailable in Ruby.

Don't be put off by that though - I can still honestly recommend using Rollbar for your Ruby on Rails application monitoring.

Summing up, Rollbar is a very reliable, sophisticated solution - and I am telling you that from my own experience, as that's what I use daily at work.

Sentry

Sentry is another Ruby on Rails application monitoring solution included in Hix on Rails from its start.

Ruby on Rails Application Monitoring with Sentry
FreeTrial100k/mLowestSince
< 5k30 days$26 / 100k$26 / 1000k2012

Similar to Rollbar, we've decided to go with it due to being very popular among the Ruby on Rails community and offering a free start for everybody, no matter how big a project they develop.

Sentry scales with your application. Just keep those bugs to a minimum and you’ll love us.

sentry.io

This is so true - I still run some of my not-so-popular side-projects with Sentry hooked up and easily manage to stay on the free plan.

Hooking up a tool like Sentry for Ruby on Rails application monitoring from its first day on production goes a long way - and you can easily do that following our step by step tutorial on how to set up Sentry in Ruby on Rails.

On their official Github organization profile, they host an open-sourced raven-ruby gem, that provides easy integration with their API.

Summing up, and I am speaking from a pleasant experience as I browse my Sentry dashboard daily, it is a great tool - very generous pricing, just enough of the free plan and intuitive UI.

Poor Man's Choice: Exception Track

If you decide not to pay for error and exception monitoring in your Ruby on Rails application for whatever reason, you can still access them easily via exception-track gem.

Tracking exceptions for Rails application and storing them in the database.

Exception Track README.md

In my experience, it is especially useful for the development process, for exactly the same reasons as the aforementioned Rails Performance gem.

My usual workflow with this gem hooked up in the development environment looks like this:

This simple workflow helps to keep the focus on the task at hand and still results in leaving the previously written code not broken.

I wouldn't recommend using the tool in production though, as it is very basic and not so easy to work with.

What's next?

When we have our APM exceptions monitoring in Ruby on Rails application in place, it is time to go a little beyond Rails itself.

At some point in your career as a Ruby on Rails developer, you have probably heard about Rails not being performant and losing its popularity due to that fact.

Ruby on Rails in StackOverflow Survey 2019
StackOverflow Survey 2019

This rumor alone should be a reason enough for anybody who builds his or her business on the Ruby on Rails stack to thoroughly monitor the performance of a system that hosts it.

There are no excuses for not doing so, no matter if you use a dedicated cloud solution or your private VPS - and it is safe to say that you might end up saving yourself some money in the process by learning your limitations.

This part of your Ruby on Rails application is too important to be left unmonitored, and here are some tools that might help you get the job done.

System monitoring

For a Ruby on Rails application so-called "system", in the simplest form, the monitoring breaks down to keeping track of the following:

It should be monitored not only for your process running the Ruby on Rails application but also for anything that your app relies on, such as for example Nginx, Sidekiq, Redis, PostgreSQL - to name a few.

The market is full of ready-to-use solutions dedicated to doing just that - some of them were mentioned along with the APM products.

Here's some more, if you look for options:

I deliberately do not go into details about those tools, because they are way beyond the scope of Ruby on Rails application monitoring tutorial.

That said, every conscious maintainer should give it some thought in order to keep full control of his system.

Availability monitoring

With the system monitoring in place and assuming that your Ruby on Rails application runs behind some public domain or even just a static IP address, it is time to set up an availability monitoring.

In the most simple form, it's a classic heartbeat check - your domain gets pinged by a dedicated service every second.

If it does not respond, you get notified.

Some options to consider:

Same as with system monitoring, I deliberately do not go into specifics, as it is far beyond the Ruby on Rails application monitoring scope.

One thing I can say is that personally I find UptimeRobot very nice to work with for small projects, as it has a reasonable free tier

Downtime Happens. Get Notified! 50 Monitors, Checked Every 5 Minutes, Totally Free!

uptimerobot.com

This does not by any means suggest that you should use this tool instead of any others available. Always consider your options.

Security monitoring

This one is tricky, yet very reassuring once you have it in place. It is also one of the least covered parts of the market Rails-wise.

Let's break our options into three categories.

The first category is a list of ready-to-use tools and services that we can purchase or subscribe to. Those are:

They're available in various plans, providing pretty much the same thing - a dedicated dashboard on which you can see your Ruby on Rails application vulnerabilities.

Same as before, I'll spare you the details - review them and adapt to your specific needs. This is not cheap stuff though.

The second category is my favorite combination of three CLI tools that are easy to set up on your Continuous Integration suite, and those are:

Both Brakeman and Dawnscanner check your Ruby on Rails application code against Common Vulnerabilities and Exposures (CVE) list.

CVE - Common Vulnerabilities and Exposures
CVE - Common Vulnerabilities and Exposures

Bunder Audit does pretty much the same, just not with your app's own code, but with its dependencies.

All of the tools come with an easily executable CLI command, which makes them easy to run in CI - just remember to set their exit code to a warning, not an error, as your checks can start crashing overnight.

With those three in place, you've got yourself a nice security-breach prevention system. Just remember, it's never enough in this domain.

The third category is especially important for monitoring Ruby on Rails applications that render HTML views.

There's a multitude of attacks executable via a web browser that loads your website served by Ruby on Rails application.

With help come those tools:

The first two tools audit your domains HTTP security headers, which are:

Security Headers Report Summary
Security Headers Report Summary

On top of that, Mozilla checks:

All of those you're able to append to any HTML document you serve with your Ruby on Rails application in order to instruct the browser what actions it should execute.

The last of the tools above validates your domain's or IP's SSL certificate, which presence is pretty much standard nowadays.

Digicert SSL Report
Digicert SSL Report

Some of those headers are also applicable for the pure backend API versions of Ruby on Rails applications.

Along with the HTML documents you send, there is also a matter of assets, and one of many things worth keeping in check is the Content-Disposition header.

Take your time to read more about all of those and at least manually audit your website from time to time - as I have said before, it goes a long way.

Pagespeed monitoring

Although applicable only for Ruby on Rails applications that provide both frontend and backend and not for API-only projects, page speed monitoring is crucial for the end-user experience.

Let's see what's available:

The first solution, Pagespeed Insights is a simple tool that allows us to audit a single URL at the time.

It gives a great overview, to begin with, but this does not scale well, which gets us to the next two.

Both GTmetrix and Pingdom Website Speed Test are services that anybody can subscribe to. Depending on the selected plan, they allow constant monitoring of a fixed number of URL addresses.

Pingdom Website Speed Test Results
Pingdom Website Speed Test Results

After reviewing their plans you might think - wow, that's a little expensive for something that is not critical for the business to work.

A 100-millisecond delay in load time can cause conversion rates to drop by 7%

Akamai research, spring 2017

This can turn out as a gamechanger for a lot of businesses and is definitely worth considering in the long run.

Bonus: if you're like the most in the world, you probably use Google Analytics.

One thing you might want to consider using completely for free is a drop-in solution, a Site Performance Dashboard.

Here's how it looks:

Google Analytics Site Performance Dashboard
Google Analytics Site Performance Dashboard

In order to gather more data in the early stages of your website served by Ruby on Rails, you can simply configure the GA javascript client to send more reports by increasing the siteSpeedSampleRate parameter.

Where does might Google get this data from, you ask?

The answer is the Chrome User Experience Report.

You can also access this intel in the aforementioned Google Pagespeed Insights tool.

PageSpeed Insights Chrome User Experience Report
PageSpeed Insights Chrome User Experience Report

Yet still, it is nice to have a dedicated dashboard for it and glance at it once in a while, just in case.

One last thing worth mentioning is that the Lighthouse hosted at the web.dev is also available in the form of two NPM packages that suit perfectly into the Continuous Integration suite:

Using one of those you can probably hook it all up by yourself and avoid monthly expenses - the only cost it is going to take is your time for implementing it properly.

SEO monitoring

The last, but by no means the least important metric that we will describe here is our website's SEO.

This again does not apply to API-only Ruby on Rails application monitoring but is still worth mentioning along with other aspects of the business lifecycle.

Here are some services that you can subscribe to:

Most of them let you drop your website's URL or domain and present a thorough overview of applicable improvements.

WooRank report on Google's on-page SEO
WooRank report on Google's on-page SEO

Again, for a small price, you can automate the process and have them constantly crawl multiple endpoints in order to tell you more frequently about the problems that arise during new features development.

Conclusion

Summing it all up, Rails Application monitoring is a very complex process.

As you could see, a lot of people made a living of it, and this is good - thanks to them, you don't have to break a sweat.

Just pick a toolset that works best for you and calmly sleep through the night, knowing that dedicated services keep an eye on your Ruby on Rails application.

What's your take on the Ruby on Rails application monitoring?

Did you find an answer to your questions, is your maintainer's need satisfied?

Please let me know in the comments!

Or maybe you would like to see any of those tools integrated into the Hix on Rails Application Template?

If so, you can vote on them on our product's roadmap - all it takes is a Trello account and you're good to go!

Thanks for reading!

If you're looking for Ruby on Rails Action Mailer configuration then you are in the right place.

This tutorial explains how to configure Ruby on Rails in the production environment toward sending emails via Ruby on Rails Action Mailer integrated with the most popular email providers

Gmail, Amazon SES, Mailgun, SendGrid, and Mailchimp's Mandrill are the most popular choices for sending emails with Ruby on Rails.

Table of contents

Let's learn how to configure Ruby on Rails Action Mailer module...

ActionMailer with AmazonSES in Ruby on Rails

...or have it done

Yes, Hix does this - so you don't have to.

Ruby on Rails Action Mailer overview

Ruby on Rails Action Mailer is a module responsible for sending emails from Ruby on Rails application.

Ruby on Rails Action Mailer
Ruby on Rails Action Mailer

Ruby on Rails comes equipped with a dedicated generator, a command-line utility that builds a scaffold file structure for Mailers.

rails generate mailer OrderCompleted

Ruby on Rails Action Mailers live in the app/mailers directory of the application, inheriting from the ActionMailer::Base class.

app
└── mailers
    └── application_mailer.rb

Action Mailers have:

We can definitely see multiple similarities to Ruby on Rails controllers.

Every Ruby on Rails Action Mailer class comes rigged with self-explanatory methods, called actions:

For the complete list of options available to Ruby on Rails Action Mailer, take a look at the mail gem used by the framework.

It is possible to set the default SMTP settings on the Ruby on Rails Action Mailer instance, using the default method.

The Ruby on Rails Action Mailer configuration resides in the corresponding environment files in the config directory.

config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
config.action_mailer.preview_path = "#{Rails.root}/tmp/mailers/previews"
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  address: 'smtp.example.com',
  port: 1025,
  domain: 'example.com',
  user_name: '<username>',
  password: '<password>',
  authentication: 'plain',
  enable_starttls_auto: true
}
config.action_mailer.default_url_options = {
  host: '',
  port: 1025,
  protocol: 'http'
}

See the documentation for a full list of Ruby on Rails Action Mailer configuration options.

There are multiple ways to avoid sending emails in the Ruby on Rails development environment:

There's also a full section dedicated to testing Mailers on the Ruby on Rails website if you're using MiniTest, and RSpec has their own instructions on the matter, too.

Let's now see how to configure Ruby on Rails Action Mailer to send emails with the most popular email providers.

Ruby on Rails Action Mailer Gmail configuration

Ruby on Rails Action Mailer is able to send emails with the Gmail account when provided matching SMTP configuration.

Gmail, standing for Google Mail, enables each account to send 500 emails each day through its SMTP server in the free plan.

It is also worth reviewing the GSuite sending limits (2,000 for standard and 500 for trial accounts) if your Ruby on Rails application is going to send more emails than that.

Ruby on Rails Action Mailer with Gmail
Ruby on Rails Action Mailer with Gmail

Let's dive into it.

Gmail account setup

In order to use Ruby on Rails Action Mailer with Gmail, the best solution that does not violate your other security measures such as 2-Step Verification is using App Password.

If your account uses 2-Step Verification, the App Password is a 16-digit passcode that gives a non-Google device or app access to your Google Account.

Follow the steps below in order to generate your Gmail App Password.

  1. Open your Google Account Security settings.Google Account Security settings
    Google Account Security settings
  2. In "Signing to Google" tile, navigate to App passwords.
  3. Google might ask you to reauthenticate at this point.
  4. On the App passwords page, select the "Mail" app and "Other" device, providing the name of your Ruby on Rails application. Then, click "Generate".Create App Password
    Generate Google App Password
  5. That's it, copy your App Password from the yellow box.Copy your App Pasword
    Copy your App Pasword

If you are using a Gmail account that is not secured with 2-Step Verification, you can simply use your usual password instead, as the App passwords functionality is not available in this case.

Gmail Rails config

Ruby on Rails Action Mailer is able to send emails via Gmail with simple SMTP settings configured in the chosen environment files.

It does not require any additional gems to be installed, as it's just a simple SMTP configuration, available for many other email providers as well.

config/production.rb

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  port: 587,
  address: 'smtp.gmail.com',
  user_name: 'wiktor.plaga@gmail.com',
  password: 'abcdef0123456789',
  authentication: :plain,
  enable_starttls_auto: true
}

Storing information that sensitive is a bad idea though, so you're better of keeping it in the environment variables, using dotenv-rails gem.

.env

SMTP_USER_NAME=wiktor.plaga@gmail.com
SMTP_PASSWORD=abcdef0123456789

With this in place, edit the Ruby on Rails Action Mailer SMTP configuration as follows.

config/production.rb

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  port: 587,
  address: 'smtp.gmail.com',
  user_name: ENV['SMTP_USER_NAME'],
  password: ENV['SMTP_PASSWORD'],
  authentication: :plain,
  enable_starttls_auto: true
}

At this point, your Ruby on Rails Action Mailer can easily send emails using your Gmail account.

Ruby on Rails Action Mailer Amazon SES configuration

Ruby on Rails Action Mailer is easily configurable to use Amazon Simple Email Service.

Ruby on Rails Action Mailer with Amazon SES
Ruby on Rails Action Mailer with Amazon SES

Let's do it.

Amazon SES account setup

In order for Ruby on Rails Action Mailer to send emails via Amazon SES, you need to create the AWS account.

After doing so, follow the steps below.

  1. Log into your AWS Console.
  2. In the "Services" dropdown go to "Customers Engagement" section and navigate to "Simple Email Service".AWS Simple Email Service
    Navigate to Amazon Simple Email Service
  3. In the left-hand sidebar navigate to "SMTP Settings", copy your "Server name" and click the "Create My SMTP Credentials" button.Create My SMTP Credentials
    Create Amazon SES SMTP Credentials
  4. Click the "Create" button.Click the Create button
    Click the Create button
  5. Download or copy Amazon SES SMTP credentials for later usage.Download Amazon SES SMTP credentials
    Download Amazon SES SMTP credentials

Sending emails in production via Amazon SES additionally requires requesting a sending limit increase - after doing so, you will be able to send emails to everybody.

You can do that in Email Sending > Sending Statistics > Request Sending Limit increase.

Production: Request Sending Limit Increase
Production: Request Sending Limit Increase

However, in order to test your Ruby on Rails Action Mailer configuration, it's enough to verify your email address in Identity Management > Email Addresses section of the Amazon SES dashboard.

Verify testing email
Verify testing email

Add your email address to which you want to send a message via Ruby on Rails Action Mailer and head to your mailbox - you will receive a verification link.

After securely saving the SMTP credentials for Amazon SES usage, let's move to Ruby on Rails Action Mailer configuration.

Amazon SES Rails config

Ruby on Rails Action Mailer needs SMTP configuration toward sending emails via Amazon Simple Email Service.

config/production.rb

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  port: 587,
  address: 'email-smtp.eu-west-1.amazonaws.com',
  user_name: 'your-aws-smtp-username',
  password: 'your-aws-smtp-username',
  authentication: :plain,
  enable_starttls_auto: true
}

In order to follow the Twelve-Factor App guideline, it is better to use environment management gem such as dotenv-rails.

.env

SMTP_ADDRESS=email-smtp.eu-west-1.amazonaws.com
SMTP_USER_NAME=your-aws-smtp-username
SMTP_PASSWORD=your-aws-smtp-password

With environment variables in place, you are ready to edit the configuration file as follows.

config/production.rb

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  port: 587,
  address: ENV['SMTP_ADDRESS'],
  user_name: ENV['SMTP_USER_NAME'],
  password: ENV['SMTP_PASSWORD'],
  authentication: :plain,
  enable_starttls_auto: true
}

All done, your Ruby on Rails Action Mailer is ready to send emails via Amazon SES SMTP account.

Ruby on Rails Action Mailer Mailgun configuration

Ruby on Rails Action Mailer is capable of sending emails with Mailgun via its SMTP configuration.

Ruby on Rails Action Mailer with Mailgun
Ruby on Rails Action Mailer with Mailgun

Let's dive in.

Mailgun account setup

In order for Ruby on Rails Action Mailer to send emails with Mailgun via SMTP, you need to create your Mailgun account.

Follow the steps below.

  1. Create an account on the official Mailgun website.Mailgun Signup website
    Mailgun signup form
  2. Choose your Mailgun plan.Choose your Mailgun plan
    Choose your Mailgun plan

In order to send emails, you have to additionally verify your domain by adding required TXT records to your domain's DNS.

Let's now set up Ruby on Rails Action mailer with the brand new Mailgun account.

Mailgun Rails config

Ruby on Rails Action Mailer is able to send emails via your Mailgun account with this simple configuration.

config/production.rb

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  port: 587,
  address: 'smtp.mailgun.org',
  domain: 'hixonrails.com',
  user_name: 'wiktorplaga@hixonrails.com',
  password: 'secret-mailgun-account-password',
  authentication: :plain
}

It is better not to store any secrets in your Ruby on Rails application source code, so we recommend using dotenv-rails gem instead.

.env

DOMAIN_NAME=hixonrails.com
SMTP_USER_NAME=wiktorplaga@hixonrails.com
SMTP_PASSWORD=secret-mailgun-account-password

config/production.rb

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  port: 587,
  address: 'smtp.mailgun.org',
  domain: ENV['DOMAIN_NAME'],
  user_name: ENV['SMTP_USER_NAME'],
  password: ENV['SMTP_PASSWORD'],
  authentication: :plain
}

That's it, you can start sending emails now.

However, there's another thing to consider when it comes to sending emails with Ruby on Rails using Mailgun.

Mailgun exposes an email sending API, that's dedicated for better long term performance and maintenance wise.

Mailgun SMTP and API comparison
Mailgun SMTP and API comparison

In order for your Ruby on Rails application to send emails with Mailgun API, you can use the mailgun-ruby gem.

Add the following to your Gemfile.

Gemfile

gem 'mailgun-ruby'

and run bundle install.

The last step toward sending emails via Mailgun API with Ruby on Rails Action mailer is its configuration.

Mailgun sends you the API key upon account registration.

Registration email with Mailgun API Key.
Registration email with Mailgun API Key.

In case you've already deleted it, it's still available on your Mailgun account > Settings > API Keys section.

Mailgun API Key in Settings > API Keys dashboard
Mailgun API Key in Settings > API Keys dashboard

Now that you've got the Mailgun API key ready, let's add it to the Ruby on Rails Action Mailer configuration file.

config/production.rb

config.action_mailer.delivery_method = :mailgun
config.action_mailer.mailgun_settings = {
  api_key: 'api-myapikey',
  domain: 'mydomain.com',
  # api_host: 'api.eu.mailgun.net'  # Uncomment this line for EU region domains
}

Both configuration values are better off residing in the dedicated environment file.

.env

DOMAIN_NAME=hixonrails.com
MAILGUN_API_KEY=api-myapikey

config/production.rb

config.action_mailer.delivery_method = :mailgun
config.action_mailer.mailgun_settings = {
  api_key: ENV['MAILGUN_API_KEY'],
  domain: ENV['DOMAIN_NAME'],
  # api_host: 'api.eu.mailgun.net'  # Uncomment this line for EU region domains
}

That's it, your Ruby on Rails Action Mailer is ready to send emails via Mailgun API.

Ruby on Rails Action Mailer SendGrid configuration

Ruby on Rails Action Mailer is easily configurable to send emails with SendGrid.

Ruby on Rails Action Mailer with SendGrid
Ruby on Rails Action Mailer with SendGrid

Let's do it.

SendGrid account setup

Let's create a free account for sending emails with Ruby on Rails Action Mailer with SendGrid.

Follow the steps below.

  1. Start for free on an official SendGrid website.SendGrid official website
    SendGrid official website
  2. Provide your username, password and email address.Provide account credentials
    SendGrid signup - account credentials
  3. Visit your mailbox and verify the email address provided.
  4. Provide further personal and business information.Provide account personal information
    SendGrid signup - personal information
  5. In account's dashboard "Send your first email" section, click the "Start" button in the first "Integrate using our Web API or SMTP relay" section.Integrate SendGrid Web API or SMTP relay
    Integrate SendGrid Web API or SMTP relay

At this point, there are two alternative ways to obtain SendGrid credentials for sending emails with Ruby on Rails Action Mailer module.

The first way is a classic SMTP integration.

Follow the steps below in order to obtain your SendGrid SMTP account password.

  1. Choose "SMTP Relay" integration option.SendGrid SMTP relay integration
    Choose "SMTP relay" integration
  2. Provide your first API key name, click "Create Key" and copy the generated key.
    SendGrid API key creation
    SendGrid key form
  3. On the bottom of the page, check the checkbox and click the "Next: Verify Integration" button.SendGrid API key verification
    SendGrid API key verification

The second option, that's recommended by SendGrid, is using the Web API. This will require installing an additional third-party gem to work with Ruby on Rails Action Mailer.

Follow the steps below for generating your SendGrid Web API key.

  1. Choose "Web API" integration option.SendGrid Web API integration
    Choose "Web API" integration
  2. Choose Ruby language.SendGrid Ruby language integration
    Choose Ruby language
  3. Provide your first API key name, click "Create" and copy the generated API key.SendGrid API key creation
    SendGrid API key form
  4. On the bottom of the page, check the checkbox and click the "Next: Verify Integration" button.SendGrid API key verification
    SendGrid API key verification

Now that we've created the SendGrid account with all the credentials required, let's get to Ruby on Rails Action Mailer configuration.

SendGrid Rails config

In order for Ruby on Rails Action Mailer to send emails with SendGrid, we need proper SMTP settings in place.

config/production.rb

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  user_name: 'your_sendgrid_username',
  password: 'your_sendgrid_password',
  domain: 'yourdomain.com',
  address: 'smtp.sendgrid.net',
  port: 465,
  authentication: :plain,
  enable_starttls_auto: true
}

Although it is better to keep those secrets out. Use dotenv-rails gem instaed.

.env

DOMAIN_NAME=hixonrails.com
SMTP_USER_NAME=wiktorplaga
SMTP_PASSWORD=you-will-never-guess-it

With those environment variables in place, replace a previous configuration with the following.

config/production.rb

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  user_name: ENV['SMTP_USER_NAME'],
  password: ENV['SMTP_PASSWORD'],
  domain: ENV['DOMAIN_NAME'],
  address: 'smtp.sendgrid.net',
  port: 465,
  authentication: :plain,
  enable_starttls_auto: true
}

In order to test the SMTP integration locally, you might need to change the port to 25 or 587, as the 465 is reserved for SSL connections and does not work unless you have a local self-signed certificate.

There's also another way for Ruby on Rails Action Mailer to send emails with SendGrid - it's by using SendGrid API.

First, install the sendgrid-actionmailer gem

The gem also extends the usual mail action with SendGrid-specific options that are not available with the default Ruby on Rails Action Mailer functionality.

Gemfile

gem 'sendgrid-actionmailer'

After running bundle install in the CLI, prepare your Ruby on Rails Action Mailer configuration for SendGrid API.

.env

SENDGRID_API_KEY=your-sendgrid-api-key

config/production.rb

config.action_mailer.delivery_method = :sendgrid_actionmailer
config.action_mailer.sendgrid_actionmailer_settings = {
  api_key: ENV['SENDGRID_API_KEY'],
  raise_delivery_errors: true
}

Your Ruby on Rails Action Mailer is now ready to send emails via SendGrid API.

Go back to your SendGrid dashboard and verify the previously generated SMTP or API key.

Ruby on Rails Action Mailer Mandrill configuration

Ruby on Rails Action Mailer is able to integrate with Mandrill via SMTP settings.

Ruby on Rails Action Mailer with Mandrill
Ruby on Rails Action Mailer with Mandrill

Let's set it up.

Mandrill account setup

Mandrill is a transactional email API for Mailchimp users.

Mandrill is available as an add-on to Standard and higher monthly plans, or the legacy Monthly Plan. Free, Essentials, and Pay As You Go users will need to upgrade to use Mandrill.

Mailchimp's Mandrill documentation

Follow the steps below to create your Mailchimp account.

  1. Visit the official Mailchimp website and fill out the signup forms.
  2. Next, add Mandrill to your Mailchimp account.
  3. In your account API settings, create Mandrill API Key.

Let's move to the Ruby on Rails Action Mailer configuration.

Mandrill Rails config

With Mandrill API Key in place, you're ready to configure Ruby on Rails Action Mailer SMTP settings to work with Mandrill.

config/production.rb

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  address: 'smtp.mandrillapp.com',
  port: 25,
  enable_starttls_auto: true,
  user_name: 'wiktorplaga@hixonrails.com',
  password: 'mandrill-api-key',
  authentication: 'login',
  domain: 'hixonrails.com'
}

However, it's better to use dotenv-rails gem.

.env

DOMAIN_NAME=hixonrails.com
MANDRILL_USERNAME=wiktorplaga@hixonrails.com
MANDIRLL_API_KEY=mandrill-secret-api-key

With those Mandrill environments variables in place, the production configuration file looks like this.

config/production.rb

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  address: 'smtp.mandrillapp.com',
  port: 25,
  enable_starttls_auto: true,
  user_name: ENV['MANDRILL_USERNAME'],
  password: ENV['MANDRILL_API_KEY'],
  authentication: 'login',
  domain: ENV['DOMAIN_NAME']
}

Your Ruby on Rails Action Mailer is ready to send emails with Mandrill.

Conclusion

Ruby on Rails Action Mailer configuration is simple and straightforward no matter what email service you use.

All it takes is a few SMTP configuration options, and in some cases, an additional gem.

In order to configure Action Mailer along with your Ruby on Rails application setup, use Hix on Rails Application Template.

In this Ruby on Rails tutorial, we are going to configure Ruby on Rails Active Storage module to work with Google Cloud Platform, Amazon AWS S3 Buckets, and Microsoft Azure Cloud.

Table of contents

Let us learn more about Ruby on Rails Active Storage setup...

ActiveStorage GCS, S3, Azure Blob config

...or have it done

Yes, Hix does this - so you don't have to.

What is Ruby on Rails Active Storage?

Ruby on Rails Active Storage is responsible for storing any files in the Ruby on Rails application and exposing them to Ruby on Rails application's Active Record objects.

Ruby on Rails Active Storage out of the box comes equipped with four different file storage options:

and on top of that, supports mirroring files between multiple storage destinations for sane migrations and backups.

Furthermore, Ruby on Rails Active Storage equips the application into the ability to perform various file transformations:

Ruby on Rails Active Storage is the module to use whenever in need to do any kind of work on files.

If your Ruby on Rails application needs to store an avatar uploaded by a user in order to easier identify him in your web app, use Ruby on Rails Active Storage module.

Files with different extensions

If your Ruby on Rails application needs to generate payment invoices in order to later send them via email, use Ruby on Rails Active Storage module.

Ruby on Rails Active Storage configuration overview

In order to work, Ruby on Rails Active Storage requires two tables in your application's database:

In order to acquire Ruby on Rails migrations creating those tables and then create them in your Ruby on Rails application, run

rails active_storage:install
rails db:migrate

Ruby on Rails Active Storage supports declaring multiple services configuration usage, with an ability to keep multiple storage services mirrored.

The Ruby on Rails Active Storage configuration file bases on two special keys in order to synchronize files between multiple storage services:

This is especially useful in order to safely migrate between services in the production environment of the Ruby on Rails application with zero downtime.

While configuring Ruby on Rails Active Storage in your application, you are going to be interested in the following files.

On top of the default Ruby on Rails environments, any other environment configuration file that your application defines, such as for example config/environments/staging.rb, is going to configure the Ruby on Rails Active Storage module.

Ruby on Rails Active Storage server disk usage configuration

Let us take a look at the most basic configuration for the Ruby on Rails Active Storage module - the simple server disk usage.

Ruby on Rails Active Storage on server disk
Ruby on Rails Active Storage on server disk

This is the default configuration that comes with Ruby on Rails project intialization.

config/storage.yml

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

The example Ruby on Rails Active Storage file defines two services, local and development.

Both of them save files to defined Ruby on Rails application directories, let's make sure they are created in your project root.

cd /path/to/rails/app
mkdir files
mkdir -p tmp/files

This should be optional unless your Ruby on Rails application was initialized with the --skip-active-storage configuration option.

The test service takes advantage of the temporary directory, that's usually ignored by git version control in the .gitignore file.

The disk service is the one that you'd probably want to use in the development and potentially in the production environment.

It would also go to the .gitignore file, yet you wouldn't want to lose it on production - anyway, make sure its there for the development process.

.gitignore

/storage/*
/tmp/*

Let's now take a look at the Ruby on Rails Active Storage environment configuration file - let it be the test one, as it will most likely look like in most of Ruby on Rails applications.

config/environment/test.rb

config.active_storage.service = :test

This simple configuration option accepts a symbol representing the service name previously defined in the Ruby on Rails Active Storage configuration file.

In our case, it tells Ruby on Rails Active Storage module to write to the temporary files directory while running the app in the test environment.

Configuration of other environments' Ruby on Rails Active Storage module is going to look like that:

config/environment/production.rb, config/environment/development.rb

config.active_storage.service = :local

And that's pretty much it.

Continue reading in order to learn how to use third-party cloud storage services with Ruby on Rails Active Storage module.

Ruby on Rails Active Storage Google Cloud Platform configuration

Google Cloud Platform Storage service connection is easily configurable with Ruby on Rails Active storage module.

Ruby on Rails with Google Cloud Storage
Ruby on Rails Active Storage with Google Cloud Storage

The most difficult part of the process is not Ruby on Rails code-related - yet still worth automating with Hix on Rails - but the whole setup on the Google Cloud Platform part.

Let's get through it.

GCP account setup and bucket creation

In order to use Google Cloud Storage with Ruby on Rails Active Storage module, we need to create an account first. Follow these steps in order to do that.

  1. On the official Google Cloud Storage website page, click "Try it free".Try Google Cloud Storage for free
    Try Google Cloud Storage for free
  2. You will be asked to log into your Google account. Do that, or create one if you don't have it.
  3. In the first step of Google Cloud account creation, confirm that Google guessed your country of origin correctly and accept the terms and conditions.Google Cloud Storage account creation step 1
    Step 1 of Google Cloud Storage account creation
  4. In the second step, sell your soul to Google providing your address and credit card information. You might choose between an "Individual" and "Business" accounts here, too.Google Cloud Storage account creation step 1
    Step 2 of Google Cloud Storage account creation
  5. Click "Start my free trial", and on the next page click the "Got it" button in the welcome popup.Welcome to Google Cloud Platform
    Welcome to Google Cloud Platform

You are now on your Google Cloud Platform dashboard dedicated to Storage management. By default, Google Cloud Platform creates an entity called "My First Project".

For the purposes of this guide, we are going to use it, but in your Ruby on Rails production projects, it's worth creating a project with a more meaningful name than that.

  1. Click the "Create bucket", and then close the popup window by clicking the "Got it" button.Click Create bucket button
    Click "Create bucket" button
  2. In the first step of the bucket creation, provide its name - if not sure, go through the bucket naming guidelines - and then click "Continue". Keep your bucket name in mind in order to connect to it via Ruby on Rails Active Storage module.Name your bucket and click continue
    Name your bucket and click continue
  3. In the next step, select storage location best matching your Ruby on Rails application audience, then click "Continue".Adjust bucket location settings
    Adjust bucket location settings
  4. Depending on your need, select the storage data class - it defines how often your files are going to be accessed. Then, click "Continue".Select bucket storage data class
    Select bucket storage data class
  5. In the access control step, it is best to leave it as-is if in doubt.Adjust bucket access control if needed
    Adjust bucket access control if needed
  6. The rest of the configuration is optional - click "Continue" in order to review it, and then click the "Create" button.

Now that we've created the Google Cloud Platform account and our first bucket in the Storage service, let's get through the authorization part.

GCP storage credentials

Follow the credentials generation process in order to authorize Ruby on Rails Active Storage to connect to Google Cloud Storage.

  1. Go to the Google Cloud service account management website.
  2. Click the "Open the IAM & Admin page" button.Open the IAM and Admin page
    Open the IAM & Admin page
  3. Click "Select a project", choose a project, and click "Open".
  4. In the left-hand sidebar, navigate to "Service accounts" page.Service accounts in sidebar
    Service accounts in sidebar
  5. On the service accounts page, click the "Create service account" button.Create service account
    Create service account
  6. Provide service account name. The ID is autogenerated from the name, and description is optional. Click the "Create" button.Provide service account name
    Provide service account name
  7. Optionally set the service account permissions to Storage Admin. Then, click the "Continue" button.Service account permissions
    Service account permissions
  8. In the next step, click the "Create key" button.Create service account credentials
    Create service account credentials
  9. In the right-hand sidebar, select JSON option and click "Create".Create service account credentials
    Create service account credentials
  10. The private key was downloaded. Save it for further usage in the Ruby on Rails Active Storage configuration.Private access key generated succesfully
    Private access key generated succesfully

Now that we've successfully obtained the Google Cloud Storage JSON credentials private key, let's connect our Ruby on Rails Active Storage using it.

GCP Rails configuration

For Ruby on Rails Active Storage to work with Google Cloud Storage there's a dedicated gem required to be installed.

Add the following to your Ruby on Rails application Gemfile file.

Gemfile

gem 'google-cloud-storage'

Next, open the downloaded Google Cloud Storage JSON file with a text editor of your choice.

keyfile.json

{
  "type": "service_account",
  "project_id": "40hallowed-ridge-264013",
  "private_key_id": "32976f16b04ece6a6fb8bc3bb4c52ea48f738bb8",
  "private_key": "-----BEGIN PRIVATE KEY-----\n<.....>\n-----END PRIVATE KEY-----\n",
  "client_email": "hix-on-rails@40hallowed-ridge-264013.iam.gserviceaccount.com",
  "client_id": "102135739378581270686",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/hix-on-rails%40hallowed-ridge-264013.iam.gserviceaccount.com"
}

Ruby on Rails Active Storage supports two types of configuration for the Google Cloud Storage service.

The first way to configure Ruby on Rails Active Storage to connect with your Google Cloud Storage bucket is by using the credentials key, which accepts a path to the JSON credentials file stored in your Ruby on Rails application directory.

config/storage.yml

google:
  service: GCS
  credentials: <%= Rails.root.join("path/to/keyfile.json") %>
  project: "My First Project"
  bucket: "hix-on-rails-active-storage"

The second option is to pass each of the configuration options defined in the Google Cloud Storage JSON file separately.

config/storage.yml

google:
  service: GCS
  credentials:
    type: "service_account"
    project_id: "hallowed-ridge-264013"
    private_key_id: "32976f16b04ece6a6fb8bc3bb4c52ea48f738bb8"
    private_key: "-----BEGIN PRIVATE KEY-----\n<.....>\n-----END PRIVATE KEY-----\n"
    client_email: "hix-on-rails@hallowed-ridge-264013.iam.gserviceaccount.com"
    client_id: "102135709378581270686"
    auth_uri: "https://accounts.google.com/o/oauth2/auth"
    token_uri: "https://accounts.google.com/o/oauth2/token"
    auth_provider_x509_cert_url: "https://www.googleapis.com/oauth2/v1/certs"
    client_x509_cert_url: "https://www.googleapis.com/robot/v1/metadata/x509/hix-on-rails%40hallowed-ridge-264013.iam.gserviceaccount.com"
  project: "My First Project"
  bucket: "hix-on-rails-active-storage"

In both cases, it is not the best idea to keep any secrets in the version control system. Let's install the dotenv-rails gem instead and put all the configuration into the dedicated .env file.

.env

GCS_PROJECT_ID=hallowed-ridge-264013
GCS_PRIVATE_KEY_ID=32976f16b04ece6a6fb8bc3bb4c52ea48f738bb8
GCS_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n<.....>\n-----END PRIVATE KEY-----\n"
GCS_CLIENT_EMAIL=hix-on-rails@hallowed-ridge-264013.iam.gserviceaccount.com
GCS_CLIENT_ID=102135709378581270686
GCS_AUTH_PROVIDER_X509_CERT_URL=https://www.googleapis.com/robot/v1/metadata/x509/hix-on-rails%40hallowed-ridge-264013.iam.gserviceaccount.com
GCS_PROJECT="My first project"
GCS_BUCKET=hix-on-rails-active-storage

After doing that, simply use all the environment variables in the Ruby on Rails Active Storage configuration file.

config/storage.yml

google:
  service: GCS
  credentials:
    type: "service_account"
    project_id: <%= ENV['GCS_PROJECT_ID'] %>
    private_key_id: <%= ENV['GCS_PRIVATE_KEY_ID'] %>
    private_key: <%= ENV['GCS_PRIVATE_KEY'] %>
    client_email: <%= ENV['GCS_CLIENT_EMAIL'] %>
    client_id: <%= ENV['GCS_CLIENT_ID'] %>
    auth_uri: "https://accounts.google.com/o/oauth2/auth"
    token_uri: "https://accounts.google.com/o/oauth2/token"
    auth_provider_x509_cert_url: "https://www.googleapis.com/oauth2/v1/certs"
    client_x509_cert_url: <%= ENV['GCS_CLIENT_X509_CERT_URL'] %>
  project: <%= ENV['GCS_PROJECT'] %>
  bucket: <%= ENV['GCS_BUCKET'] %>

This way your Google Cloud Storage credentials are not stored in the repository holding your Ruby on Rails application code and are less likely to get stolen.

Ruby on Rails Active Storage AWS S3 configuration

Amazon Web Services AWS S3 storage service connection is easily configurable with Ruby on Rails Active Storage module.

Ruby on Rails with AWS S3
Ruby on Rails Active Storage with Amazon S3

The most difficult part of the configuration is the whole setup on the Amazon Web Services AWS S3 part - yet it is still worth it to automate Ruby on Rails Active Storage configuration with Hix on Rails.

Let's dive into it.

AWS account setup

Get through the following steps in order to create your Amazon account for connecting Ruby on Rails Active Storage with the AWS S3 service.

  1. Go to AWS Amazon S3 official website and click "Get Started with Amazon S3" button.Get started with Amazon S3
    Get Started with Amazon S3
  2. Click the "Create new account" button. If you have an account already, you can skip the rest of these steps.Create new Amazon account
    Create new Amazon account
  3. Provide your account email, password and name. Then click the "Continue" button.Provide your account email, password and name
    Provide your account email, password and name
  4. Sell your soul to Amazon providing your full name and address data. At this point it is possible to create either "Personal" or "Business" account. Then click the "Create account and continue" button.Provide your credentials and address
    Provide your credentials and address
  5. Provide your Credit Card information and click the "Verify and Add" button.Provide your credit card information
    Payment information
  6. Select the country and provide your phone number in order to get the verification code. Fill up the security check input, then click the "Send SMS" button.Provide phone number
    Identity verification: country and phone number
  7. Wait for the SMS message and enter your verification code, then click the "Verify code" button.Enter the veirification code
    Identity verification: enter the code form SMS message
  8. In the successful verification popup, click the "Continue" button.Identity verification success
    Identity verification success
  9. Select your support plan. It's good to start for free and upgrade it as you need.Amazon Support plan
    Select Amazon Support plan
  10. Click the "Sign in to the Console" button.Sign in to the Console
    Welcome to the AWS

Now that you've created your AWS account, let's create the Amazon S3 bucket.

Follow the steps below in order to do that.

  1. Sign in to the AWS Management Console providing email and password to your account.Sign in to AWS Management Console
    Sign in to AWS Management Console
  2. Click the "Services" dropdown in the navigation bar and navigate to the "Storage / S3" page.Navigate to Storage S3 Service
    Navigate to Storage S3 Service
  3. In the S3 dashboard, click the "Create bucket" button.Create S3 bucket
    Click the "Create bucket" button
  4. Enter your bucket name and select its region - it is important to remember for further Ruby on Rails Active Storage configuration. Then, click the "Next" button.S3 bucket name and region
    Provide S3 bucket name and region
  5. Browse through the S3 bucket configuration options. Then click the "Next" button.S3 bucket configuration options
    S3 bucket configuration options
  6. Adjust your S3 bucket permissions settings, they can be changed later if needed. When done, click the "Next" button.S3 bucket permissions settings
    S3 bucket permissions settings
  7. In the final step, review all the information provided, then click the "Create bucket" button.S3 bucket settings review
    S3 bucket settings review

The last step for Ruby on Rails Active Storage module towards accessing your Amazon AWS S3 bucket is obtaining your account credentials.

Let's see how to do that.

AWS storage credentials

With regard to the AWS Best Practices, we are going to create a special user for our Ruby on Rails Active Storage module, with access specifically set to the Amazon AWS S3 service only.

The Amazon access can be modified at any point for given users.

Follow the steps below.

  1. In the AWS S3 dashboard, click your account dropdown and "My Security Credentials" link.Amazon account Security Credentials
    Navigate to Amazon account Security Credentials
  2. In the popup, click the "Get Started with IAM Users" button.Get Started with IAM Users
    Get Started with IAM Users
  3. In the Identity and Access Management dashboard, click the "Add user" button.Add AWS user
    Click the "Add user" button
  4. Enter the user name and password, and allow programmatic and AWS Management Console access. Do not require a password change. Then, click the "Next: Permissions" button.Amazon user credentials and access
    Provide name, password and access options
  5. Click the "Attach existing policies directly" tile, then search for "S3" and check the "AmazonS3FullAccess" option.Grant full access to Amazon S3
    Grant full access to Amazon S3
  6. Optionally, add user tags. When done, click the "Next: Review" button.Amazon S3 user tags
    Optional Amazon S3 user tags
  7. Review the new user, then click the "Create user" button.Amazon S3 user creation review
    Amazon S3 user creation review
  8. Copy your "Access key ID" and "Secret access key".Get your Amazon S3 user credentials
    Get your Amazon S3 user credentials
  9. At this point, it is also good to backup your access keys CSV file safely, just in case.

Now that we've obtained Amazon AWS S3 credentials, let's finalize connecting the Ruby on Rails Active Storage module to our freshly created AWS S3 bucket.

AWS Rails configuration

Ruby on Rails Active Storage module is able to connect with your Amazon AWS S3 service thanks to aws-sdk-s3 gem.

Open your project's Gemfile file and add the following.

gem 'aws-sdk-s3'

Now, let's get to the Ruby on Rails Active Storage configuration.

Browse a full list of AWS regions in order to find your S3 bucket region code.

config/storage.yml

s3:
  service: S3
  access_key_id: "AKIAIOSFODNN7EXAMPLE"
  secret_access_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
  region: "eu-west-2"
  bucket: "hix-on-rails"

Adjust the Ruby on Rails Active Storage configuration file with your Amazon AWS S3 credentials.

A better way to store Ruby on Rails application credentials is by using the dotenv-rails gem. After installing it, create the .env file and add the following.

.env

AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
AWS_BUCKET=hix-on-rails
AWS_REGION=eu-west-2

The next step is to load those environment variables into the Ruby on Rails Active Storage configuration file.

config/storage.yml

s3:
  service: S3
  access_key_id: <%= ENV['AWS_ACCESS_KEY'] %>
  secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %>
  region: <%= ENV['AWS_REGION'] %>
  bucket: <%= ENV['AWS_BUCKET'] %>

This way you don't store any secrets in your Ruby on Rails project's version control system - other supported ways to achieve the same goal are using different configuration methods of the AWS Ruby SDK package.

Ruby on Rails Active Storage Microsoft Azure Cloud configuration

Microsoft Azure Blob Storage service connection is easily configurable with Ruby on Rails Active Storage module.

Ruby on Rails with Microsoft Azure
Ruby on Rails Active Storage with Microsoft Azure Blob Storage

Once you get through the Microsoft Azure Blob Storage account creation and setup, it is worth to automate the Ruby on Rails Active Storage configuration with Hix on Rails.

Let's rock.

Azure account setup

For Ruby on Rails Active Storage to work with Microsoft Azure Storage, the Microsoft account and Microsoft Azure account are needed.

Follow the steps below in order to create a Microsoft account.

  1. Visit the Microsoft Azure Storage website and click the "Start free" button.Start for free with Microsoft Azure
    Start for free with Microsoft Azure
  2. On the next page, click the "Start free" button.Start for free with Microsoft Azure
    Start for free with Microsoft Azure
  3. Provide your account email, then click the "Next" button.Provide your account email
    Provide your account email
  4. Provide your account password, then click the "Next" button.Provide your account password
    Provide your account password
  5. Provide your country and birth date, then click the "Next" button.Provide your country and birth date
    Provide your country and birth date
  6. Go to your email account, copy and paste the verification code. Then click the "Next" button.Verify the account email
    Verify the account email

Now that we have created the Microsoft account, we are going to create the Microsoft Azure account related to it.

You should be redirected to the form presented below.

  1. Provide your basic credentials - country, first and last name, email, phone number and optionally your company VAT ID. Then click the "Next" button.Provide your basic credentials
    Provide your basic credentials
  2. After entering your phone number, click the "Text me" button.Verify your phone number
    Verify your phone number
  3. Wait for the SMS message and enter the code received. Wait for the verification to complete and click the "Next button".Identity SMS verification
    Identity SMS verification
  4. Sell your soul to Microsoft providing all the necessary billing data. Then click the "Next" button.Provide billing data
    Provide billing data
  5. Check the required agreements and click the "Sign up" button.Agree and sign up
    Agree and sign up

That's it, both Microsoft accounts required by Ruby on Rails Active Storage are ready to use.

In the new account, let's create the "Storage account" and an entity that's specific to Azure, called "Container", which is an equivalent to AWS S3 and Google Cloud Storage "Bucket".

  1. Click the "Go to portal" button.Go to portal
    Go to portal
  2. Skip the Azure usage wizard for now by clicking "Maybe later" button in the popup.Skip the Azure usage wizard
    Skip the Azure usage wizard
  3. In the top-left corner open the hamburger menu and navigate to the "Storage accounts" page.Navigate to Storage accounts page
    Navigate to Storage accounts page
  4. Click the "Create storage account" button.Create storage account
    Create storage account
  5. Provide account name, select its location and optionally browse through all the configuration tabs. Then click the "Review + Create" button.Provide account data
    Provide account data
  6. Wait for the account validation, then click the "Create" button.Wait for validation and create account
    Wait for validation and create account
  7. Wait for the container to be created - it will take up to 5 minutes. Then click the "Go to resource" button.Go to resource
    Go to resource
  8. Click the "Containers" tile.Navigate to Containers
    Navigate to Containers
  9. Click the "+ Container" link, provide your container data and click the "OK" button.Create your container
    Create your container

With all this in place, let's collect the final piece required for Ruby on Rails Active Storage to work with our Microsoft Azure account.

Azure storage credentials

The last step toward working Ruby on Rails Active Storage module reading and writing files to our Microsoft Azure Storage service is obtaining its credentials.

In order to do that, in the left-hand sidebar "Settings" section navigate to the first section named "Access keys".

Obtain Microsoft Azure credentials

Leave this page open for the Ruby on Rails Active Storage configuration described in the next step.

Azure Rails configuration

In order to work, Ruby on Rails Active Storage requires the dedicated gem.

Open your Gemfile and add the following.

gem 'azure-storage-blob'

The next step is to edit the Ruby on Rails Active Storage configuration file.

config/storage.yml

azure:
  service: AzureStorage
  storage_account_name: "hixonrails"
  storage_access_key: "12id12dni1ksld1niodnio1dn1opdm1skdm1idmop1wm1pdm1pd1"
  container: "activestorage"

The more secure way to store your Microsoft Azure Storage credentials is to use dotenv-rails gem instead of keeping them in the Ruby on Rails Active Storage configuration file, which is checked into the git version control system.

.env

AZURE_STORAGE_ACCOUNT_NAME=hixonrails
AZURE_STORAGE_ACCESS_KEY=12id12dni1ksld1niodnio1dn1opdm1skdm1idmop1wm1pdm1pd1
AZURE_STORAGE_CONTAINER=activestorage

With this saved, edit the Ruby on Rails Active Storage configuration file.

config/storage.yml

azure:
  service: AzureStorage
  storage_account_name: <%= ENV['AZURE_STORAGE_ACCOUNT_NAME'] %>
  storage_access_key: <%= ENV['AZURE_STORAGE_ACCESS_KEY'] %>
  container: <%= ENV['AZURE_STORAGE_CONTAINER'] %>

This way your Ruby on Rails application is one step closer to respect Twelve-Factor App methodology.

Conclusion

Ruby on Rails Active Storage configuration is as easy as it gets - all you need to do is filling your access data to the Cloud Storage provider of your choice.

It gets even easier if you decide that your Ruby on Rails Active Storage module is going to store the files on your server's disk.

The difficult, yet in case of most of the organizations one-time part of the Ruby on Rails Active Storage configuration is the account creation and setup with the Cloud Storage provider of your choice - Amazon, Google or Microsoft.

In order to make the Ruby on Rails Active Storage configuration part even easier, consider using Hix on Rails, the Ruby on Rails Application Template that integrates the Active Storage setup in its setup wizard.

An automated Ruby environment management is necessary for developers to easily work on multiple Ruby programs on the same machine.

In the Ruby community, there are two popular managers responsible for installing and maintaining multiple Ruby versions - RVM and Rbenv.

Table of contents

Let us learn all about Ruby Environment Management ...

Ruby and RoR version checks in Hix

...and go latest

Yes, Hix does this - so you don't have to.

What is Ruby Environment Management?

If you are actively working on programs written in Ruby, at some point you are going to install multiple versions of the language on your system.

Ruby environment managers such as RVM and Rbenv allow you to do just that.

It is a generally accepted practice to include the .ruby-version file in the root of Ruby-written programs and applications, such as Ruby on Rails projects. The version file includes a specific Ruby version with which the program is supposed to work.

.ruby-version

2.6.5

Both RVM and Rbenv respect the aforementioned Ruby version, and upon navigating to the root of Ruby program that includes the file, they inform you that a particular Ruby version has to be installed in case it is missing on your system.

RVM vs Rbenv - which Ruby Version Manager should I use?

The short answer for developers is: it does not really matter, just pick one and be done with it - both RVM and Rbenv get the job done.

The long answer is: it depends.

RVM vs Rbenv on Github
RVM vs Rbenv on Github

One factor in favor of Rbenv over RVM is that it receives more love on Github. But let's get to the facts.

RVM pros over Rbenv:

Rbenv pros over RVM:

Rbenv main sell point is that its lightweight in comparison with RVM, while still providing just enough functionality for the Ruby development.

Now that we definitely have not decided which one to use leaving this decision to you, follow the installation instructions of the Ruby environment manager of your choice.

RVM installation

Depending on your operating system, follow the instructions below in order to install the RVM Ruby Environment Manager.

Ubuntu

RVM has a dedicated package for Ubuntu. In order to use it, you are going to be able to add stuff to PPA.

sudo apt-get install software-properties-common
sudo apt-add-repository -y ppa:rael-gc/rvm
sudo apt-get update
sudo apt-get install rvm

The next step is configuring the terminal to always perform login in order to always load the RVM.

At the terminal window:

  1. Navigate to Edit / Profile Preferences ,
  2. Go to the Title and Command tab,
  3. Check Run command as login shell

The last step is to reboot your machine.

Other operating systems

In order to install RVM, you are going to need the following packages: curl and gpg2. After confirming their presence, simply run

curl -sSL https://get.rvm.io | bash -s stable

Confirm your installation running the rvm install ruby command.

RVM overview

As stated before, RVM has more features built-in that Rbenv does.

In order to browse all the RVM commands, run either rvm --help or man rvm in your CLI.

Basic command-line RVM usage can be boiled down to this set of commonly used commands:

The last two commands are useful to remember whenever you start the development of a new Ruby-written program. In most cases, it's best to use the latest stable version, which is always installable via the rvm install ruby --latest command.

Rbenv installation

Based on your operating system, follow the instructions below in order to install the Rbenv Ruby Environment Manager.

macOS

Installing the Rbenv on macOS is really easy and can be done using Homebrew.

brew install rbenv
rbenv init

After running the commands, close and open your terminal for changes to take effect.

The Ruby installation plugin is included by default, so you can now install any Ruby version using the rbenv install X.Y.Z command.

Linux

In order to set up Rbenv on Debian based system, we are going to install all Ruby dependencies first.

sudo apt update
sudo apt install autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm5 libgdbm-dev

For OSs other than Debian, the same might be done using other system package managers.

Next, we are going to clone the official Rbenv repository into the home directory and add its binary to $PATH in order to use rbenv command line utility.

git clone https://github.com/rbenv/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc

The next step is to add the following command to your shell configuration file in order to load Rbenv automatically when the CLI starts.

~/.zshrc or ~/.bashrc

eval "$(rbenv init -)"

The last step is installing Ruby installation Rbenv plugin by simply cloning its official Github repository into the correct path.

git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build

That's it, Rbenv is ready to use. You can install the latest stable Ruby version using the rbenv install -l command.

Rbenv overview

In order to use Rbenv via CLI, you need to have the aforementioned ruby-build command-line utility installed.

In order to browse all the Rbenv commands available, run the rbenv --help method.

There are basic Rbenv commands that you are going to use at some point of Ruby development:

Whenever you start to develop the new Ruby program, it is worth using the latest stable Ruby version, which you can easily install using the rbenv install -l command.

Conclusion

Ruby Environment Management is a must-have for every Ruby developer.

Ruby community provides two very popular Ruby environment managers, Rbenv and RVM. Both of them are pretty easy to install and get the job done.

In this tutorial, we'll go step by step through Ruby on Rails Redis installation and configuration.

Redis is a key-value database, and it is very much worth using in multiple scenarios when working with Ruby on Rails.

Table of contents

Let's learn all about Redis in this Ruby on Rails guide...

Ruby on Rails with Redis, Sentinel and Sidekiq

...or have it done

Yes, Hix does this - so you don't have to.

What is Redis?

Redis is a BSD licensed, in-memory data structure store. It is one of the most popular NoSQL choices among open-source options available.

On top of that, Redis ranks as the most popular key-value database, and it was voted the most loved database in the Developer Survey by Stack Overflow three years in a row: 2017, 2018 and 2019.

Redis in DB-Engines ranking
Redis in DB-Engines ranking, December 2019

Redis supports various data structures:

and is used as a database, session cache, full page cache, and message broker, such as publish-subscribe messaging.

Why use Redis with Ruby on Rails?

There are multiple reasons to use Redis in Ruby on Rails application.

First of all, Redis offers the most popular in-memory data store. Data kept in the memory, as opposed to tools that write to disks, is going to be read and written faster.

RAM for Redis, HDD for SQL
Redis = RAM, SQL = HDD

Another reason to use Redis in Ruby on Rails is so obvious that it is even made official by the Ruby on Rails maintainers: using Redis as Ruby on Rails application cache-store.

Next, there are leaderboards: think anything that changes over time, like:

or internal application statistics, like:

A good example of the leaderboard is the Sidekiq Dashboard - which itself is a great reason to Ruby on Rails Redis usage, as it offers the most popular community choice for asynchronous code execution - and uses Redis.

Sidekiq Dashboard in Ruby on Rails
Sidekiq Dashboard in Ruby on Rails

Last but not least is a commonly needed these days Publish-Subscribe feature, and Redis is truly crafted for the job.

Action Cable in Ruby on Rails
Action Cable in Ruby on Rails

Redis is officially the default production pub/sub queue for the built-in Ruby on Rails ActionCable library, dedicated to channeling data through WebSockets.

As you can see, there are a lot of scenarios when it's going to be worth using Ruby on Rails and Redis combination.

Redis installation

Now that we know what is Redis and what it is used for in Ruby on Rails, let's go through step by step guide to installing it for further usage with our Ruby on Rails application.

macOS

The most straightforward way to install Redis on the macOS is using Homebrew.

Homebrew macOS package manager
Homebrew, macOS package manager

Follow these steps:

  1. Install Homebrew, there's a single command to do so on the official website.
  2. Install Redis via Homebrew: brew install redis.

For the development convenience, we are going to do one more thing, that's gonna save us a lot of trouble in the future.

Let's install and enable Brew Services, in order to run Redis in the background. This way, anytime you reboot your machine, it is going to launch Redis for you automatically.

Run the following commands in your CLI.

brew tap homebrew/services
brew services start redis

The first command installs the brew services and the second one launches Redis as a brew service. You can browse all services running at any point using the brew services list command.

Verify that Redis is running with redis-cli ping command - it should return PONG.

At this point, it is worth installing a Redis client for macOS - this way you will be able to easily browse all the data written to any Redis instance:

As scary as it sounds, paying for the Redis client is worth it in the long run, as it vastly improves Ruby on Rails development and debugging process.

Linux

Depending on your Linux distribution you are going to use a different package manager to install Redis.

If you use CentOS or RedHat, install Redis using yum package manager.

sudo yum install redis

Otherwise, if you use Debian based distro such as Ubuntu, use apt package manager.

sudo apt install redis

In both cases, in order to automatically start Redis on boot, run

sudo systemctl enable redis

This way you won't have to remember to launch Redis every time, it is very convenient for continuous development.

Verify that Redis is running with redis-cli ping command - it should return PONG.

At this point, it is also worth installing the Redis GUI client. It greatly improves the development and debugging experience, allowing you to easily browse all data written to Redis while working with your Ruby on Rails application.

Redis Desktop Manager for Linux
Redis Desktop Manager

We recommend using a Redis Desktop Manager, which is free for Linux distributions.

Ruby on Rails Redis installation

If you use Hix on Rails, then you can skip the rest of this tutorial - just run the installation wizard and all of the below is going to be preconfigured for you. Optionally you might jump to the Redis Sentinel production configuration part for better understanding and customization.

Otherwise, if you still did not automate this part of your life yet, read on.

With Redis up and running on our system, let us install the required Redis-related gems in order to use it with our Ruby on Rails application.

Redis recommended Ruby client
Ruby client officially recommended by Redis

We are going to use a Ruby client recommended on the official Redis website.

On top of that, there are another two gems worth installing:

In the Gemfile of your Ruby on Rails project, add the following, outside any of the specific groups. They need to be available to all of the Ruby on Rails environments.

Gemfile

gem 'redis'
gem 'redis-namespace'
gem 'redis-rails'

Now, run the bundle install command in order to generate the Gemfile.lock file.

In order to easily connect to Redis from our Ruby on Rails application, we are going to additionally use the environment variables management gem, dotenv-rails - install it and in your .env file add these three environment variables for development.

.env

REDIS_DB=0
REDIS_URL=redis://127.0.0.1
REDIS_PORT=6379

those are the default host and port of every Redis installation.

Next, we are going to tell our Ruby on Rails application to connect to Redis upon booting by creating the dedicated initializer.

config/initializers/redis.rb

# frozen_string_literal: true

Redis.current = Redis.new(url:  ENV['REDIS_URL'],
                          port: ENV['REDIS_PORT'],
                          db:   ENV['REDIS_DB'])

If you are going to use the aforementioned Action Cable, there's one little thing worth doing at this point.

As you can see, in our environment we have separated the Redis URL and DB variables. Concatenated, they result in the Redis host, and it is how Ruby on Rails Action Cable uses them. Open its configuration and change it to the following.

config/cable.yml

development:
  adapter: async

test:
  adapter: test

production:
  adapter: redis
  url: <%= ENV.fetch("REDIS_URL") %>/<%= ENV.fetch("REDIS_DB") %>
  channel_prefix: app_production

I personally like to keep the development environment as close to the production one as possible in order to catch any bugs at the earliest stage.

To do that, you might consider changing the development Action Cable configuration to the same as production one - this way while writing your Ruby on Rails application's code and running it locally, you will use Redis as well.

Ruby on Rails Redis production configuration with Sentinel

If you care about high Redis availability in the production environment of your Ruby on Rails application, you might consider using the Redis Sentinel.

Redis Sentinel cluster
Redis Sentinel cluster

Using Sentinel is the officially recommended way to automatically manage Redis failovers, it is also capable of monitoring and notifying on the Redis deployment.

Official Redis Sentinel documentation intro
Sentinel on the official Redis website

The Redis client that we have previously installed in the Ruby on Rails application in order to connect to the Redis client is able to perform automatic failover using Redis Sentinel.

In order to do that, we are going to change the Ruby on Rails Redis configuration file. Open the previously created initializer and edit it with the following:

config/initializers/redis.rb

# frozen_string_literal: true

if Rails.env.production?
  SENTINELS = ENV['SENTINEL_HOSTS'].split(' ').map! do |host|
    { host: host, port: ENV['SENTINEL_PORT'] }
  end

  Redis.current = Redis.new(url: ENV['SENTINEL_URL'],
                            sentinels: SENTINELS,
                            role: :master)
else
  Redis.current = Redis.new(url: ENV['REDIS_URL'],
                            port: ENV['REDIS_PORT'],
                            db: ENV['REDIS_DB'])
end

This configuration file assumes the existence of three additional environment variables. In the environment configuration of your Ruby on Rails application, add the following.

.env

SENTINEL_URL=redis://sentinel-master/1
SENTINEL_HOSTS=sentinel-slave-1 sentinel-slave-2 sentinel-slave-3
SENTINEL_PORT=26379

Another assumption that might require additional tweaks is that all the slave Redis instances run on the default Sentinel port which is 26379. If that is not a case, adjust the initializer file accordingly.

If you are using Sidekiq and want it to respect your Sentinel production configuration, you'll need to adjust its configuration pretty much the same way - by conditionally connecting your Ruby on Rails to the Redis Sentinel in the production environment.

In order to additionally improve Ruby on Rails Redis performance, you might want to take a look on hiredis and its dedicated Ruby wrapper hiredis-rb.

Conclusion

Ruby on Rails Redis installation and configuration is a pretty straightforward thanks to the awesome official and community support.

All it takes is installing a few well maintained Ruby gems, and your Ruby on Rails application is ready to read and write to Redis key-value store.

All of this config comes ready with Ruby on Rails application initialized with Hix on Rails Application Template.

This is the ultimate, step by step Ruby on Rails guide to RSpec testing framework configuration in Ruby on Rails project.

Table of contents

Let's learn all about configuring RSpec...

Automate gems installation in Ruby on Rails

...or have it done

Yes, Hix does this - so you don't have to.

What is RSpec?

RSpec is the most popular Ruby on Rails testing framework according to Ruby on Rails community. It is also perfectly capable to test any Ruby-written code. RSpec organization repository is neatly organized into smaller parts, such as:

and then some more. It all builds up into a comprehensive, fully-featured Ruby and Ruby on Rails testing framework.

RSpec organization on Github
RSpec organization on Github

One can easily see that the RSpec for Ruby on Rails is the most frequently developed of all the gems.

As stated on the official RSpec informative website, RSpec provides a Behavior-Driven Development, BDD for Ruby, and it makes Test-Driven Development, TDD, fun and productive.

An official RSpec info website
RSpec official info website

Thorough documentation of the RSpec framework and all of its gems with executable examples is available thanks to Relish on their official website dedicated to RSpec.

RSpec documentation on Relish
RSpec documentation on Relish

Altogether it seems an awful lot, but it's definitely worth using RSpec in Ruby on Rails applications, as it is the most advanced Rails testing framework of all.

Why use Ruby on Rails with RSpec over alternatives?

Now that we review what is the RSpec testing framework, let's take a look at why it should be your choice when it comes to Ruby on Rails testing.

As stated at the beginning, RSpec is the most popular choice for Ruby on Rails projects testing. However, it does not come with the default Ruby on Rails application setup, it needs to be installed manually.

The default framework for Ruby on Rails applications testing is a MiniTest. It is a built-in mechanism with the official Ruby on Rails documentation on how to write unit, functional, integration and system tests, and all of its terminologies explained.

Official Ruby on Rails testing guide
Official Ruby on Rails testing guide

Another noteworthy testing framework widely used with Ruby and Ruby on Rails - as with Java, Electron and many others - is a Cucumber framework.

Cucumber for Ruby on Rails
Cucumber for Ruby on Rails

So what does make RSpec the best choice for testing Ruby on Rails applications?

First of all, RSpec has the best documentation, which provides a ton of helpful examples and real-life scenarios that are commonly needed to be covered by developers. This is crucial for using anything that provides its own Domain-Specific Language - DSL- as the RSpec does.

On top of that, RSpec out of the box has all the features that developers need, and all of them are highly maintained.

MiniTest on the other hand, along with its claim that everything done by RSpec might be accomplished using dedicated plugins, does not maintain them successfully, and a lot of them are broken and have not been updated in a long time.

At last, RSpec is an application, while MiniTest and Cucumber are simply frameworks. I cannot stress enough how important it is for daily usage. It does not require anything else to run the test suite, providing an end to end solution for Ruby testing.

RSpec provides a mature, well maintained and documented command-line interface program. It works exactly as one would expect it to, with the CLI help available via the --help option.

Summing it all up, RSpec is the most popular community choice for testing Ruby on Rails applications. Thanks to that, as it's open-sourced, it is highly maintained, a lot of solutions to the common problems are easily googleable and it grows in power rapidly.

What is code coverage?

Code coverage, also known as test coverage, is a measure responsible for calculating the percentage of code used while running the program's test suite.

On its own, a 100% code coverage does not guarantee that the code does not contain any bugs, as a simple code execution does not guarantee its accuracy.

However, it gives a nice overview of the program's test suite as a whole, telling the developers which parts are safe to edit, and which are yet to be tested.

Rspec code coverage with SimpleCov

Using RSpec in Ruby on Rails, the most popular choice for calculating the project's code coverage reports is SimpleCov.

SimpleCov code coverage report
SimpleCov code coverage report

By default, it provides a simple total percentage of the project's test suite code coverage.

On top of that, SimpleCov allows grouping the reports by meaningful categories such as Ruby on Rails Controllers, Models, Views and Mailers, Sidekiq Workers and anything else that comes to mind for the given Ruby on Rails application, such as Service, Query, and Form Objects.

Using the SimpleCov gem, one can set it up to fail - which means returning a non-zero value CLI-wise - for a minimum (and maximum) test code coverage limits, enforcing developers to meet the established limitations.

It is a super helpful way to make people write tests when implemented in the Continuous Integration suite.

RSpec code coverage overview with Coveralls

If you are serious about the code coverage, we recommend using Coveralls.

Coveralls code coverage reporting solution
Coveralls, a code coverage reporting solution

It is a SaaS that provides a comprehensive dashboard showing the test coverage history and statistics for the selected projects and can be easily integrated with any of the most used git repository hosting providers such as Github, Gitlab and Bitbucket.

You might have met it already, as it provides a very popular coverage badge, commonly included in the README files of Open Source projects, as Coveralls is free to use with any open-sourced code, forever.

Code coverage README shield
Code Coverage badge by Coveralls

Coveralls is an overall great tool to ensure a better Ruby on Rails application maintenance, providing both the simple and sophisticated overviews of the projects testing suite code coverage.

Configure RSpec in a Ruby on Rails project

If you use Hix on Rails, you don't need to do any of the following - simply go through the setup wizard and be done with it, anytime you start a new project.

Otherwise, if you sadly did not automate this part of your life yet, read on.

Let us now configure the RSpec testing framework in the Ruby on Rails project, following a simple step by step guide.

Raw RSpec config in Ruby on Rails

In order to use RSpec with your Ruby on Rails application, you need to install the dedicated rspec-rails gem. Open your project's Gemfile and add it to the test and development groups.

Gemfile

group :development, :test do
  gem 'rspec-rails'
end

Next, run the bundle install command in your CLI after navigating to your project's root path, in order to include the gem in your Ruby on Rails project's Gemfile.lock file.

bundle install

RSpec is equipped with the rspec command, that comes with an initialization option. However, in Ruby on Rails, there's a dedicated generator to do just that. In your CLI, run the following command.

rails generate rspec:install

It generates three files: .rspec, spec/spec_helper.rb and spec/rails_helper.rb. The first file is loaded every time the rspec command runs via CLI, passing the RSpec options to it. By default, it only tells RSpec to include the other helper files that are responsible for defining the gem's configuration.

A full list of options available resides under the rspec --help command.

Output of the RSpec help method
A full list of RSpec options

By default, there are three options defined in the second generated file, all of which are going to be the defaults in the next major version of the RSpec framework, the RSpec 4. It is recommended by the framework authors to leave them this way. Options are:

On top of that, there are some commented-out configuration options:

The last generated file, spec/rails_helper.rb, is responsible for defining the Ruby on Rails specific configuration. Those two are separated for performance reasons.

The third file does a multitude of helpful things:

From now on, whenever adding anything related to Ruby on Rails to the RSpec configuration, we are going to do so in the spec/rails_helper.rb file.

Let us do just that by adding a few helpful gems that make testing easier and more predictable.

DatabaseCleaner gem set up with RSpec in Ruby on Rails

In order to keep our Ruby on Rails project's test database clean between test runs, we are going to install an additional gem dedicated to doing just that, the DatabaseCleaner.

First of all, select and install one of the gems dedicated to specific Ruby on Rails ORMs supported by DatabaseCleaner. The most popular choice is going to be the Active Record gem. In your Gemfile file, add the gem of your choice to the test group.

Gemfile

group :test do
  gem 'database_cleaner-active_record'
end

and run the bundle install command from the root path of your Ruby on Rails project.

Next, let us tell RSpec to clean the Ruby on Rails project tests database in between the test suite runs. Open the spec/rails_helper.rb and add the following.

spec/rails_helper.rb

RSpec.configure do |config|
  # some
  # other
  # configuration
  config.before(:suite) do
    DatabaseCleaner.strategy = :truncation
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.start
  end

  config.append_after do
    DatabaseCleaner.clean
  end
end

This set of configuration hooks tells RSpec to do the following:

Cleaning the Ruby on Rails tests database on all of these stages prevents the test's failures caused by any rubbish data leftovers generated between the RSpec tests run.

ShouldaMatchers gem set up with RSpec in Ruby on Rails

One of the most popular gems that support testing Ruby on Rails applications with RSpec is ShouldaMatchers. It provides a great toolkit for testing the methods commonly used in the classes provided in Ruby on Rails framework, such as ActiveModel, ActiveRecord and ActionController.

In order to use ShouldaMatchers in your Ruby on Rails project with RSpec, we need to install the shoulda-matchers gem first. Open the Gemfile file and add it to the tests group.

Gemfile

group :test do
  gem 'shoulda-matchers'
end

Run the bundle install command in your Ruby on Rails project's root directory, and edit the spec/rails_helper.rb with the following.

spec/rails_helper.rb

Shoulda::Matchers.configure do |config|
  config.integrate do |with|
    with.test_framework :rspec
    with.library :rails
  end
end

That's it - your Ruby on Rails project is ready to use all the matchers provided by the ShouldaMatchers in the RSpec tests.

FactoryBot gem set up with RSpec in Ruby on Rails

FactoryBot is the replacement of the most popular fixtures for Ruby on Rails projects. It provides a straightforward definition syntax and supports both multiple build strategies and factories for the same class, including inheritance.

In order to use FactoryBot in the Ruby on Rails project with RSpec, install the dedicated FactoryBotRails gem. Open the Gemfile file and add the following to the development and test groups.

Gemfile

group :development, :test do
  gem 'factory_bot_rails'
end

Adding the gem to the development group results in modifying the default Ruby on Rails generators to produce related factories - from now on, whenever you generate the new model via command line, the corresponding factory will be generated as well.

In order to include the FactoryBot in the RSpec configuration, add the following to the spec/rails_helper.rb.

spec/rails_helper.rb

RSpec.configure do |config|
  # some other configuration
  config.include FactoryBot::Syntax::Methods
end

You can take the full advantage of the FactoryBot gem whenever writing RSpec tests in your Ruby on Rails project.

TimeCop gem set up with RSpec in Ruby on Rails

As stated in the RSpec Ruby Styleguide, the best way to deal with time when testing Ruby on Rails applications with RSpec is to use the TimeCop gem.

TimeCop provides time freezing, travel, and acceleration capabilities, giving developers oneliners to deal with the time, instead of stubbing anything on Date, Time and DateTime classes.

In order to use the TimeCop gem in your Ruby on Rails project, simply add it to the test group of your Gemfile file.

Gemfile

group :test do
  gem 'timecop'
end

It does not require any configuration specific to RSpec in the Ruby on Rails project.

In order to take the quality of your RSpec Ruby tests to the next level, visit the Ruby on Rails RuboCop configuration guide - it provides the way to validate your RSpec tests suite in the Ruby on Rails project against aforementioned RSpec Style Guide automatically.

SimpleCov configuration in Ruby on Rails with RSpec

In order to generate the coverage reports in the Ruby on Rails application tested with RSpec, we are going to install the aforementioned SimpleCov gem. In your project's Gemfile, add the required gem to the test group.

Gemfile

group :test do
  gem 'simplecov'
end

and next, navigate to your projects root path and run the bundle install command.

By default, SimpleCov is going to generate all of its reports into the coverage directory of our project. Let's add it to the project's .gitignore file in order to avoid a massive amount of changes accompanying every test run.

.gitignore

coverage/

Next, we are going to follow the gem instructions in order to turn on the SimpleCov code coverage gem every time the test suite runs. Open the spec/spec_helper.rb file and add the following at the beginning of it.

spec/spec_helper.rb

require 'simplecov'

SimpleCov.start 'rails'

In the simplest manner possible, you're done - every test run is going to result in the code coverage report generation.

Coveralls account setup and configuration in Ruby on Rails

Now that we are generating the code coverage reports, let us track their history along the Ruby on Rails application development via Coveralls.

Follow the step by step guide in order to set up your Coveralls account and adding your Ruby on Rails project to it.

Be aware that you are going to subscribe to the Coveralls PRO in order to set up private repositories here.

  1. Sign up on the official Coveralls website.
    Coveralls sign in form
    Sign up form on the Coveralls official website
  2. After logging in, authorize Coveralls to access your repository hosting provider account.
    Verify Coveralls access to Gitlab account
    Verify Coveralls access to the Gitlab account
  3. Hover the left-hand side sidebar and click the "Add Repos" link.
    Add repo to Coveralls
    Add repo to track the code coverage in Coveralls
  4. Search for your Ruby on Rails project repository in Coveralls and turn it on.
    Enable Coveralls for selected repository
    Find and enable Coveralls for your Ruby on Rails repo
  5. Click the "Details" button and copy your Coveralls repository key.
    Copy Coveralls repository key
    Copy Coveralls repository key

After obtaining the Coveralls repository key and enabling it in the tool's interface, we are going to set it up in our Ruby on Rails project.

First, let's install the provided gem. Open the Gemfile file and add the coveralls to the test group.

Gemfile

group :test do
  gem 'coveralls'
end

Run the bundle install command and open the spec/spec_helper.rb file, in order to tell RSpec to use the provided formatter.

spec/spec_helper.rb

# frozen_string_literal: true

require 'coveralls'
require 'simplecov'

SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([SimpleCov::Formatter::HTMLFormatter,
                                                                Coveralls::SimpleCov::Formatter])
SimpleCov.start 'rails'

The last step is to create a dedicated Coveralls configuration file with our previously generated repository key.

.coveralls.yml

service_name: service-name
repo_token: YOUR_COVERALLS_REPOSITORY_KEY

Depending on the Continuous Integration service that you use, update the service name accordingly.

My advice is to take another five minutes to figure out how to skip using the .coveralls.yml file completely, as keeping secrets checked into your remote repository might not be the best idea

It is better to define them as environment variables, and most of the Continuous Integration providers enable that option. Coveralls documentation gives you guidelines on how to do just that for their supported services.

The main goal here is to generate your code coverage reports via your RSpec tests run on the Continuous Integration whenever you merge the new feature to develop and master branches. This way your Coveralls history and statistics will not clutter with endless reports of identical feature branches code coverage data.

Conclusion

As stated multiple times in this guide, RSpec is the most popular choice for testing the Ruby on Rails applications, and for a number of good reasons.

If you care about Ruby on Rails tests, setting up the code coverage reporting is recommended - it gives developers a nice overview of the project's maintenance quality.

The SimpleCov gem is a simple to use solution to do just that in your Ruby on Rails projects that use RSpec - all it takes are two extra lines of code and the dedicated gem installed.

For those who want more control, enforcing the minimal code coverage in the Ruby on Rails application takes only the single line of code in the RSpec configuration file.

If you're looking for a professional overview of the code coverage statistics and history for your Ruby on Rails projects, use Coveralls - it aggregates your code coverage data and exposes it via sophisticated web UI.

As you can see, there's a lot of configuration related to the RSpec testing framework set up in the Ruby on Rails project -fortunately, you can skip most of it by using the Hix on Rails, the Ruby on Rails project generator.

This is the ultimate guide to Ruby on Rails project RuboCop setup in 2020.

Table of contents

Let's learn all about configuring RuboCop in Ruby on Rails project...

Automate Ruby on Rails gems installation

...or have it done

Yes, Hix does this - so you don't have to.

What is RuboCop and Ruby Style Guide?

RuboCop is the most popular Ruby static code analyzer and code formatter, code linter in short. Linting is the process of running a program that analyzes the code for programmatic and stylistic errors.

Out of the box, it enforces most of the guidelines outlined in the Ruby Style Guide maintained by the Ruby community. The guide groups its guidelines by related sections, which corresponds to RuboCop gems departments.

There are nine departments in the base RuboCop gem. Numbers might change in time and are given here only for the rough overview of what the gem offers.

In total, there is a little less than 400 rules applicable to anything written in Ruby, if we choose so.

But, it does not end here - let us take a quick look at accelerating the Ruby code by following extended RuboCop guidelines.

RuboCop Performance

There's an extension wisely encapsulated in its own Ruby gem called RuboCop Performance. Its job is pointing out Ruby code optimization opportunities.

All 25 rules of the RuboCop Performance gem are grouped in the single RuboCop department, called Performance.

It is a relatively young project and some of the cops included were originally placed in the main RuboCop gem.

If your Ruby program is really performance-dependent, you might want to additionally look at the fasterer gem, based on the open-sourced Github repository called Fast Ruby - the biggest collection of Ruby benchmarks.

Let us now take a look into other, framework-specific RuboCop extensions.

RuboCop Rails and Rails Style Guide

When RuboCop is a code linter of your choice, RuboCop Rails extension is the must-have for your Ruby on Rails projects.

RuboCop Rails is a RuboCop extension focused on enforcing Ruby on Rails coding conventions and best practices, neatly described in the Ruby on Rails Style Guide.

The style guide itself is split into 16 sections, covering things such as Ruby on Rails configuration, dealing with time, Models, Controllers, Mailers and more.

Whenever in doubt on how to approach Ruby on Rails related problem, try browsing the relevant style guide section, or go one step further and let your projects Continuous Integration point it out for you, by configuring RuboCop gem with all its extension on either GitlabCI or CircleCI.

RuboCop RSpec and RSpec Style Guide

If RSpec is your weapon of choice unit-testing-wise, setting up the RuboCop RSpec extension will help you a lot.

RuboCop RSpec is a RuboCop extension that provides RSpec, RSpec for Rails, FactoryBot and Capybara analysis for Ruby projects, which in total gives us another 76 rules to follow, for the sake of neat codebase.

All of the RuboCop RSpec cops - and then some - are extensively described in the RSpec Ruby Style Guide, providing examples of the code that follows the guideline paired with the one that does not.

It is my personal favorite style guide of all provided by the RubCop HeadQuarters, and I rely on it a lot during Code Reviews - my Github account saved replies are linking to it heavily.

Next to the gem itself, the guide gives an extremely useful overview of how to write unit tests of Ruby on Rails related parts, such as the MVC Models, Views, Controllers and also Mailers.

Unfortunately, some of the Rails related rules are not possible to enforce via the gem itself, hence the Github saved replies linking to the relevant guide sections.

It is still a great tool whenever you use RSpec in your Ruby and Ruby on Rails projects.

RuboCop MiniTest and MiniTest Style Guide

If you use MiniTest, the second most popular choice for testing the Ruby written programs, there's a RuboCop extension dedicated to it, called RuboCop MiniTest.

It enforces best practices outlined in the MiniTest Style Guide, yet another great read provided by RuboCop HeadQuarters.

It's a relatively young project comparing to the more popular RSpec choice. It describes a total of 15 rules for writing unit tests using the MiniTest framework.

RuboCop set up in a single Ruby on Rails project

Now that we went through most of the RuboCop extensions - there are two more, for Rake and Markdown - let us take a look at how to hook it all up in the Ruby on Rails application.

RuboCop and its extension configuration files are written in YAML. They are all placed in the same config directory, in each of the repositories respectively, assisted with a great RubyDoc documentations, which altogether makes it very easy to find and understand every rule.

When working on the Ruby on Rails project that uses either RSpec or MiniTest, we are going to install 4 RuboCop gems:

Go ahead and edit your Gemfile, adding the following to the development and test group.

group :development, :test do
  gem 'rubocop'
  gem 'rubocop-performance'
  gem 'rubocop-rails'
  gem 'rubocop-rspec' # or gem 'rubocop-minitest'
end

Next in your CLI, navigate to the directory path of your Ruby on Rails project and run the bundle install command in order to update your Gemfile.lock.

Now that all the gems are installed, let us prepare our custom RuboCop configuration file, called .rubocop.yml.

It is responsible for two things:

  1. Importing installed extensions
  2. Defining which cops we do and do not want to enforce

By default, it uses the predefined RuboCop configuration with no other extensions installed, as it is designed to work with any Ruby language codebase.

In order to include the installed extensions, create the following RuboCop configuration file.

require: 
  - rubocop-performance
  - rubocop-rails
  - rubocop-rspec # or rubocop-minitest

Next, we are going to follow the example configuration for Ruby on Rails project presented in the RuboCop documentation - but in order to use the aforementioned extensions, we are going to skip some of it.

Add the following to your configuration file.

AllCops:
  Exclude:
    - 'db/**/*'
    - 'script/**/*'
    - 'bin/**/*'

It tells RuboCop to exclude given directories while analyzing the codebase - the readability does not matter there too much and is not worth bothering for the pleasing Ruby on Rails development.

Next, let us cut some additional slack while working with RuboCop. Those are the sane RuboCop rules to use with Ruby on Rails project.

Below the previous configuration, add the following.

Metrics/LineLength:
  Max: 100

Metrics/BlockLength:
  Exclude:
    - config/**/*
    - spec/**/*

Lint/AmbiguousBlockAssociation:
  Exclude:
    - spec/**/*

Style/Documentation:
  Enabled: false

Most of those are pretty self-descriptive, but let's go through them quickly:

It is important to remember that nothing here is written in stone - if you ever feel like you waste more time than its worth fixing some "stupid RuboCop rules", you can always disable them in this file.

At this point, assuming that you've recently created your brand new Ruby on Rails project the RuboCop analysis will give you some headache, as Ruby on Rails does not follow its default guidelines.

But worry not - most of it can be easily fixed using the RuboCop command with the --safe-auto-correct flag.

Let's not be naive, everything can crash, no matter if its name contains "safe" - create a backup of your recent changes to git first.

Then, navigate to your project directory and run the following.

bundle exec rubocop --safe-auto-correct

It will fix all RuboCop violations that are marked as auto-fixable in the default configuration file. Browse the changes and if it seems ok, add it to git.

There's also a big chance that you work on some much older Ruby on Rails codebase, and the quick-fix presented above might not be that effective, nor the best idea - some stuff might actually break.

Thankfully to the awesome RuboCop maintainers, there's a solution for legacy code implementations, the --auto-gen-config command-line flag.

In the root directory of your legacy Ruby on Rails project after installing all the gems and creating the configuration file, run the following.

bundle exec rubocop --auto-gen-config

It does two things:

  1. Analyzes the codebase for RuboCop violations, writing the exclusions into the .rubocop_todo.yml file,
  2. Updates the .rubocop.yml file with an import of the exclusions.

Now, if you run the bare bundle exec rubocop command again, it will show 0 offenses.

This is a great way for improving legacy Ruby on Rails applications code: just tell your team, that whenever anybody works on it, they should:

  1. Look it up and comment-out a path to it in the TODO file,
  2. Fix what's possible,
  3. Delete the commented-out paths exclusions for good.

That way the Ruby on Rails codebase quality is going to improve vastly over time, eventually allowing developers to remove the TODO list completely.

Sharing RuboCop configuration in multiple Ruby on Rails projects

It is easy to set the RuboCop up for a single Ruby on Rails project, although, following the current microservices trend, that's hardly enough. There's a big chance that wherever you work at, your team either:

RuboCop evolves, all its extensions do too, and developers' preferences change. Maintenance of all those moving parts along with keeping sane is not a trivial task. Imagine that company you work for has 15 microservices, all written in Ruby on Rails, and consider one of the following:

  1. Your team decides that they don't like Department/Cop anymore
  2. RuboCop releases a newer version
  3. RuboCop Rails releases a newer version
  4. RuboCop RSpec releases a newer version
  5. RuboCop Performance releases a newer version

It's quite a copypaste task to keep it all up to date.

Percy, the QA SaaS, and Google APIs propose (and use themselves) a solution to that - creating your own gem with all the required extensions installed, a single source of the RuboCop configuration.

With your own gem, the "only" thing you need to do is updating it (and either backward-fixing or ignoring the "new" violations after the update) in every single project. There's automatically less room for error, as the single configuration per project would require you to update the core, every single extension and on top of that, the configuration file.

There's another option available, although I'm not a big fan of it, as in my opinion it is not controlled enough and might actually do some damage - with RuboCop, you might include the configuration from an URL address, so theoretically you would not need to manually update it in every single project.

What I don't like about it: if you lint the code in your Continuous Integration suite, it might suddenly cause your jobs to stop passing if new rules won't be backward compatible with the old code - and as a result, stop the development just to fix them.

Summing up, if your team maintains and/or creates a lot of Ruby on Rails applications, consider encapsulating your RuboCop configuration in the separated, shared gem.

Advanced RuboCop configuration

For all the standards nazis like myself, I'm going to mention yet another detail that I've recently discovered about RuboCop: it does not enable all its options by default.

See it for yourself.

  1. Browse the config/default.yml file in the core RuboCop gem repository,
  2. Search CTRL + F for the "Enabled: false" phrase.

At the time of writing this guide, there are 35 occurrences of the searched phrase, two of which are some explanatory comments.

It seems that there are 33 additional rules that one can potentially follow, improving the Ruby on Rails codebase even further!

Those are:

Let's check out one that I personally like the most, the ClassStructure cop residing in the Layout department.

As its description states, Layout/ClassStructure enforces a configured order of definitions within a class body. There are multiple things that can be included in the Ruby class, and thanks to this cop we can make sure that all the classes written in the codebase define them in the custom or default order:

Next to those, there are multiple other Layout, Lint and Style cops, that put together remind me of some very wise words that I've read a long time ago.

Any codebase should look like it is written by a single person.

"Clean Code" by Robert Cecil Martin

That is the effect you might accomplish via the disabled by default RuboCop configuration.

Conclusion

RuboCop is a very powerful and the most popular code linting tool for the Ruby language.

Its configuration is not rocket science, so the amount of community knowledge on writing a clean, easily maintainable code comes with a very low price - all it takes is installing a few gems and writing a simple YAML file.

The only justification of not using it is knowing all those rules by heart - and I seriously doubt that there's a lot of people who do.

Using RuboCop when developing Ruby on Rails applications helps developers to avoid common mistakes, guards from the code formatting discrepancies and allows them to create a codebase that is well maintained and easy to understand.

Use RuboCop in your Ruby on Rails projects, period.

This is the ultimate guide for your next Ruby on Rails project setup on Gitlab with GitlabCI for continuous integration in 2020.

Table of contents

Let's learn how to set up GitlabCI configuration for Ruby on Rails...

Ruby on Rails on Gitlab with GitlabCI

...or have it done

Yes, Hix does this - so you don't have to.

What is Gitlab?

Gitlab is, among all the other DevOps related features, one of the top git remote hosting cloud providers, next to Microsoft's Github and Atlassian's Bitbucket.

It can be both self-hosted or used via provided web UI on an official website. Like the other two giants, it offers an unlimited amount of public and private repositories, with limited users access extendable with a paid plan.

Fun fact is that both Ruby and Ruby on Rails are a big part of the Gitlab's tech stack.

Gitlab Ruby stack on Stackshare

Gitlab allows its users to integrate various pipelines into the code lifecycle, providing powerful GitlabCI, which should be rather called GitlabCD, for Continuous Delivery, as it equips developers with everything that's necessary to deliver code from their workstations straight to the production servers.

Why use Gitlab for Ruby on Rails app?

Creating constant backups of your code without using git or any other version control system would be true horror. Gitlab's biggest advantage for Ruby on Rails and projects written with any other frameworks is that on top of checkpoints in your codebase saved locally, you can host them in the cloud.

An ability to roll back to the older version of the code in case of introducing bugs in newer releases is yet another life-saving feature of Gitlab and other git remote hosting providers.

Another advantage is that with its massive usage as a self-hosted remote git repository solution there's a big chance that anybody that is going to collaborate with your code is going to know how to use Gitlab, so statistically, a learning curve is gone.

Thanks to its intuitive UI, Merge Requests, Code Review and Forks, Gitlab allows developers to easily work together.

On top of all that, it introduces its own, very advanced git branching strategy called GitLab flow.

Continuous Integration for Ruby on Rails

Continuous Integration (CI) in a programming world is a widely accepted practice that requires developers to push their work to the shared codebase continuously, ideally several times a day.

On top of general usages such as building programs and running the test suite against new features, new code might be verified against static code analysis tools knowledge base, pinpointing security vulnerabilities, common stylistic mistakes and all different kinds of inaccuracies.

Continuous Integration pipelines are a great place to ensure high code quality, well, continuously, which is good for both programmers and software itself.

There are multiple open-source static code analysis tools available for both Ruby and Ruby on Rails.

Most of them can be set up on the CI server to audit the code of Ruby on Rails project every time its pushed, or nightly.

Why use GitlabCI for Ruby on Rails app?

GitlabCI is Gitlab's own solution for Continuous Integration and Delivery, hosted in its cloud.

It is tightly integrated with Gitlab repository hosting, turned on by default, so every time you create a new repository on Gitlab all you need to do in order to turn on its Continuous Integration solution for your project is providing a correct configuration file, .gitlab-ci.yml.

There are several shared runners available, so there's no need for your custom CI server maintenance (hello Jenkins), just one YAML file and you're all set.

No credit card information required, a perfect combination to start small with your project and pay for what you use as you grow.

GitlabCI provides an intuitive, well-organized UI with all the information required to establish the problem that occurs when the new code was integrated into the Gitlab hosted codebase.

It is crucial to set up the Continuous Integration system for any project, let alone Ruby on Rails, from the first day of the development.

This is a great way to avoid a lot of technical debt, protect yourself from common mistakes and enforce certain standards that make working with Ruby on Rails codebase pleasing and its maintenance much, much easier.

Create Ruby on Rails project on Gitlab

Follow the instructions below to create your Gitlab account and set up the Ruby on Rails project.

  1. Sign up on the official Gitlab website.
    Gitlab sign up form
    Sign up form on the Gitlab official website
  2. Verify your email and complete the simple account creation wizard.
  3. When successfully logged in, select "Create project".
    Gitlab create project
    Create a project on Gitlab
  4. Provide a project name and click "Create project".
    Gitlab new project form
    Creating a new project on Gitlab
  5. Copy your new project's URL to the clipboard.
    Gitlab new project's URL
    New project's Gitlab remote URL
  6. If you are using Hix on Rails, that's all you are going to need for now, just paste the address into the CLI when asked for it.
  7. Navigate to the Ruby on Rails project root directory in the command line and enter git remote add origin YOUR_REPOSITORY_URL

Ruby on Rails project with GitlabCI pipelines

If you are using Hix on Rails - that's it. Your pipeline will run with all the code quality checks selected in the installation wizard upon the first push the remote. Beware that it will initially fail unless you create any database migration, as it is necessary for the database to be created.

Otherwise, if you still on the copypaste duty instead of automating that part of your life, follow the steps below for Ruby on Rails project configuration on the GitlabCI.

In your project root, create the required GitlabCI configuration file.

cd path/to/your/project/root
touch .gitlab-ci.yml

Open the GitlabCI configuration file with a text editor of your choice and paste the basic code required, depending on which database you use.

Ruby on Rails with PostgreSQL on GitlabCI

PostgreSQL is the most popular choice for Ruby on Rails projects.

For the GitlabCI to test your application along with PostgreSQL you are going to need a specific setup in the config/database.yml file. We use the dotenv-rails gem.

config/database.yml

default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV['DB_POOL'] %>
  username: <%= ENV['DB_USERNAME'] %>
  password: <%= ENV['DB_PASSWORD'] %>
  host: <%= ENV['DB_HOST'] %>
  port: 5432

development:
  <<: *default
  database: hix_postgresql_development

test:
  <<: *default
  database: hix_postgresql_test

production:
  <<: *default
  database: hix_postgresql_development

If you decided to go with it, here's the basic GitlabCI configuration for the Ruby on Rails project build with the PostgreSQL database.

.gitlab-ci.yml

stages:
  - build
  - test

.build:
  image: ruby:2.6.5
  cache:
    key: rat-app-name
    paths:
      - apt-cache/
      - vendor/ruby
      - node_modules/
    policy: pull
  before_script:
    - gem install bundler --no-document
    - bundle install --jobs $(nproc) "${FLAGS[@]}" --path=vendor

.db:
  extends: .build
  services:
    - postgres:12.0
  variables:
    POSTGRES_USER: hix_postgresql
    POSTGRES_PASSWORD: hixonrails
    DB_USERNAME: hix_postgresql
    DB_PASSWORD: hixonrails
    DB_HOST: postgres
    RAILS_ENV: test
    DISABLE_SPRING: 1
    BUNDLE_PATH: vendor/bundle
  before_script:
    - export APT_CACHE_DIR=`pwd`/apt-cache && mkdir -pv $APT_CACHE_DIR
    - apt update -qq && apt -o dir::cache::archives="$APT_CACHE_DIR" install -yqq nodejs
    - gem install bundler --no-document
    - bundle install --jobs $(nproc) "${FLAGS[@]}" --path=vendor
    - bundle exec rails db:create db:schema:load --trace

As is, this file will fail the pipeline, it is only a strong foundation for further jobs presented in the guide.

Adjust the configuration file for this code to work with your project:

  1. In the build Ruby image, line 6, adjust your Ruby version. At the time of writing this article the last stable version is used, 2.6.5.
  2. In the database PostgreSQL image, line 20, adjust your PostgreSQL version. At the time of writing this article, the last stable version is used, 12.0.
  3. You can freely change corresponding user and password values, respectively in lines 22 - 24 and 23 - 25, however it's not mandatory.
  4. Replace all occurrences of the "hix_postgresql" with your Ruby on Rails project name.

it is important for the Continuous Integration suite to run on an environment as close to your production as possible.

To check your local PostgreSQL version, run the following command in the CLI.

psql -V

If you are developing some serious Ruby on Rails project, it is the best moment to install the latest stable version of the PostgreSQL database. If not, find the Docker PostgreSQL image corresponding to your local database version and adjust the GitlabCI configuration file accordingly.

Follow the next steps to actually use defined images in your continuous integration workflow.

Ruby on Rails with MySQL on GitlabCI

MySQL is the second most popular choice for Ruby on Rails applications, just behind the PostgreSQL.

For the MySQL to work you, same as with PostgreSQL, you are going to need a setup in the config/database.yml file adjusted to the one configuring the GitlabCI.

default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV['DB_POOL'] %>
  username: <%= ENV['DB_USERNAME'] %>
  password: <%= ENV['DB_PASSWORD'] %>
  host: <%= ENV['DB_HOST'] %>
  port: 3306

development:
  <<: *default
  database: hix_mysql_development

test:
  <<: *default
  database: hix_mysql_test

production:
  <<: *default
  database: hix_mysql_production

If that's your choice, here's the basic GitlabCI configuration for the Ruby on Rails project build with the MySQL database.

stages:
  - build
  - test

.build:
  image: ruby:2.6.5
  cache:
    key: rat-app-name
    paths:
      - apt-cache/
      - vendor/ruby
      - node_modules/
    policy: pull
  before_script:
    - gem install bundler --no-document
    - bundle install --jobs $(nproc) "${FLAGS[@]}" --path=vendor

.db:
  extends: .build
  services:
    - name: mysql:8.0.18
      command: ['--default-authentication-plugin=mysql_native_password']
  variables:
    MYSQL_ROOT_PASSWORD: hixonrails
    DB_USERNAME: root
    DB_PASSWORD: hixonrails
    DB_HOST: mysql
    RAILS_ENV: test
    DISABLE_SPRING: 1
    BUNDLE_PATH: vendor/bundle
  before_script:
    - export APT_CACHE_DIR=`pwd`/apt-cache && mkdir -pv $APT_CACHE_DIR
    - apt update -qq && apt -o dir::cache::archives="$APT_CACHE_DIR" install -yqq nodejs
    - gem install bundler --no-document
    - bundle install --jobs $(nproc) "${FLAGS[@]}" --path=vendor
    - bundle exec rails db:create db:schema:load --trace

It needs a few tweaks in order to work with your particular project. Do the following:

  1. In the build Ruby image, line 6, adjust your Ruby version. At the time of writing this article the last stable version is used, 2.6.5.
  2. In the database MySQL image, line 21, adjust your MySQL version. At the time of writing this article, the last stable version is used, 12.0.
  3. You can freely change corresponding root password values, respectively in lines 24 - 26, however, it's not mandatory.
  4. Replace all occurrences of the "hix_postgresql" with your Ruby on Rails project name.

Be aware that those are only images to extend in order to use them for the jobs to follow and they do nothing by themselves, as they do not belong to any of the stages defined at the beginning of the GitlabCI configuration file.

I am going to state that again, in case you skipped the PostgreSQL section: it is important for the Continuous Integration suite to run on an environment as close to your production as possible.

Take a moment now to check your local MySQL version. In your local CLI, type:

mysql -V

and do one of the following:

  1. Best: Update your local MySQL version to the latest stable one.
  2. Good: Update your GitlabCI docker image to the one matching your local version - check an official Docker MySQL images
  3. Bad: Do nothing (in case versions differ, because if they don't your technically in point 2).

If you went with the local update alternative, your future self is smiling at you right now. The second point is probably the most common choice, as all it takes is editing the configuration file.

The third option is plain wrong and it will cost you more time than it's worth it, eventually - go back to point 2.

Now that we have the installed bundle with our Ruby on Rails applications database ready to use, let's see what we can use them to run.

Ruby on Rails with RSpec on GitlabCI

RSpec is the favorite choice of the Ruby and Ruby on Rails community for writing tests.

It is important to check if newly developed features did not break older parts of the codebase and the Continuous Integration flow is a great place to do it. If you enforce the full test suite run from the Ruby on Rails application day one and agree with your team on some rational test coverage you will not regret it.

Speaking of the code coverage, there are great tools like SimpleCov, the Ruby gem for generating test coverage reports that hooked up with a Coveralls always tell you what's codebase code coverage at a glance, from the README.md badge level.

The Continuous Integration part of checking Ruby on Rails application tests health is really easy, all it takes is to store the results in the CI environment after the suite run. Reporting part comes in the RSpec configuration, you can read about it in the Ruby on Rails tested with RSpec article.

Overall, running the test suite of the Ruby on Rails project is the perfect job for the GitlabCI, so let's get to it.

Edit your GitlabCI configuration file with the following.

rspec:
  extends: .db
  stage: test
  cache:
    policy: pull-push
  artifacts:
    name: coverage
    paths:
      - coverage/
  script:
    - bundle exec rspec --profile 10 --format progress

You can skip the artifacts part of the job if you did not bother with SimpleCov configuration, but you don't have to. It is always possible to browse the coverage results from the GitlabCI level.

Another thing that's happening here is the profiling flag of our RSpec script - given the integer 10, it will show us the ten slowest unit tests in the whole suite.

Ruby on Rails with RuboCop on GitlabCI

RuboCop is the Ruby and Ruby on Rails community favorite linting tool. It checks the code against almost four hundred rules in its default configuration.

Along with the default gem corresponding to a Ruby Styleguide website, there are RuboCop extensions encapsulated in the separated gems for some of the most popular Ruby frameworks, including Ruby on Rails and RSpec.

On top of that, there's another gem authored by RuboCop Headquarters specifically checking the Ruby code performance, called, you guessed it, rubocop-performance.

If you decided to use the RuboCop in your Ruby on Rails project, the GitlabCI continuous integration suite is the place to do it - this way you can always be sure that your code is kept up to the RuboCop standard.

Edit the GitlabCI configuration file of your Ruby on Rails project with the following code.

rubocop:
  extends: .build
  stage: build
  cache:
    policy: pull-push
  script:
    - bundle exec rubocop

The RuboCop job does not require a Docker database image. We simply extend bare build, in which the gems bundle is installed - this way your CI runs faster every time.

For the complete RuboCop setup for Ruby on Rails applications using RSpec, please read the Ruby on Rails project RuboCop setup with RSpec.

Ruby on Rails with Brakeman on GitlabCI

If you keep the security of the Ruby on Rails project in mind, Brakeman is the way to go.

It is a simple command-line tool that checks the Ruby on Rails codebase against known security vulnerabilities, including SQL Injection and Cross-Site Scripting. You can read about those in our Ruby on Rails security guidelines.

The GitlabCI Continuous Integration suite is the best place to check your code against Brakeman's knowledge of breaking Ruby on Rails stuff. If you decided to use it, edit your configuration file with the following.

brakeman:
  extends: .build
  stage: build
  cache:
    policy: pull-push
  script:
    - bundle exec brakeman --rails6 -A

Same as the RuboCop job, Brakeman does not need the Docker database image in order to run, so we save ourselves a few seconds every time and extend the bare build one.

Remember, that using any security audit tool does not guarantee that your Ruby on Rails application is 100% safe. Please read the Open Web Application Security Project Top 10 Project and on top of other things, audit your website regularly with tools like Mozilla Observatory.

Ruby on Rails with Fasterer on GitlabCI

Fasterer is a static Ruby code analysis command-line tool that corresponds to the open-source project called Fast Ruby.

It is the single biggest website with up-to-date benchmarks of various Ruby methods that are able to achieve the same goal, which allows programmers to find the fastest tool for a lot of stuff done with Ruby.

If you decide to use the Fasterer in your Ruby on Rails project, here's the GitlabCI Continuous Integration configuration for running the static performance analysis against the codebase.

fasterer:
  extends: .build
  stage: build
  cache:
    policy: pull-push
  script:
    - bundle exec fasterer

One configuration tweak worth pointing out and included in the example fasterer repository configuration file is to turn off each.with_index vs a while loop comparison when using with Ruby on Rails applications.

Ruby on Rails with Rails Best Practices on GitlabCI

Rails Best Practices is a Ruby on Rails blog by Xinmin Labs, with its last article written in 2014. Do not give up on it though, as most of its wisdom is still applicable now, and it is safe to say that it will be for a long time.

Next to the old but gold read, there's a static code analysis tool with the same "Rails Best Practices" name. It reports all the code violating the guidelines thoroughly explained on the website.

If you decide to follow the Rails Best Practices, your GitlabCI Continuous Integration suite for the Ruby on Rails project is the best place to do so.

rails_best_practices:
  extends: .build
  stage: build
  cache:
    policy: pull-push
  script:
    - bundle exec rails_best_practices

With this small additional GitlabCI configuration comes a lot of good stuff that will keep your Ruby on Rails codebase safe and sound, pointing out common mistakes that are otherwise easy to forget.

Conclusion

Gitlab is a very popular choice for Ruby on Rails applications remote version control and it comes with many benefits, one of which is its tremendous help in the DevOps world.

GitlabCI is a powerful yet very easy to set up cloud suite for Continuous Integration and Delivery, and it comes built-in and ready to use with every new Gitlab repository, for free.

A lot of Ruby on Rails community knowledge about how to do things correctly was forged into static code analysis tools.

Enforcing the standardized style guide for your Ruby on Rails application via GitlabCI jobs and pipelines is a great way to both learn the framework better and save yourself some trouble in the future.

This is the step by step guide to install and configure Rollbar logger in the Ruby on Rails project in 2020.

Table of contents

Let's learn all about setting up Rollbar for Ruby on Rails...

Setup Ruby on Rails monitoring with Rollbar

...or have it done

Yes, Hix does this - so you don't have to.

What is Rollbar?

Rollbar is a realtime application monitoring and error tracking software which one can visit anytime via a web browser.

Applications can communicate with Rollbar via the HTTP protocol, sending data about their crashes and exceptions.

Developers subscribe to Rollbar's notifications and can almost instantly react to production problems by easily pinpointing them via sophisticated UI, which provides a complete set of data necessary for the job.

Why use Rollbar with Ruby on Rails?

  1. It is free to use up to 5000 API requests per month.
  2. It gathers more data than the default Ruby on Rails logger.
  3. It provides an intuitive UI, which is more comfortable to work with than primitive log files.

Ruby on Rails is provided with a basic logger that writes to the selected file, or files. Reading a single file with the constantly appended massive stack traces is a primitive way to monitor the application.

Rollbar collects and aggregates Ruby on Rails application crashes and exceptions data, with an additional context, such as a suspected release that started to cause the problem.

Via a sophisticated Rollbar web UI developer can browse errors by the latest, most occurrent and multiple additional pieces of information provided.

I cannot stress enough how crucial it is that your Ruby on Rails application is hooked up with an advanced logging and monitoring system such as Rollbar from its day one on production.

Rollbar account and project setup

Follow the instructions below to create your Rollbar account and set up Ruby on Rails project for further monitoring.

  1. Sign up on the official Rollbar website. By default, every email from your email domain will be allowed to join.Rollbar sign up form
    Sign up form on the Rollbar official website
  2. Verify your email and set up your user credentials.Rollbar user signup
    Sign up form for the specific Rollbar user
  3. You'll be taken to the Quick Setup Overview. The first step is to create your project.Rollbar quick setup
    Rollbar Quick Setup overview
  4. Enter your project name and press "Continue".Step 1: Create Rollbar project
    Create a Rollbar project
  5. In the next step, select "Rails" for your project SDK.Step 2: Select Ruby on Rails project SDK
    Select Ruby on Rails project SDK
  6. Copy your Rollbar Access Token from the last step.Step 3: Copy Rollbar Access Key
    Copy Rollbar Access Token

Rollbar allows you to set up multiple organization's projects and monitor them all via single web UI, which comes very handy especially for multiple services monitored daily.

Rollbar installation in Ruby on Rails project

If you use Hix on Rails, your job is done here, all you gonna do is paste your Rollbar Access Key into the first step of the Hix on Rails project initialization wizard.

Otherwise, if you sadly did not automate that part of your life yet, follow steps below for Ruby on Rails Rollbar configuration.

  1. Open your projects Gemfile and paste the gem 'rollbar' so it's available for every environment.
  2. In a command-line navigate to the project's directory, enter bundle install and while it runs go to the next step.
  3. Create the config/rollbar.rb file and paste the minimal configuration required, replacing the value with previously copied Rollbar Access Key.
  4. Create the config/initializers/rollbar.rb file to wrap a default Rails.logger so whenever you use it, the results are visible in the Rollbar UI.
  5. To report exceptions occurring in the Ruby on Rails booting process add the code to the config/environment.rb file, as Rails does not provide a way to hook into it.

config/rollbar.rb

# frozen_string_literal: true

Rollbar.configure do |config|
  config.access_token = 'YOUR_ROLLBAR_ACCESS_TOKEN_GOES_HERE'
end

config/rollbar.rb

# frozen_string_literal: true

Rails.logger.extend(ActiveSupport::Logger.broadcast(Rollbar::Logger.new))

config/environment.rb

# frozen_string_literal: true

require_relative 'application'
require_relative 'rollbar'

notify = -> (e) do
  begin
    Rollbar.with_config(use_async: false) do
      Rollbar.error(e)
    end
  rescue
    Rails.logger.error 'Synchronous Rollbar notification failed.  Sending async to preserve info'
    Rollbar.error(e)
  end
end

begin
  Rails.application.initialize!
rescue Exception => e
  notify.call(e)
  raise
end

This is a minimal setup required to hook up your Ruby on Rails application with your newly created Rollbar account, via the dedicated rollbar gem.

It is overall a better idea to not store credentials in your project repository and use dedicated environmental management instead. For example, if you use a dotenv-rails gem, it is a better idea to provide your DSN via the .env file.

.env

ROLLBAR_ACCESS_KEY=YOUR_ROLLBAR_ACCESS_TOKEN_GOES_HERE

config/rollbar.rb

# frozen_string_literal: true

Rollbar.configure do |config|
  config.access_token = ENV['ROLLBAR_ACCESS_TOKEN']
end

Let's see what other configuration options are worth tweaking while monitoring Ruby on Rails project with Rollbar.

Ruby on Rails Rollbar configuration

With the minimalistic setup, we started to report Ruby on Rails application exceptions to the Rollbar.

Rollbar default configuration with the access key passed at this point is:

Rollbar.configure do |config|
  config.access_token = ENV['ROLLBAR_ACCESS_TOKEN']
  config.async_handler = nil
  config.before_process = []
  config.capture_uncaught = nil
  config.code_version = nil
  config.custom_data_method = nil
  config.default_logger = lambda { ::Logger.new(STDERR) }
  config.logger_level = :info
  config.delayed_job_enabled = true
  config.disable_monkey_patch = false
  config.disable_core_monkey_patch = false
  config.disable_rack_monkey_patch = false
  config.dj_threshold = 0
  config.enabled = nil # set to true when configure is called
  config.endpoint = DEFAULT_ENDPOINT
  config.environment = nil
  config.exception_level_filters = {
    'ActiveRecord::RecordNotFound' => 'warning',
    'AbstractController::ActionNotFound' => 'warning',
    'ActionController::RoutingError' => 'warning'
  }
  config.failover_handlers = []
  config.framework = 'Plain'
  config.ignored_person_ids = []
  config.payload_options = {}
  config.person_method = 'current_user'
  config.person_id_method = 'id'
  config.person_username_method = nil
  config.person_email_method = nil
  config.project_gems = []
  config.populate_empty_backtraces = false
  config.report_dj_data = true
  config.open_timeout = 3
  config.request_timeout = 3
  config.net_retries = 3
  config.js_enabled = false
  config.js_options = {}
  config.locals = {}
  config.scrub_fields = [:passwd, :password, :password_confirmation, :secret,
                        :confirm_password, :password_confirmation, :secret_token,
                        :api_key, :access_token, :accessToken, :session_id]
  config.scrub_user = true
  config.scrub_password = true
  config.randomize_scrub_length = false
  config.scrub_whitelist = []
  config.uncaught_exception_level = 'error'
  config.scrub_headers = ['Authorization']
  config.sidekiq_threshold = 0
  config.safely = false
  config.transform = []
  config.use_async = false
  config.use_eventmachine = false
  config.verify_ssl_peer = true
  config.web_base = DEFAULT_WEB_BASE
  config.write_to_file = false
  config.send_extra_frame_data = :none
  config.project_gem_paths = []
  config.use_exception_level_filters_default = false
  config.proxy = nil
  config.raise_on_error = false
  config.transmit = true
  config.log_payload = false
  config.collect_user_ip = true
  config.anonymize_user_ip = false
  config.backtrace_cleaner = nil
  config.hooks = {
    :on_error_response => nil, # params: response
    :on_report_internal_error => nil # params: exception
  }

  config.configured_options = ConfiguredOptions.new(self)
end

Environments setup

Using Rollbar reporting in the test and development environments is an overkill. You can set up when it's enabled via the configuration.

Rollbar.configure do |config|
  config.enabled = %w[production staging].include?(Rails.env)
end

If you want to give your custom name to the environment, you can do that by yet another environment-related configuration option.

Rollbar.configure do |config|
  config.environment = 'your_custom_environment_name'
end

Asynchronous reporting

Error logging is not the primary task of most of the web applications, including Ruby on Rails. It is good to keep it asynchronous, and Rollbar allows users to do so by exposing the asynchronous configuration for the most popular choices of asynchronous code execution in Ruby.

Sidekiq integration with Rollbar.

Rollbar.configure do |config|
  config.use_sidekiq, queue: :rollbar
end

SuckerPunch integration with Rollbar.

Rollbar.configure do |config|
  config.use_sucker_punch
end

GirlFriday integration with Rollbar.

Rollbar.configure do |config|
  config.use_async = true
end

DelayedJob integration with Rollbar.

Rollbar.configure do |config|
  config.delayed_job_enabled = true
  config.use_delayed_job, queue: 'rollbar'
  config.report_dj_data = true
  config.dj_threshold = 0
end

Data sanitization

As we can see in the Rollbar defaults above, the logger scrubs some of the data from its reports.

Rollbar.configure do |config|
  config.collect_user_ip = false
  config.anonymize_user_ip = true
  config.user_ip_obfuscator_secret = "a-private-secret-here"
  config.scrub_fields = [:passwd, :password, :password_confirmation, :secret,
                        :confirm_password, :password_confirmation, :secret_token,
                        :api_key, :access_token, :accessToken, :session_id]
  config.scrub_user = true
  config.scrub_password = true
  config.scrub_headers = ['Authorization']
end

We can further configure that by adding the custom fields that we want to remove from the reports or even whitelist some that we don't.

Users data

Whenever your Ruby on Rails application provides any kind of authentication for the visitors, you can report user data for an additional context.

Rollbar.configure do |config|
  config.person_method = "my_current_user"
  config.person_id_method = "id"
  config.person_username_method = "name"
  config.person_email_method = "email"
end

Pinpoint guilty release

For an easier way to estimate what caused the reported exception to occur it is useful to report some release context to Rollbar, ideally extracted from your code version control.

Rollbar.configure do |config|
  config.code_version = `git describe --abbrev=0`
end

The following will give you the most recent annotated git tag. If you follow the Semantic Versioning, it will be for example 3.17.2.

Proxy and Secure Sockets Layer

It is possible to report the Ruby on Rails exception occurrences to Rollbar via a proxy.

Rollbar.configure do |config|
  config.proxy = {
    host: 'http://some.proxy.server',
    port: 80,
    user: 'username_if_auth_required',
    password: 'password_if_auth_required'
  }
end

An exported environment variable https_proxy will be respected as well.

export https_proxy='http://username:password@example.com:5000'

On top of that, you can disable SSL verification with a configuration flag, as it's enabled by default.

Rollbar.configure do |config|
  config.verify_ssl_peer = false
end

Custom reports modifications

Every Ruby on Rails application exception reported to Rollbar is expandable. It accepts lambda as an argument and has to return a Hash later merged to the original exception.

Rollbar.configure do |config|
  conifg.custom_data_method = lambda {
    { android_version: 6, dimensions: { width: 320, height: 540 } }
  }
end

Once sent, it appears in the Occurrences tab of the exception reported.

If there's some really important functionality in our Ruby on Rails application, it is a good practice to prepare for the worst with custom exceptions and to set their severity to critical with configuration options.

Rollbar.configure do |config|
  config.exception_level_filters.merge!({
    'PaymentException': 'critical'
  })
end

The same configuration option comes to help if we want to ignore reporting a chosen exception.

Rollbar.configure do |config|
  config.exception_level_filters.merge!({
    'ActionController::RoutingError': 'ignore'
  })
end

However, it's not the most developer-friendly to always remember to add the critical error severity to the configuration. My advice is to define your own critical exception class and inherit from it further down the code whenever.

Conclusion

Rollbar is a powerful tool that helps you to keep the Ruby on Rails application well-maintained and is definitely worth using if you want to monitor every newly developed feature seriously.

With Hix on Rails, all you need to do in order to have a fully configured Rollbar logger is creating your account and copy-pasting the Rollbar Access Key into the project initialization wizard.

This is the step by step guide to install and configure Sentry Raven logger in the Ruby on Rails project in 2020.

Table of contents

Let's learn all about configuring Sentry for Ruby on Rails monitoring...

Sentry monitoring setup for Ruby on Rails

...or have it done

Yes, Hix does this - so you don't have to.

What is Sentry?

Sentry is a realtime application monitoring and error tracking software which one can visit anytime via a web browser.

Applications can communicate with Sentry via the HTTP protocol, sending data about their crashes and exceptions.

Developers subscribe to Sentry's notifications and can almost instantly react to production problems by easily pinpointing them via sophisticated UI, which provides a complete set of data necessary for the job.

Why use Sentry Raven with Ruby on Rails?

  1. It is free to use up to 5000 API requests per month.
  2. It gathers more data than the default Ruby on Rails logger.
  3. It provides an intuitive UI, which is more comfortable to work with than primitive log files.

Ruby on Rails is provided with a basic logger that writes to the selected file, or files. Reading a single file with the constantly appended massive stack traces is a primitive way to monitor the application.

Sentry collects and aggregates Ruby on Rails application crashes and exceptions data, with an additional context, such as a suspected release that started to cause the problem.

Via a sophisticated Sentry web UI developer can browse errors by the latest, most occurrent and multiple additional pieces of information provided.

I cannot stress enough how crucial it is that your Ruby on Rails application is hooked up with an advanced logging and monitoring system such as Sentry from its day one on production.

Sentry account and project setup

Follow the instructions below to create your Sentry account and set up the Ruby on Rails project for further monitoring.

  1. Sign up on the official Sentry website.Sentry sign up form
    Sign up form on the Sentry official website
  2. In the second onboarding step, select "Rails" platform.Select Sentry project platfrom
    Select "Rails" platform in the Sentry setup
  3. From the third onboarding step copy your Sentry DSNSentry DSN
    Copy Sentry DSN

The DSN abbreviation stands for Data Source Name and is autogenerated for every project that you are going to hook into your Sentry account.

It allows you to keep all the logs in one place, which comes very handy especially for multiple services monitored daily.

Sentry Raven installation in Ruby on Rails project

If you use Hix on Rails, your job is done here, all you gonna do is paste your Sentry DSN into the second step of the Hix on Rails project initialization wizard.

Otherwise, if you sadly did not automate that part of your life yet, follow steps below for Ruby on Rails Sentry configuration.

  1. Open your projects Gemfile and paste the gem 'sentry-raven' so it's available for every environment.
  2. In a command-line navigate to the project's directory, enter bundle install and while it runs go to the next step.
  3. Create the config/initializers/sentry.rb file and paste the minimal configuration required, replacing the value with previously copied Sentry DSN.

config/initializers/sentry.rb

# frozen_string_literal: true

Raven.configure do |config|
  config.dsn = 'YOUR_SENTRY_DSN_GOES_HERE'
end

This is a minimal setup required to hook up your Ruby on Rails application with your newly created Sentry account, via the dedicated sentry-raven gem.

It is overall a better idea to not store credentials in your project repository and use dedicated environmental management instead. For example, if you use a dotenv-rails gem, it is a better idea to provide your DSN via the .env file.

.env

SENTRY_DSN=YOUR_SENTRY_DSN_GOES_HERE

config/initializers/sentry.rb

# frozen_string_literal: true

Raven.configure do |config|
  config.dsn = ENV['SENTRY_DSN']
end

Let's see what other configuration options are worth tweaking while monitoring Ruby on Rails project with Sentry.

Ruby on Rails Sentry configuration

With the minimalistic setup, we started to report Ruby on Rails application exceptions to the Sentry.

Raven default configuration with the DSN passed at this point is:

Raven.configure do |config|
  config.dsn = ENV['SENTRY_DSN']
  config.async = false
  config.context_lines = 3
  config.current_environment = current_environment_from_env
  config.encoding = 'gzip'
  config.environments = []
  config.exclude_loggers = []
  config.excluded_exceptions = IGNORE_DEFAULT.dup
  config.inspect_exception_causes_for_exclusion = false
  config.linecache = ::Raven::LineCache.new
  config.logger = ::Raven::Logger.new(STDOUT)
  config.open_timeout = 1
  config.processors = DEFAULT_PROCESSORS.dup
  config.project_root = detect_project_root
  config.rails_activesupport_breadcrumbs = false
  config.rails_report_rescued_exceptions = true
  config.release = detect_release
  config.sample_rate = 1.0
  config.sanitize_credit_cards = true
  config.sanitize_fields = []
  config.sanitize_fields_excluded = []
  config.sanitize_http_headers = []
  config.send_modules = true
  config.server = ENV['SENTRY_DSN']
  config.server_name = server_name_from_env
  config.should_capture = false
  config.ssl_verification = true
  config.tags = {}
  config.timeout = 2
  config.transport_failure_callback = false
  config.before_send = false
end

Environments setup

By default, whenever provided a valid DSN, Sentry Raven will work automatically in every Ruby on Rails environment, where the defaults are test, development, and production.

That's overkill for the development environment, so my advice is to further configure it after checking if it works.

Raven.configure do |config|
  config.environments = %[production]
end

This way an automated test suite and development of new features won't eat up your quota.

Another closely related option that is wisely deduced by Raven is current environment detection.

  1. First, Sentry tries to get ENV['RAILS_ENV']
  2. Next, if first is absent, it tries ENV['RACK_ENV']

You can customize it via the current environment configuration flag.

Raven.configure do |config|
  config.current_environment = 'staging'
end

Whatever you'll set here, will be visible in the Sentry environments dropdown.

Sentry filtering by environments
Sentry environments dropdown

Asynchronous reporting

Error logging is not the primary task of most of the web applications, including Ruby on Rails. It is good to keep it asynchronous, and Sentry allows users to do so by exposing the asynchronous configuration flag.

Raven.configure do |config|
  config.async = lambda { |event| SentryJob.perform_later(event) }
end

app/jobs/sentry_job.rb

class SentryJob < ActiveJob::Base
  queue_as :sentry

  def perform(event)
    Raven.send_event(event)
  end
end

If the async callback raises an exception, Raven will attempt to send synchronously.

Data sanitization

Sentry for Ruby on Rails provides two configuration options for data sanitization.

Raven.configure do |config|
  config.sanitize_fields = ["my_field", "foo(.*)?bar]
  config.sanitize_http_headers = %w[Referer User-Agent Server From]
end

The field sanitization accepts a raw string and regex-like strings for striping the data from the requests sent to Sentry.

The second one allows you to filter out HTTP headers from the payload. A full list of potentially sensitive HTTP headers can be found in the RFC 2616.

Data processing

The default Sentry data processors are:

# Note the order - we have to remove circular references and bad characters
# before passing to other processors.
DEFAULT_PROCESSORS = [
  Raven::Processor::RemoveCircularReferences,
  Raven::Processor::UTF8Conversion,
  Raven::Processor::SanitizeData,
  Raven::Processor::Cookies,
  Raven::Processor::PostData,
  Raven::Processor::HTTPHeaders
].freeze

which we can modify via yet another configuration flag by adding new and removing existing processors from the array.

require 'raven/processor/removestacktrace'

Raven.configure do |config|
  config.processors << Raven::Processor::RemoveStacktrace
  config.processors -= [Raven::Processor::PostData]
  config.processors -= [Raven::Processor::Cookies]
end

You might want to remove cookies and post data processors via the configuration, as by default Sentry does not send POST data or cookies if present, and it may improve your further debugging experience.

A full list of the Raven processors belonging to the `Raven::Processor` module.

├── processor
│   ├── cookies.rb
│   ├── http_headers.rb
│   ├── post_data.rb
│   ├── removecircularreferences.rb
│   ├── removestacktrace.rb
│   ├── sanitizedata.rb
│   └── utf8conversion.rb

On top of all that, Sentry allows filtering out selected exceptions by appending them to the excluded exceptions array.

Raven.configure do |config|
  config.excluded_exceptions += ['ActionController::RoutingError']
end

On an even deeper level, Sentry allows you to prevent exceptions from being sent via providing your custom logic.

Raven.configure do |config|
  config.should_capture = Proc.new do |exception|
    exception.super != 'WillinglyUnreportedException'
  end
end

It is especially useful when you want to filter out a whole bunch of exceptions without always remembering to put them into the excluded exceptions array.

class WillinglyUnreportedException < StandardError; end
class DontCareTooMuchException < WillinglyUnreportedExceptions; end
class NevermindException < WillinglyUnreportedExceptions; end

Another option that might be especially useful for large applications is data sampling.

Raven.configure do |config|
  config.sample_rate = 0.5
end

A value of 0 will deny sending any events, and value of 1 will send every single event, which is the default behavior.

Pinpoint guilty release

Sentry is clever in deducing which release causes an exception. It takes the following in the given order of precedence.

  1. Commit SHA of the last git commit
  2. Last line of the application root REVISION file
  3. For Heroku, dyno metadata enabled via Heroku Labs

It can be customized if you have some kind of custom release tracking system.

Raven.configure do |config|
  config.release = 'custom release string'
end

The default settings may be configured smoothly with popular git remote providers such as Github and Gitlab for convenient linking to the guilty git commits and tags via Sentry UI.

Proxy and Secure Sockets Layer

Sentry gives its user an option to configure a proxy connection.

Raven.configure do |config|
  config.proxy = 'http://example.com'
end

It accepts a simple string representing the URL to your proxy server.

SSL verification might be disabled in the configuration file, as it's enabled by default.

Raven.configure do |config|
  config.ssl_verification = false
end

Custom reports modifications

In your configuration file, you can use two options provided for globally customizing Sentry reports.

Raven.configure do |config|
  config.tags = { hostname: `hostname` }
  config.before_send = lambda do |event, hint|
    event.fingerprint = ['fingerprint']
    event
  end
end

A first of them, the tagging option, allows you to send an additional context with your events for further filtering. For example, if you have a load balancer set up in front of your Ruby on Rails application, you might want to send some info identifying a specific instance on which the exception occurred.

The second one helps you to modify every single occurrence on the fly, accessing it before is send. Be aware that if you won't return the event from this method, it will be dropped.

Conclusion

Sentry is a powerful tool that helps you to keep the Ruby on Rails application well-maintained and is definitely worth using if you want to monitor every newly developed feature seriously.

With Hix on Rails, all you need to do in order to have a fully configured Sentry logger is creating your account and copy-pasting the Sentry DSN into the project initialization wizard.

This is the ultimate guide for your next Ruby on Rails project setup on Github with CircleCI for continuous integration in 2020.

Table of contents

Let's learn all about setting up Ruby on Rails project on Github with CircleCI...

Ruby on Rails on Github with CircleCI

...or have it done

Yes, Hix does this - so you don't have to.

What is Github?

Github is one of the top 100 websites on the Internet, with ~310M monthly visits. It holds the biggest OpenSource codebase in the world.

Github top 100 Internet websites
Github on Similarweb, December 2019

One can safely say that it's a proven tool in a programmers' toolbox.

Fun fact is that Ruby, with Ruby on Rails, is a big part of the Github's tech stack.

Github's Ruby tech stack
Github on Stackshare

Among all the other features, Github is a remote repository hosting for the git version control system. When developers create their code, they make constant changes, additions, improvements and deletions to the codebase.

The version control system stores these code revisions in a central repository, which allows programmers to easily collaborate, as they can download the new version of the software, add their changes and upload them.

Why use Github for Ruby on Rails app?

The biggest advantage of using Github for Ruby on Rails project, as well as any other remote repository hosting provider, is that you can create constant backups of your code

Git provides a full history of changes and an ability to roll back to the older version of the code in case of introducing changes that causes errors.

With Github, it is available at any point in time, online. You are not limited to the single machine on which code was written.

Another advantage is that with its massive Open Source codebase there is a big chance that anybody that is going to collaborate with your code is going to know how to use Github, so statistically, a learning curve is the smallest possible.

Github provides an intuitive UI that allows developers to easily collaborate, with its Pull Requests, Code Review and Forks.

It even introduces its own git branching strategy, called GitHub flow.

Continuous integration for Ruby on Rails

Continuous Integration (CI) is a development practice that requires collaborators to upload their code to the shared repository continuously, ideally several times a day.

Every time they do, the code is verified by an automated build, the test suite runs and dedicated static code analysis tools check it for security vulnerabilities, errors, and all kinds of inaccuracies.

It is good for both developers and software to automatically check the code quality and CI a great place to do it.

There are multiple open-source static code analysis tools available for both Ruby and Ruby on Rails.

Most of them can be set up on the CI server to audit the code of Ruby on Rails project every time its pushed or nightly.

Why use CircleCI for Ruby on Rails app?

CircleCI is a Continous Integration and Delivery cloud provider.

It integrates with Github, so using both of them together is as simple as creating your accounts and setting up the Ruby on Rails project.

No custom servers maintenance, just going through some web forms and you are all set.

No credit card information required, a perfect combination to start small with your project and pay for what you use as you grow.

CircleCI provides an intuitive, well-organized UI with all the information required to establish the problem that occurs when the new code was integrated into the Github hosted codebase.

It is crucial to set up the Continuous Integration system for any project, let alone Ruby on Rails, from the first day of the development.

This is a great way to avoid a lot of technical debt, protect yourself from common mistakes and enforce certain standards that make working with Ruby on Rails codebase pleasing and its maintenance much, much easier.

Create Github account and Ruby on Rails project

Follow the instructions below to create your Github account and set up the Ruby on Rails project.

  1. Sign up on the official Github website. Github sign up form
    Sign up form on the Github official website
  2. Verify your email.
  3. You will be redirected to the new Github repository creation page.
  4. Provide the repository name and click the "Create repository" button. Github create repository form
    Create git repository on Github
  5. On the new repository page, get your remote repository HTTPS or SSH link. Link to the new Github repository
    Copy a link to the new repository on Github
  6. If you are using Hix on Rails, that's all you are going to need for now, just paste the address into the CLI when asked for it.
  7. Navigate to the Ruby on Rails project root directory in the command line and enter git remote add origin YOUR_REPOSITORY_URL

Create CircleCI account linked to Github

Follow the instructions below to create your CircleCI account linked to your Github account, and to set up the Ruby on Rails project continuous integration.

  1. Click "Sign up with Github" on the official CircleCI website.CircleCI sign up form
    Sign up with Github on the official CircleCI website
  2. On the authorization page, click "Authorize circleci".CircleCI authorization on Github
    Authorize CircleCI on Github
  3. You will be redirected to the CircleCI dashboard. From the left-side sidebar, select "Add Projects".Add projects in the CircleCI dashboard
    Add projects in the CircleCI dashboard
  4. In the projects tab, click "Set up project" next to the newly created Github project.Setup project in the CircleCI dashboard
    Setup project in the CircleCI dashboard

Ruby on Rails project on CircleCI

If you are using Hix on Rails, that's it, all you need to do is click "Start building" after pushing the code with your first database migration, as the database creation is a part of the Ruby on Rails application build process and it will fail if no tables are present.

Otherwise, if you sadly did not automate that part of your life yet, follow steps below for Ruby on Rails project configuration on the CircleCI.

In your project root, create the required CircleCI configuration file.

cd path/to/your/project/root
mkdir .circleci
touch .circleci/config.yml

Open the CircleCI configuration file with a text editor of your choice and paste the basic code required, depending on your database choice.

Ruby on Rails with PostgreSQL on CircleCI

PostgreSQL is the most popular choice for Ruby on Rails applications.

For the CircleCI to work you are going to need a specific setup in the config/database.yml file. Notice that the dotenv-rails gem is used.

config/database.yml

default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV['DB_POOL'] %>
  username: <%= ENV['DB_USERNAME'] %>
  password: <%= ENV['DB_PASSWORD'] %>
  host: <%= ENV['DB_HOST'] %>
  port: 5432

development:
  <<: *default
  database: hix_postgresql_development

test:
  <<: *default
  database: hix_postgresql_test

production:
  <<: *default
  database: hix_postgresql_production

If you decided to go with it, here's the basic CircleCI configuration for the Ruby on Rails project build with the PostgreSQL database.

version: 2.1

executors:
  default:
    working_directory: ~/hix_postgresql
    docker:
      - image: circleci/ruby:2.6.5
        environment:
          BUNDLE_JOBS: 3
          BUNDLE_PATH: vendor/bundle
          BUNDLE_RETRY: 3
          BUNDLER_VERSION: 2.0.1
          RAILS_ENV: test
          DB_HOST: 127.0.0.1
          PG_HOST: 127.0.0.1
          PGUSER: hixonrails
      - image: circleci/postgres:12.0
        environment:
          POSTGRES_DB: hix_postgresql_test
          POSTGRES_USER: hixonrails

commands:
  configure_bundler:
    description: Configure bundler
    steps:
      - run:
          name: Configure bundler
          command: |
            echo 'export BUNDLER_VERSION=$(cat Gemfile.lock | tail -1 | tr -d " ")' >> $BASH_ENV
            source $BASH_ENV
            gem install bundler

jobs:
  build:
    executor: default
    steps:
      - checkout
      - restore_cache:
          keys:
            - hix_postgresql-{{ .Branch }}-{{ checksum "Gemfile.lock" }}
            - hix_postgresql-
      - configure_bundler
      - run:
          name: Install bundle
          command: bundle install
      - run:
          name: Wait for DB
          command: dockerize -wait tcp://127.0.0.1:5432 -timeout 1m
      - run:
          name: Setup DB
          command: bundle exec rails db:create db:schema:load --trace
      - save_cache:
          key: hix_postgresql-{{ .Branch }}-{{ checksum "Gemfile.lock" }}
          paths:
            - vendor/bundle
      - persist_to_workspace:
          root: ~/
          paths:
            - ./hix_postgresql

workflows:
  version: 2
  integration:
    jobs:
      - build

There are multiple adjustments necessary for this code to work with a particular project.

  1. In the Docker Ruby image, line 7, adjust your Ruby version. At the time of writing this article the last stable version is used, 2.6.5
  2. In the Docker PostgreSQL image, line 17, adjust your PostgreSQL version. At the time of writing this article the last stable version is used, 12.0.
  3. In lines 16 and 20, you can adjust the PostgreSQL user name, however, it's not mandatory.
  4. Replace all occurrences of the "hix_postgresql" with your Ruby on Rails project name.

For the workflow to pass on the CircleCI, you need to have db/schema.rb file checked into the repository, which means that you need to create at least one database migration.

Ruby on Rails with MySQL on CircleCI

MySQL is the second most popular choice for Ruby on Rails applications, just behind the PostgreSQL.

For the CircleCI to work you are going to need a specific setup in the config/database.yml file. Notice that the dotenv-rails gem is used.

config/database.yml

default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV['DB_POOL'] %>
  username: <%= ENV['DB_USERNAME'] %>
  password: <%= ENV['DB_PASSWORD'] %>
  host: <%= ENV['DB_HOST'] %>
  port: 3306

development:
  <<: *default
  database: hix_mysql_development

test:
  <<: *default
  database: hix_mysql_test

production:
  <<: *default
  database: hix_mysql_production

If you decided to go with it, here's the basic CircleCI configuration for the Ruby on Rails project build with the PostgreSQL database.

version: 2.1

executors:
  default:
    working_directory: ~/hix_mysql
    docker:
      - image: circleci/ruby:2.6.5
        environment:
          BUNDLE_JOBS: 3
          BUNDLE_PATH: vendor/bundle
          BUNDLE_RETRY: 3
          BUNDLER_VERSION: 2.0.1
          RAILS_ENV: test
          DB_HOST: 127.0.0.1
          DB_USERNAME: root
          DB_PASSWORD: ''
      - image: circleci/mysql:8.0.18
        command: [--default-authentication-plugin=mysql_native_password]
        environment:
          MYSQL_ALLOW_EMPTY_PASSWORD: 'true'
          MYSQL_ROOT_HOST: '%'

commands:
  configure_bundler:
    description: Configure bundler
    steps:
      - run:
          name: Configure bundler
          command: |
            echo 'export BUNDLER_VERSION=$(cat Gemfile.lock | tail -1 | tr -d " ")' >> $BASH_ENV
            source $BASH_ENV
            gem install bundler

jobs:
  build:
    executor: default
    steps:
      - checkout
      - restore_cache:
          keys:
            - hix_mysql-{{ .Branch }}-{{ checksum "Gemfile.lock" }}
            - hix_mysql-
      - configure_bundler
      - run:
          name: Install bundle
          command: bundle install
      - run:
          name: Wait for DB
          command: dockerize -wait tcp://127.0.0.1:3306 -timeout 1m
      - run:
          name: Setup DB
          command: bundle exec rails db:create db:schema:load --trace
      - save_cache:
          key: hix_mysql-{{ .Branch }}-{{ checksum "Gemfile.lock" }}
          paths:
            - vendor/bundle
      - persist_to_workspace:
          root: ~/
          paths:
            - ./hix_mysql

workflows:
  version: 2
  integration:
    jobs:
      - build

There are multiple adjustments necessary for this code to work with a particular project.

  1. In the Docker Ruby image, line 7, adjust your Ruby version. At the time of writing this article the last stable version is used, 2.6.5
  2. In the Docker MySQL image, line 17, adjust your MySQL version. At the time of writing this article the last stable version is used, 8.0.18.
  3. Replace all occurrences of the "hix_mysql" with your Ruby on Rails project name.

For the workflow to pass on the CircleCI, you need to have db/schema.rb file checked into the repository, which means that you need to create at least one database migration.

Ruby on Rails with RSpec on CircleCI

RSpec is the most popular Ruby testing framework, hence the tool of our choice.

In the continuous integration flow, running the test suite is one of the most common jobs, to ensure that new features do not break other well-tested parts of a Ruby on Rails application.

On top of that, RSpec can be easily configured with SimpleCov, the ruby gem for generating test coverage reports. Generating those reports gives developers a nice overview on how the Ruby on Rails application is maintained.

This is the perfect job for the CircleCI, so if you have decided to go with it, edit the previously created configuration file, adding the RSpec job and running it in the defined workflow.

jobs:
  build:
    executor: default
    steps:
      - checkout
      - restore_cache:
          keys:
            - hix-{{ .Branch }}-{{ checksum "Gemfile.lock" }}
            - hix-
      - configure_bundler
      - run:
          name: Install bundle
          command: bundle install
      - run:
          name: Wait for DB
          command: dockerize -wait tcp://127.0.0.1:3306 -timeout 1m
      - run:
          name: Setup DB
          command: bundle exec rails db:create db:schema:load --trace
      - run:
          name: RSpec
          command: |
            bundle exec rspec --profile 10 \
                              --format progress
      - store_artifacts:
          path: coverage
      - save_cache:
          key: hix-{{ .Branch }}-{{ checksum "Gemfile.lock" }}
          paths:
            - vendor/bundle
      - persist_to_workspace:
          root: ~/
          paths:
            - ./hix

workflows:
  version: 2
  integration:
    jobs:
      - build

For the RSpec to work it needs the Ruby on Rails project to be built and the database to be set up.

You can skip the part that stores the artifacts if you did not bother with the SimpleCov setup.

The profiling flag is another thing that's nice to have in the CI workflow - it tells you which tests are the slowest to run.

Hix on Rails comes additionally configured to use Coveralls, which gives a nice test coverage percentage badge for your Ruby on Rails project's README.md.

Ruby on Rails with RuboCop on CircleCI

RuboCop is the most popular Ruby code linting tool available, with almost 400 rules checked in the default configuration.

Next to the default gem, there are plugins that check the Ruby on Rails, RSpec and Ruby code performance rules, which combined gives as the total of almost 500 rules checked, every time new code is contributed to the codebase.

If you decided to use the RuboCop in your Ruby on Rails project here's the CircleCI configuration required.

  rubocop:
    executor: default
    steps:
      - attach_workspace:
          at: ~/
      - configure_bundler
      - run:
          name: Rubocop
          command: bundle exec rubocop

workflows:
  version: 2
  integration:
    jobs:
      - build
      - rubocop:
          requires:
            - build

For the complete RuboCop setup for Ruby on Rails applications using RSpec, please read the Ruby on Rails project RuboCop setup with RSpec.

Ruby on Rails with Brakeman on CircleCI

Brakeman is the most popular ruby gem for Ruby on Rails applications security vulnerabilities audit.

It provides a simple command-line tool that among the total 29 warnings, checks your Ruby on Rails application code for possible SQL Injection or Cross-Site Scripting attacks. You can read more about those in Ruby on Rails security guide.

The CircleCI continuous integration suite is the perfect place to check your code for security, so if you decided to use Brakeman in your Ruby on Rails application, here's the required CircleCI configuration.

brakeman:
    executor: default
    steps:
      - attach_workspace:
          at: ~/
      - configure_bundler
      - run:
          name: Brakeman
          command: bundle exec brakeman

workflows:
  version: 2
  integration:
    jobs:
      - build
      - brakeman:
          requires:
            - build

Remember, that using any security audit tool does not guarantee that your Ruby on Rails application is 100% safe. Please read the Open Web Application Security Project Top 10 Project and on top of other things, audit your website regularly with tools like Mozilla Observatory.

Ruby on Rails with Fasterer on CircleCI

Fast Ruby is the open-source project with a multitude of various benchmarks between different Ruby methods able to achieve the same goal.

Fasterer is a ruby gem, a static code analysis command-line tool that's able to check your code for potentially faster solutions, based on the Fast Ruby benchmarks.

If you decide to use the Fasterer, your continuous integration flow on CircleCI is a perfect place to do so.

  fasterer:
    executor: default
    steps:
      - attach_workspace:
          at: ~/
      - configure_bundler
      - run:
          name: Fasterer
          command: bundle exec fasterer

workflows:
  version: 2
  integration:
    jobs:
      - build
      - fasterer:
          requires:
            - build

One option that is recommended to be turned off for Ruby on Rails project using Fasterer is the each.with_index versus the while loop, all the rest of a default configuration is good to go.

Ruby on Rails with Rails Best Practices on CircleCI

Rails Best Practices is an old but gold blog about Ruby on Rails applications development. It explains with a great detail common Ruby on Rails (and other) patterns, like "Law of Demeter" and "Tell, don't ask".

Next to the great read, there's another static code analysis tool, called… Rails Best Practices. It makes sure to report any Ruby on Rails application code that does not apply to the guides written on the blog.

If you decide to use it, your continuous integration suite on CircleCI is the perfect place to do so.

  rails_best_practices:
    executor: default
    steps:
      - attach_workspace:
          at: ~/
      - configure_bundler
      - run:
          name: Rails Best Practices
          command: bundle exec rails_best_practices

workflows:
  version: 2
  integration:
    jobs:
      - build
      - rails_best_practices:
          requires:
            - build

I strongly recommend against giving up on the tool only because the blog's last update was in 2014. All of the rules, as well as all the code quality checks, are still applicable in the latest Ruby on Rails version.

Conclusion

Ruby on Rails is a very popular choice for web application development and it comes with many benefits, one of which is the well-established community knowledge on how to do things correctly.

A lot of this knowledge was forged into static code analysis tools that let developers find their mistakes easily.

CircleCI is trivial to use yet very powerful Continous Integration provider that lets you build, test and audit your Ruby on Rails application code with minimal setup, for free.

If you care about the Ruby on Rails application code quality and easy maintenance, that's the perfect combination for you.

Hix on Rails
Hix on Rails
Follow us on Twitter for RoR news and tutorials!
linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram