rails

System test: asserting Turbo Stream responses

I don’t test Hotwire behavior by guessing; I add system tests that exercise the UI. With Capybara, I click a button that triggers a Turbo Stream response and assert that the DOM changes without a full page reload. The exact assertion depends on the fe

ActiveRecord scopes for reusable query logic

Scopes encapsulate reusable query logic directly in the model, improving code readability and reducing duplication across controllers and services. I use scopes for common filters like active, published, or recent rather than writing raw where clauses

ETags for conditional requests and caching

ETags enable efficient caching by allowing clients to make conditional requests that return 304 Not Modified when content hasn't changed. Rails automatically generates ETags based on response content, and fresh_when or stale? methods handle the condit

Turbo Frames: infinite scroll with lazy-loading frame

Infinite scroll can be done with plain HTML + Turbo Frames. Render a “next page” frame with loading: :lazy so Turbo fetches it when it enters the viewport. No JS required, and it degrades gracefully.

Resilient CSV Export as a Streamed Response

Large CSV exports should not allocate huge strings. Use ActionController::Live to stream rows. Include a heartbeat and handle client disconnects gracefully. This is real-world Rails ops code.

Filter UI that syncs query params via Stimulus (no front-end router)

Filters are better when the URL reflects state. I use a small Stimulus controller that updates the query string as filters change, then triggers a Turbo visit (often with data-turbo-action='replace'). This gives shareable URLs and correct back-button

Shallow Controller, Deep Params: Form Object Pattern

When controllers become parameter jungles, use a form object. It centralizes coercion, validations, and save logic. This pattern is extremely effective for admin panels and multi-step flows.

Remove deleted items instantly with turbo_stream.remove

Destructive actions should feel immediate. For delete links inside a list, I return a Turbo Stream that does turbo_stream.remove dom_id(record). That removes the DOM node without re-rendering the rest of the list, which avoids the common “jump” effect

N+1 query detection with Bullet gem

N+1 queries are the silent performance killer in Rails apps—they're easy to introduce during rapid development and expensive to diagnose in production. The Bullet gem monitors queries during development and test runs, raising alerts when it detects mi

Debounced live search with Stimulus + Turbo Streams

For search-as-you-type, I keep the server in charge and use a small Stimulus controller to debounce form submission. The controller listens to input events, waits ~250ms, then triggers a normal Turbo form submit. The server responds with index.turbo_s

ActionMailer advanced patterns for transactional emails

ActionMailer handles email delivery in Rails. Mailers are similar to controllers—actions generate email content. I use ActionMailer for welcome emails, password resets, notifications. Layouts apply consistent styling across emails. Previews enable vie

ActiveRecord query optimization and N+1 prevention

ActiveRecord provides powerful query interface, but naive usage causes N+1 queries. includes eager loads associations in 2-3 queries. joins performs SQL JOINs for filtering. preload always uses separate queries; eager_load forces LEFT OUTER JOIN. I us