CI Gates, Test Result Caches, and the Code Graph That Might Tell Us What to Test
What I learned from splitting Rails CI by risk, caching exact test results, and exploring whether AI and code graphs can make test selection safer.
What I learned from splitting Rails CI by risk, caching exact test results, and exploring whether AI and code graphs can make test selection safer.
A REX production incident exposed the gap between a successful Kubernetes rollout and a working application, and what we changed to close it.
A practical way for small education and SaaS teams to diagnose Rails or LMS platform friction and decide whether a rewrite is actually justified.
Why a Rails test suite can fail on Ubuntu because of an older native libvips, and how to upgrade it safely without confusing it with the ruby-vips gem.
A practical guide to using Hermes Agent with a local Gemma model for routine coding work, while reserving cloud models for tasks that genuinely need them.
How a moving set of Rails CI flakes exposed shared download state, Selenium stale-node retries, and specs asserting before the browser settled.
A Rails CI debugging story: following the evidence to shared test state, instead of weakening assertions to make failures disappear.
A practical Rails performance field guide for diagnosing CPU, IO, GVL, GC, memory, Puma, and container-runtime bottlenecks before choosing a fix.
A Rails after_save callback silently duplicated database rows: how the symptom appeared, why the obvious suspect was innocent, and the real root cause.
Migrating Rails UJS to Turbo can silently break submit buttons and resets in production, because Turbo's event timing and Promise handling differ from UJS.
How to split Redis into isolated session, cache, and Sidekiq instances so a cache blip never logs users out or stops background jobs.
How to use git worktree to run parallel AI coding sessions safely, with practical patterns for isolating gems, databases, ports, and runtime state.
How I reduced Docker development friction across three Rails apps by removing rebuild-heavy steps, adding runtime dependency sync, and enabling webpack HMR.
A practical comparison of [type, id] versus [id, type] composite index order for polymorphic associations in Rails and MySQL, and how to choose.
A migration path from Webpacker and Yarn to pnpm and Vite in a Rails app, including the dependency, Docker, and asset-hash pitfalls we hit along the way.
This document defines official patterns and anti-patterns for handling transactions, derived data, touch, and async updates in Rails services at my company.
Keeping counters and summaries accurate in Rails without slowing down writes means separating core data in a transaction from derived data updated after commit.
Install PostgreSQL from the PGDG repo on Ubuntu, set up a matching development role, and debug the password authentication failures Rails hits most.
Rails 8's load_async runs association queries concurrently instead of one after another, and getting it right means sizing your connection pool correctly.
A keyword-argument mismatch between Ruby 3.4 and connection_pool 3.x breaks RedisCacheStore at Rails 8.1.1 boot, fixed with a patch loaded before initializers run.
How Puma worker timeouts and Nginx 499 errors expose slow Rails requests, and how to fix them with aligned timeouts, background jobs, and caching.
A flaky RSpec suite traced to a Rake task that commits data outside the per-test transaction, and how DatabaseCleaner's truncation strategy fixes it.
Using application services to build test data couples your specs to that business logic, making test suites slow and fragile; Factory Bot traits fix it.
Active Storage's variant API gets rough past the basic thumbnail case: multiple sizes, per-attachment metadata, and tests that break on file-not-found errors.
User impersonation lets an admin temporarily act as another user for debugging and support, and the pretender gem handles the current_user switch and session state.
A practical breakdown of when to mock external dependencies in Rails tests versus using the real thing, built around the test pyramid, VCR, WebMock, and Pact.
Rails 7's button_to wraps a form around the button instead of rendering a plain input, which silently breaks existing CSS selectors and JavaScript click handlers.
Multi-step Rails forms need somewhere to hold data between steps, and this compares session storage, direct Redis caching, and temporary DB rows for that job.
Rails normalizes headers to HTTP_-prefixed names, which decides whether Accept, a legacy X- prefix, or a plain name is right for a custom API header.
Rails keeps users logged in by encrypting the whole session into a browser cookie, then lets Warden authenticate each request, which changes how you should test it.
How to stop duplicate Rails requests from creating the same record twice, using a Redis-backed semaphore lock instead of chasing a race condition.
How British Summer Time breaks Ruby tests, cron schedules, and cloud functions that assume UTC, and how to write timezone-aware specs instead.
A Rails test suite hung intermittently until transactional tests, ActiveJob, and ActiveStorage turned out to be racing over the same locked rows.
Two concurrent requests can both pass an exists? check and race to insert the same row; here is why, and how to write idempotent Rails controllers.
When async updates to the same record can finish in any order, the oldest write can silently overwrite the newest one; here is how to stop that.
Why ordering ActiveRecord results by an associated table's column breaks with includes, and how references, Arel, and left_joins fix it for good.
How ActiveRecord's includes prevents N+1 queries in Rails, and the common mistakes with order, filtering, and pluck that silently break it.
A framework for deciding how much to test: the testing pyramid, layered test responsibility by architecture tier, and what makes test data good.
How optimistic concurrency, unique job locks, and throttling stop out-of-order background job updates in both Rails/Sidekiq and Laravel queues.
A Rails.cache TypeError on an anonymous module led into Ruby's Marshal restrictions and the relationship between object_id and C-level memory addresses.
A step-by-step guide to migrating a Rails app's pagination from Kaminari to will_paginate, covering models, controllers, views, and API responses.
Why Rails caching raises TypeError: can't dump anonymous module with Kaminari-paginated collections, and how to trace and fix the module causing it.
Running a Ruby on Rails app in Kubernetes means containerizing it correctly and handling migrations, background jobs, and Puma as separate concerns.
Four breaking changes we hit upgrading to Rails 7.2: show_exceptions, array-containment SQL, connection pool locking, and assert_enqueued_email_with.
Caching, the Oj gem, eager loading, background jobs, and load_async each cut serialization time for deeply nested Rails associations like classrooms and scores.
delete_all skips callbacks and dependent associations while destroy_all runs them, and picking the wrong one silently breaks counter caches and cascades.
Console-ready Ruby snippets to inspect Sidekiq queues, scheduled jobs, retry and dead sets, and currently running workers when the dashboard is not enough.
What joins, preload, eager_load, and includes actually do in ActiveRecord, shown with real SQL logs, plus the chained calls that quietly bring the N+1 back.
Practical production debugging techniques for Rails: log analysis, replicating production data, rbtrace live injection, feature-flagged debug modes, and replica apps.
How I traced a Redis memory jump from 130MB to 800MB back to an unthrottled Sidekiq integration, and the maxmemory, eviction, and unique-job fixes that followed.
A collection of .irbrc helpers for tracing method calls, logging SQL queries, profiling code, and inspecting Ruby objects during Rails console debugging.
A comparison of Rails session stores: cookie sessions, ActiveRecord, and Redis, including how to share sessions across subdomains and multiple apps.
A rundown of Rails credentials, environment variables, 1Password CLI, and cloud secret managers like AWS Secrets Manager and Vault, and when to use each.
Why byebug can't break on Devise's metaprogrammed current_user method, and several ways to debug or patch a method that isn't in your source.
How splitting static and dynamic fields, granular fragment caching, and incremental loading keep a large, frequently updated list fast without stale data.
Redis serves two very different roles in a Rails app, a disposable read cache and a durable job queue, and conflating the two causes real outages.
A comparison of Discard and ActsAsParanoid, the two common Rails soft-delete gems, and the query and unscope pitfalls each one introduces.
What Rails actually loads when you run a rake task, the console, the server, or tests, and how to load rake tasks in each environment when you need them.
How ActiveRecord's unscope method selectively removes where and order conditions from default scopes, with examples and alternatives like merge and unscoped.
A comparison of database auditing options, pg_audit, audited, paper_trail, Hibernate Envers, and SQL Server temporal tables, and when each one fits.