Avoid exceptions for typecasting to integer

There's a method Integer() defined on Kernel, that typecasts everything into an Integer.

Integer("2")  # 2
Integer(nil) # Can't convert nil to Integer (TypeError)
Integer([]) # Can't convert Array into Integer (TypeError)
Integer(Object.new) # Can't convert Object into Integer (TypeError)
Integer(2) # 2
Integer("11", 2) # 3

This is very similar but not identical to to_i:

"2".to_i # 2
nil.to_i # 0
[].to_i # undefined method 'to_i' for an instance of Array (N...

Rails: Redirecting the Logger output temporary aka showing Rails logs in the console

Most of the time, when you are interested in any log output,

  • you see the logs directly on your console
  • or you tail / grep some logfile in a separate terminal window

In rare cases it's helpful to redirect the Logger output temporary to e.g. STDOUT.

Rails.logger = Logger.new(STDOUT)
ActiveRecord::Base.logger = Logger.new(STDOUT)

User.save!
#=> D, [2025-09-08T11:12:26.683106 #1094157] DEBUG -- :   User Load (1.1ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1  [["LIMIT", 1]]

Many frameworks in Rails ...

Improve accessibility with [aria-required] in SimpleForm

SimpleForm comes with an option browser_validations which could be used to give fields that have a presence validation the HTML required attribute. We usually turn it off due to difficulties controlling its behavior and appearance. Instead we only mark required fields with an asterisk (*) next to its label. Blind users probably only discover the validation issue after submitting the form due to the now displayed error messages.

A compromise with better acce...

How to define a table name prefix for all Rails models in a given namespace

ActiveRecord computes table names of model classes, and results are usually just like you'd expect.
Adding a prefix for all classes in a namespace can feel a odd or broken, but does not have to be. It's actually very easy when done right.

Summary (tl;dr)

Here's the short version: Define a table_name_prefix method in the namespace module, and do not define any table_name_prefix in ActiveRecord classes inside of it. If this sounds familiar, we have [a card about using it already](https://makandracards.com/makandra/47198-rails-namespac...

Updated: Testing Accessibility using Orca

As it's quite hard to use a screen reader when you have never done so before, I added a guide on how to visually review the spoken text instead.


Debugging Orca's Output

We can visually review everything the screen reader says by hacking together a real-time transcript of Orca's speech.

To do so, run orca in a CLI window telling it to write a temporary debug log (without Braille to reduce noise)

orca --disable braille --debug-file=/tmp/orca-log.txt

Tip: The screen reader will still be audible. You can reduce its volume ...

Rails: Handling actions that need to happen after all transactions

In Rails 7.2. the feature ActiveRecord.after_all_transactions_commit was added, for code that may run either inside or outside a transaction (we have a special card for nested transactions in general) and needs to perform work after the state changes have been properly persisted. e.g. sending an email.

Example

def publish_article(article)
  article.update(published: true)

  ActiveRecord.after_all_transactions_commit do
    PublishNotification...

Testing for Performance: How to Ensure Your Web Vitals Stay Green

Frontend performance and user experience are orthogonal to feature development. If care is not taken, adding features usually degrades frontend performance over time.

Many years, frontend user experience has been hard to quantify. However, Google has developed some metrics to capture user experience on the web: the Web Vitals. The Core Web Vitals are about "perceived loading speed" (Largest Contentful Paint), reactivity (Interaction to Next Paint) and visual stability (Content Layout Shift).

I have recent...

Simple gem for CLI UIs

If you want to build a small CLI application, that supports more advanced inputs than gets, I recommend using the cli-ui gem. It's a small dependency-free library that provides basic building blocks, like an interactive prompt:

require "cli/ui"

CLI::UI::StdoutRouter.enable

puts CLI::UI.fmt "a small {{red:demo}}"

# supports h, j, k, l, arrows and even filtering
CLI::UI::Prompt.ask("Choose a plan:", options: ["small", "medium", "large"])

or a simple progress bar for long running scrip...

Adding comments to ambiguous database columns

The DB schema is the most important source of truth for your application and should be very self-explanatory. If determining the true meaning of a DB column requires historical research in your issue tracker or reverse engineering of your source code you might consider adding a comment.

Both PostgreSQL and MySQL support comments in the DB schema:

How to: Self-hosted fonts via NPM packages

We usually ship applications that self-host webfonts to comply with GDPR.

Many popular web fonts are available as NPM packages provided by Fontsource.
We recommend using those instead of downloading and bundling font files yourself. (See below for a list of benefits.)

Usage

  1. Go to fontsource.org and search for the font you want to add (or a font that suits your application).
  2. Click the font card to vie...

Better performance insights with gem `rails_performance`

Even if you don't make any beginner mistakes like N+1 queries or missing DB indices, some requests can have bad performance. Without good performance metrics, you probably won't notice this until it's too late.

