rails

Counter cache for association counts

Computing counts on associations can be expensive when done repeatedly—post.comments.count executes a SELECT COUNT(*) query every time. Counter caches solve this by maintaining a denormalized count column on the parent model that increments/decrements

Rack middleware for request/response processing

Rack middleware processes HTTP requests/responses in Rails' stack. Middleware sits between web server and application, modifying requests before they reach controllers. I build custom middleware for logging, authentication, rate limiting, request modi

Update an error summary area via turbo_stream.update

For forms with multiple fields, I like an error summary at the top. With Turbo Streams, you can update just the summary target when validation fails. This is helpful when the form is long and the user might not see inline errors immediately. The serve

Rails caching strategies for performance

Rails caching dramatically improves performance by avoiding expensive computations and queries. Fragment caching caches view partials. Russian doll caching nests cache fragments for efficient invalidation. Low-level caching stores arbitrary data. Rail

Database Views for Read Models

Some read paths want a denormalized shape without materializing a new table. Postgres views are a clean option. Keep the view definition in a migration and map it with a read-only model.

Server-rendered skeleton UI for slow frames

For slow endpoints, I like a skeleton placeholder rather than a blank area. Turbo Frames make this easy: render a “loading skeleton” inside the frame tag as the initial content, then set src so Turbo fetches the real content. When the response arrives

Turbo-friendly 422 responses for invalid forms

In a Turbo app, returning the right HTTP status is not optional—it controls how Turbo treats the response. For invalid form submissions, return 422 Unprocessable Entity and render the form with errors. If you mistakenly return 200, Turbo may treat it

Character counter for textareas with Stimulus

A character counter is small, but it removes uncertainty for users (especially when there’s a limit). I implement it with Stimulus so it stays reusable: attach to a wrapper, declare input + output targets, and compute remaining characters based on an

RESTful API design with Rails

Rails conventions support RESTful API development. I use resourceful routing for standard CRUD operations. Controllers inherit from ActionController::API for API-only apps. JSON serialization with Jbuilder or Active Model Serializers structures respon

Action Cable for real-time WebSocket communication

Action Cable brings WebSocket support to Rails, enabling real-time features like live notifications, collaborative editing, or chat systems. Clients subscribe to channels that broadcast updates when server-side events occur. I use Redis as the pub/sub

Pagination links that escape a Turbo Frame with _top

Sometimes a frame is great for partial navigation, but sometimes you explicitly want a full-page visit. Pagination is a common case: when the page number changes, I often want the URL to update and the browser history to behave normally. You can tell

Use dom_id everywhere to keep Turbo replacements deterministic

Turbo Stream updates are easiest when every meaningful element has a stable id. Rails’ dom_id helper makes this painless: dom_id(@post) yields post_123, and dom_id(@post, :header) yields header_post_123. I use this pattern throughout Hotwire UIs so I