I’ve been a Ruby Software Developer since 2012. It’s more than seven years of experience in developing web applications using Ruby and Ruby on Rails framework.

When I joined SourceLevel, the main application already existed. Before becoming a Startup, SourceLevel was called Ebert. Folks from Plataformatec did an excellent job building the foundations of what now is our product.

It’s been Ruby on Rails application since the beginning. Currently, we run under Ruby on Rails 5.1.7 version, even though we intend to upgrade to 5.2.3 soon.

Top Ruby Gems

We are a small team. Our efforts need to be well measured, and developers must work precisely on what matters. We need to find the “nirvana” among developing new features, fixing bugs, dealing with technical debts – as Martin Fowler explained -, and chore demands, which is something important to our culture.

Importing to the project a well tested and working gem for a specific job save us time. Although it also adds complexity and external dependency, its impact on productivity and velocity is significantly higher.

Developing and internally maintaining tools is an unnecessary effort for now. It is crucial to keep in mind that adding too many dependencies is terrible, and finding the balance between using a gem or developing our solution is hard.

That said, I’d like to share a list of those gems we are currently using in our product. Below I give some context on which problem each gem solves and how they save us time!

Ruby gems context and usage

I organized this section in categories that describe a bit of what and why we use each gem.

The fact we chose a specific gem, does not imply I recommend your project to use it. My idea here is to share a bit more about SourceLevel development.

Text Handling & Formatting

We are heavy Markdown users! We produce internal documentation in Markdown. The docs page is a static site entirely written in it (and built with Middleman).

In the main app, we use markerb to parse markdown content and convert it to HTML. Comments to Github, issue explanations and repository badges are examples of markdown usage. Although its repository is archived and doesn’t accept contributions anymore, it does a pretty good job. It works with both kramdown and redcarpet. We chose redcapet as our processor.

Another useful gem is charlock_holmes. As accurate as Sir Arthur’s character Sherlock Holmes, this gem detects character encoding for given files or chunks of text. Under the hood, charlock_holmes benefits from the set of libraries from ICU.

Database & Storage

We love PostgreSQL! It is reliable, open-source and has lots of functionalities that make it attractive. The ability to create materialized views is one of them.

Working with views in Rails is kind of messy. That’s why we added scenic to the SourceLevel main app. This gem adds methods to ActiveRecord::Migration that allow managing views in migrations.

We use materialized views to scope content. If you don’t know what it is, here it goes: it’s a SQL query whose results work as stored in a regular table. Long-running queries or segmented results can be fetched from appropriate views reducing both time and code complexity.

pghero gem, besides the ability to kill them if you need, also ships with a UI for you to monitor other performance indicators.

Another essential dependency is dalli. It does an incredibly good job of storing and retrieving memcached records. It’s thread-safe and allows us to run Rails.cache smoothly throughout the codebase.

HTTP Requests

SourceLevel integrates with Github in many ways. Our tool can comment in Pull Requests, update build status, listen to interaction events via webhooks, and much more. Instead of creating a lib, we picked octokit to do the job of creating a layer of abstraction. It is a very complete and well-maintained gem.

Besides Github, our main app integrates with other applications, such as Metabase. They required us to develop a simple API Client for each. To do that, we have chosen Faraday because it is straightforward, robust, flexible, testable, widely used, and easy to use.

Development & Test

Our team is adept at TDD. We love the red, green, and refactor cycle. As it has a significant impact on our culture, I point three essential gems that help us daily: guard, minitest , and pry-byebug.

My general workflow is 1) write a test for a non-covered scenario, 2) watch it fail, 3) write the minimum amount of code to make it pass, and 4) refactor. It would be so time-consuming to run all the test suits every time I change a piece of code that probably I give up.

That’s why I like guard that much. This gem can detect and automatically run only the proper test scenarios that a given change affects. With fast feedback, I can move forward in development.

There always be, though, those scenarios we need to investigate what’s going on under the hood. When I need to answer questions like “what’s the value of a variable?”, “does an if statement satisfies its condition?” and “is a method called?” I turn to pry-byebug. There are a lot of articles about this gem out there. I won’t stick to this subject in this blog post.

Finally, another topic I want to address is that we use minitest. Although RSpec is much more accessible, I like the way minitest induces you to keep all test scenarios contained within themselves.

RSpec makes code reuse simple. The bad part is that reusing too much code turns your development more expensive. You tend to spend too much time digging throughout the codebase. Questions like “where this data comes from” and “where did this record change its state?” are often raised while writing tests.

I know, it depends heavily on the developer. It’s not an exclusively tooling problem. But, in my experience, using minitest makes contained tests more natural, even though there is more duplicated code.

I could write an entire book chapter about rspec vs. minitest. For now, I hope I summarized well enough for you to get the overall idea.

In short

I presented some gems we use at SourceLevel. Then I explained what they do and why we chose them. With this blog post, I intended to show a little bit more about the backstage of our product.

I hope you like it!