We investigated multiple gems and found that rails_performance (https://github.com/igorkasyanchuk/rails_performance) provides a lot of valuable information with very little setup cost. It only needs Redis which we use in the majority of our applications anyw...

Using FactoryBot in Development

If you need dummy data to play around with in development, it's often faster to reuse your existing factories instead of using the UI or creating records in the Rails console. This approach saves time and gives you useful defaults and associations right out of the box.

You can use FactoryBot directly in the Rails console like this:

require 'factory_bot_rails' # Not needed if the factory_bot_rails gem is in the :development group
FactoryBot.create(:user)

You can also apply traits or override attributes:

FactoryBot.create...

Web performance snippets: little scripts that return performance metrics

Use these snippets when you want to measure yourself.

Currently available:

Core Web Vitals

Largest Contentful Paint (LCP)
Largest Contentful Paint Sub-Parts (LCP)
Quick BPP (image entropy) check
Cumulative Layout Shift (CLS)

Loading

Time To First Byte
Scripts Loading
Resources hints
Find Above The Fold Lazy Loaded Images
Find non Lazy Loaded Images outside of the viewport
Find render-blocking resources
Image Info
Fonts Preloaded, Loaded, and Used Above The Fold
First And Third Party Script Info
First And Third Party Script Timings
I...

Extracting parts of forms into Unpoly modals/popups

Say you wrap your index view in a form to apply different filters like pagination or a search query. On submit, your index view changes when the filters are applied (through up-submit and up-target). Now you want to enable more data-specific filters using a separate "Filters" button that opens a popup to not overload your UI.

Filter bar:

Filter popup:

The problem is tha...

Fuzzy scoping in Rails with PostgreSQL

When you want to filter records in a model where a string column roughly matches a given term, you can use PostgreSQL’s trigram similarity search.

Writing a fuzzy query in Rails

User.where("similarity(name, ?) > 0.3", "John")

This finds all users where the name is similar to "John" with a similarity score above 0.3.

You can tune the threshold:

  • Closer to 1.0 = stricter match
  • Closer to 0.0 = looser match

Ordering by best match

User
  .where("similarity(name, ?) > 0.3", "John")
  .order(Arel.sql("similarity(n...

Sidekiq: How to check the maximum client Redis database size

You can check the maximum client Redis database size in Sidekiq with this command.

Sidekiq.redis { |redis| puts redis.info.fetch('maxmemory_human') }
#=> 512.00M

If you just want the maximum database size for a known Redis database URL you can use the Redis Ruby client or the Redis CLI:

Redis database size via Ruby client

irb(main):002> Redis.new(url: 'redis://localhost:16380/1').info.fetch('maxmemory_human')
=> "512.00M"

Redis database size via CLI

$ redis-c...

Testing Accessibility using Orca

Orca is a Linux screen reader. Since it is part of the GNOME project it should come preinstalled with Ubuntu installations.

Getting started

To turn on the screen reader you can either go to Settings > Accessibility and then activate Screen Reader in the "Seeing" section or you can simply type orca in your terminal. Alternatively you can use the default keyboard shortcut super + alt + s to toggle the screen reader.

Note

It may feel quite strange in the beginning to use a screen reader. It is constantly commenting on everyth...

Rails: Configuring the default sorting behaviour

In Rails, the implicit_order_column (added in Rails 6) is a configuration option that helps you define the default sorting behavior of ActiveRecord queries when no explicit ORDER BY clause is provided. This option allows you to specify a column that Rails will use to automatically sort records in a particular order when no specific ordering is given.

Since the id is typically the primary key and automatically indexed, Rails will default t...

Rails: Keeping structure.sql stable between developers

Why Rails has multiple schema formats

When you run migrations, Rails will write your current database schema into db/schema.rb. This file allows to reset the database schema without running migrations, by running rails db:schema:load.

The schema.rb DSL can serialize most common schema properties like tables, columns or indexes. It cannot serialize more advanced database features, like views, procedures, triggers or custom ditionaries. In these cases you must switch to a SQL based schema format:

# in application.rb
config.a...

A "text-wrap: balance" fallback approach

Here is a workaround for when you want to use text-wrap: balance but must also render nicely for browsers that don't support it (mostly Safari <17.5).

Step 1: Put some <br>s into your HTML

First, place explicit line breaks that should work for most cases.
This depends on your use case and is affected by e.g. container widths or user content.

<div class="my-element">
  <p>
    Average score
    <br>
 ...

Implementing upload progress and remove button with ActiveStorage DirectUpload

DirectUpload allows you to upload files to your file storage without having to wait for the form to submit. It creates AJAX requests to persist the file within your form and wraps them in a little API. This card will show you how to use it in order to create in-place file uploads with progress and a remove button.

This is basic functionality, you may add additional elements, styles and logic to make this look fancy, but the core functionality is the same. I created a file upload that looks like this:

![Image](/makandra/625023/attachments/3...

Implementing authentication and authorization for ActiveStorage blobs/files

ActiveStorage does not provide any built-in way of implementing authentication for the available DirectUpload endpoint in Rails. When using DirectUpload as JS wrapper in the frontend, be aware that its Rails endpoint is public by default, effectively allowing anyone to upload an unlimited amount of files to your storage.

The DirectUploadController from @rails/activestorage bypasses your form controller because it uploads the file using an AJAX request that runs directly, before any form roundtrip happens. This is a comfortable solutio...

Rails: Using PostgreSQL full-text search without a gem

PostgreSQL can cosplay as a full-text search engine. It doesn't have the features or fidelity of ElasticSearch or Algolia, but it's good enough if you just need to search and rank large volumes of text.

This card will teach you how to index, search and rank your Rails models in a PostgreSQL full-text index. We will do this without using any gems aside from ActiveRecord. While there are gems like pg_search or pg_fulltext, manual integration requires very...

ActiveStorage: How to add a new preprocessed named version

Given there is a user with an attachable avatar:

class User < ApplicationRecord
  has_one_attached :avatar
end

If you want to add a preprocessed version follow these steps:

  1. Add the named version and deploy
class User < ApplicationRecord
  has_one_attached :avatar do |attachable|
    attachable.variant :preview, resize_to_fit: [177, 177 * 9 / 16], preprocessed: true
  end
end
  1. Preprocess this version for all existing records `bundle exec rails runner 'User.find_each { |user| user.avatar.variant(:preview).proc...