rails

Request spec: Turbo Stream template is rendered

For controller-level confidence, I add a request spec that sets Accept: text/vnd.turbo-stream.html and asserts the response includes a turbo stream action. This is faster than a system test and catches accidental template name changes (create.turbo_st

Tabs UI using Turbo Frames (no client router)

Tabs often turn into a mini-SPA. Instead, I treat each tab as a URL and load its content into a turbo_frame_tag named tab_content. Clicking a tab link targets that frame. This gives you browser history, deep linking, and sharable URLs, while keeping t

Declarative model broadcasts with broadcasts_to (Rails 7)

When I’m on Rails 7+, I like broadcasts_to because it makes realtime behavior obvious in the model. Instead of writing explicit after_create_commit hooks, I declare that a model broadcasts to its parent or to a scope. Then Turbo uses conventional part

Stimulus: autofocus the first invalid field after Turbo update

Turbo stream re-renders can drop focus, which is rough for accessibility. Use turbo:render to focus the first invalid field inside a specific container. This feels “native” and reduces user friction.

Turbo Streams fallback to HTML for older clients

Even in a Hotwire-first app, I keep HTML fallbacks because it makes features robust and keeps endpoints usable for bots and scripts. In controllers, I almost always include format.html alongside format.turbo_stream. For example, on create I return tur

Keep DB Connections Healthy in Long Jobs

Long-running jobs can hit stale connections. Wrap work in with_connection and consider verify! before heavy DB usage. This reduces “PG::ConnectionBad” noise during long maintenance tasks.

Transactionally Create Parent + Children with accepts_nested_attributes_for

Nested writes should be transactional: either everything is created or nothing is. Rails does this well when you keep validations coherent and avoid side effects in callbacks.

Stimulus: resilient confirmation for destructive actions

Turbo supports data-turbo-confirm, but sometimes you want a stronger confirmation step (type-to-confirm, extra context, multi-step). Stimulus lets you implement consistent confirmations without sprinkling JS across views.

Turbo Frames: conditional frame navigation for mobile vs desktop

Sometimes you want frame navigation on desktop but full-page navigation on mobile. You can decide the target frame at render time. This keeps UX tuned without duplicating controller actions.

Admin “quick toggle” with Turbo Streams and a single partial

Admin toggles (published/unpublished, featured/unfeatured) are a perfect Hotwire use case: server-rendered state, instant UI update. I render the toggle as a partial inside a frame, and the update action responds with a turbo stream replacing that fra

Turbo Streams: broadcast from a job for long operations

For long operations (imports, conversions), run work in a job and stream progress updates. The job emits broadcast_update_to so the UI updates live without polling.

Defensive Deserialization for ActiveJob

Deploys happen while jobs are in the queue. Be defensive: accept both old and new payload shapes, and keep migrations forward-compatible. This prevents “deploy broke jobs” incidents.