rails

Stimulus controller for dependent select dropdowns

Dependent dropdowns are a classic UX pattern where one select populates based on another's value. With Stimulus, I handle this entirely client-side after the initial page load by storing options as data attributes or fetching them via AJAX. When the p

Custom confirm dialog with Stimulus (better than window.confirm)

data-turbo-confirm uses the browser confirm dialog, which is functional but not pretty. For a more polished app, I replace it with a Stimulus controller that intercepts clicks, shows a custom modal, and only proceeds if the user confirms. Turbo makes

API documentation with Swagger/OpenAPI

Auto-generated API documentation from code annotations keeps docs in sync with implementation and reduces maintenance burden. The rswag gem generates OpenAPI 3.0 specs from RSpec request specs, providing interactive documentation via Swagger UI. I wri

Keyboard shortcut “command palette” modal (Hotwire-first)

A command palette feels like a SPA feature, but you can do it Hotwire-first: place a turbo_frame_tag 'modal' in the layout and load the palette HTML into it. A small Stimulus controller listens for meta+k and navigates the modal frame to /palette. The

ActiveRecord::Relation as a Boundary (No Arrays)

Return relations from query objects, not arrays. It keeps composition possible (additional filters, pagination, eager loading) and avoids loading huge result sets accidentally.

Use 303 See Other after POST in Turbo flows

After a POST, Turbo behaves best when you redirect with 303 See Other (Rails symbol :see_other). This avoids the browser trying to re-submit the POST when the user refreshes, and it plays nicely with Turbo Drive’s navigation semantics. I use it especi

Transaction-Safe After-Commit Hook (Avoid Ghost Jobs)

Enqueueing jobs inside a transaction can create “ghost jobs” when the transaction rolls back. Use after_commit or after_create_commit to enqueue work only after the DB commit succeeds.

Avoid Callback Chains: Use Domain Events (In-App)

Callback chains become spooky action at a distance. A simple in-app event bus keeps side effects explicit and testable. This isn’t about Kafka—it’s about clarity and seams.

Attach custom headers to Turbo fetch requests (stimulus-free)

Sometimes you need to attach a header to every Turbo request (like a feature-flag variant, or a client version). Turbo emits turbo:before-fetch-request, which lets you mutate the outgoing request before it is sent. I keep the handler tiny and global (

Health check endpoint for deployment monitoring

Load balancers and orchestration platforms like Kubernetes rely on health check endpoints to determine if an application instance is ready to serve traffic. A robust health check doesn't just return 200 OK—it verifies critical dependencies like databa

Audit Trail with JSON Diff (Minimal, Useful)

Auditing isn’t just “save everything”. Capture who did it, what changed, and why. Rails gives you dirty tracking; store diffs in a JSON column. Keep it minimal to avoid ballooning storage.

GraphQL API with graphql-ruby gem

GraphQL provides clients flexibility to request exactly the data they need, reducing over-fetching and under-fetching compared to REST. The graphql-ruby gem integrates GraphQL into Rails with a schema-first approach. I define types for each model, fie