rails

“Read Your Writes” Consistency: Pin to Primary After POST

With replicas, a user can create a record then immediately not see it due to replication lag. A simple mitigation is to pin subsequent reads to primary for a short window after writes.

“Write Amplification” Guard: Only Update Changed Columns

Avoid writing rows when nothing changed—especially in batch jobs. Check changed? or compute the would-be update and skip if identical. This reduces bloat and autovacuum pressure.

Undo delete with a Turbo Stream “restore” action

Undo is a great UX improvement for destructive actions. My approach is: on destroy, soft-delete the record (or keep enough data to restore), remove it from the list via turbo_stream.remove, and append a toast with an “Undo” link. Clicking “Undo” hits

Normalize Tags at Write Time

Tags are user input, so normalize aggressively: downcase, strip, collapse whitespace, remove duplicates. Doing this at write time keeps search/filter logic clean and avoids messy edge cases.

Lograge-Style JSON Logging Without Extra Gems

Production debugging is about logs that are searchable. Emit JSON with consistent keys (requestid, memberid, duration). Even if you later add Lograge, this structure maps cleanly.

Fragment caching inside Turbo Frames (fast lists)

Hotwire doesn’t replace caching—it makes it more valuable because you’re sending HTML frequently. I use fragment caching inside list partials and keep cache keys stable with cache blocks. The pattern is: cache each row by record, and cache the list wr

Turbo Streams: append server-side validation warnings

Sometimes you want to show non-blocking warnings (e.g., “link looks unreachable”) while still saving. Turbo streams can append warnings to a panel without rerendering the whole page.

Lazy-load heavy panels with IntersectionObserver + Turbo frame

Not every part of a page needs to load immediately. For heavy panels (analytics charts, audit logs), I use a Turbo Frame with src and a tiny Stimulus controller that sets the src when the element becomes visible via IntersectionObserver. This avoids f

Optimistic Locking for Collaborative Edits

If multiple admins edit the same record, use lock_version. Rails will raise on conflicting updates, and you can show a friendly “this changed underneath you” message. It prevents subtle lost updates.

Turbo Streams: update document title with a custom action

Sometimes the DOM updates but the browser tab title stays stale (e.g., unread count, active chat room). A neat Hotwire trick is a custom Turbo Stream action that sets document.title. The server emits a <turbo-stream action='set_title'> with a te

Deterministic Cache Keys for Collections

When caching lists, include inputs that change the list (filters, page, member permissions). A deterministic cache key function prevents subtle “wrong user saw wrong list” bugs.

Infinite scrolling list using lazy Turbo Frames

Turbo Frames can implement infinite scrolling without a JS router. I render the first page normally and append a “next page” frame at the bottom with loading: :lazy. When the user scrolls and the frame enters view, Turbo fetches the next page automati