Speeding up Rails 7's Controller Actions using ActiveRecord's #load_async

Most of the time in a web application, a single API request consists of multiple database queries. For example: class DashboardsController < ApplicationController def dashboard @users = User.some_complex_scope.load_async @products = Product.some_complex_scope.load_async @library_files = LibraryFile.some_complex_scope.load_async end end Quoting snippet from load_async PR description from rails repository. The queries are executed synchronously, which mostly isn’t a huge concern. But, as the database grows larger in size, the response time of requests is getting longer. A significant part of the query time is often just I/O waits.

Everything You Need to know about Serialization in Ruby on Rails - Part III

We had previously talked about the Serialization formats and How Serialization is implemented for storing objects in the relational database in the first two parts of the blog series. This article focuses on the various Serializers that prepare and construct API transferable data in Ruby on Rails.

Rails Parameters Parsing and the Case of Parameters Corruption

Rails is a developer-friendly web application framework that enables developers to do more with less code, but it isn’t always clear exactly what’s going on under the covers. One area where I’ve had a hard time was understanding how Rails parses the Request query parameters and the Form variables. So what's a query parameter? Query parameters are an optional set of key-value pairs that appear after the question mark in the URL. For example, name=contra is a query parameter in https://example.com/over/there?name=contra. And what's a form variable? When we submit a

Rate limiting using Redis in a Rails app

The web is a weird place. You go to sleep thinking that you have a perfectly functional web application and the next day when you wake up, you might find yourself staring at a sudden huge spike in the number of requests. Either your app got popular overnight or you were just a victim of a DOS attack trying to bring your app server down. Usually, it's the latter. There are some popular gems like rack-attack and rack-throttle which work quite well and provides a lot of flexibility. But if you're looking to write your custom logic with minimum dependencies,

Sync files to a remote location using rsync linux command and Ruby

Note: The entire approach highlighted in this blog about using the rsync command with Ruby is only applicable on Linux-based systems and won't be available on Windows. In this article, we will explore how to use rsync in Ruby to sync files from local to a remote location, how to improve its error logging and how rsync is better than scp. Let's first understand what is rsync: rsync is a Linux command to sync files from one location to another. We can run this command on the terminal and it will copy files from one directory to another, either locally

ActiveRecord attribute encryption in Ruby on Rails for better security compliance

Data Encryption has never been so important to modern-day applications as it is today. Storing personal data in plain-text format makes the application open to data theft. Not only users' personal data is at risk, but even the application becomes subject to scrutiny when it falls under General Data Protection Regulation (GDPR) norms. In this blog post, we will explore a quick way to encrypt & decrypt model attributes using Rails handy ActiveSupport::MessageEncryptor class to ensure compliance such as GDPR. Let's start with some basics on PII and GDPR mandates. Personally Identifiable Information (PII) examples as per GDPR PII

How to prevent race condition in Ruby on Rails applications?

Race conditions are always surprising, which can occur in production and are difficult to reproduce. They can cause duplication of records in the database. Most of the time the locking mechanism is taken care of by the Rails framework. Users don't have to manage it; especially optimistic locking using the lock_version column. In case of transactions and race around conditions, we can prevent these issues with Pessimistic Locking in ActiveRecord. It locks a record immediately as soon as the lock is requested(uses database row-level locking). Race conditions happen when two users read and update a record at the

Identifying and Removing Dead Code from a Ruby on Rails Legacy Application

Dead code is code that is never executed. It can be a commented out block of code, a method that's no longer called, or an unreachable return statement. It often reflects functionality that no longer exists. Dead code has absolutely no upside and it costs us money, time, and maintenance headaches. It's possible to identify the unused block of code in smaller projects. But in larger projects, it is not as straightforward. It is a delicate process and requires absolute surety of the deadness status to avoid any unexpected breakdowns. A few tools are present that can aid us in

The Many Faces of Ruby's Top-level

In the previous post, we looked at how Ruby's top-level acts as a wrapper of the Object class. And that the definitions you put in the top-level act as if they were put in the Object class itself. But, there was one thing that I left out in that blog post, because it deserves its own attention. Module extensionIf you have a module: module Foo def bar :bar end endand you extend it in the top-level: extend Fooyou'd expect that it would extend the Object class because of what we saw in that previous post. But you'd be wrong! Object.

Everything You Need to know about Serialization in Ruby on Rails - Part I

It was the day we were moving. I was observing how the "Packers and Movers" professionals packed our furniture. For example, the King size bed shown below had to be accommodated within a space of about 6-7 inches inside a van. While I kept wondering how they'd manage this, they dismantled the bed. And in went the camel through the needle's eye very neatly. That's when I realized the computing world is not very different from the real world. They dismantled the bed for transportation and then reassembled at the destination. Similarly, in the computing world, we deconstruct objects or