Jul 27, 2026
Rails Concerns: When They Help, When They're a Smell
Concerns are the cheapest abstraction in Rails and the most-abused. The line I draw between concerns earning their file and concerns hiding the pile.
RAILSFULLSTACK · BLOG
Production patterns from real OSS codebases (Gumroad, Mastodon, Discourse, Forem), and a dev's-eye view of the Rails hiring market.
Jul 27, 2026
Concerns are the cheapest abstraction in Rails and the most-abused. The line I draw between concerns earning their file and concerns hiding the pile.
Jul 22, 2026
Turbo 8's two headline features — page-refresh-as-broadcast and morph rendering — let you ship SPA-feeling UX without writing a controller per interaction. What it actually enables, and what's still in flight.
Jul 16, 2026
Rails 8 ships Propshaft as the default asset pipeline. It does dramatically less than Sprockets did — and that's the point. What changed, what migrating looks like, and where the edge cases bite.
Jul 1, 2026
Nine Enumerable methods beyond map and select that I actually use, grouped by intent. The ones that replaced loops in my code.
Jun 30, 2026
Ten Hash methods that show up in my code every week, grouped by intent. The ones I wish I'd known on day one of writing Ruby.
Jun 21, 2026
Discourse runs multi-process Rails on every box. Their DistributedCache pattern keeps a per-process Hash hot and uses MessageBus to invalidate. A walkthrough.
Jun 14, 2026
Mastodon's PostStatusService is what posting a toot looks like at scale. Idempotency keys, distributed Redis locks, scheduled posts. A walkthrough of the patterns I'd steal.
Jun 11, 2026
Strings and integers are fine until they're not. Here's how I introduce value objects to a Rails app — when a PORO is enough, when composed_of fits, and when to reach for money-rails.
Jun 10, 2026
When one model grows a dozen view-shaped methods, you have three options. Here's how I pick between SimpleDelegator, Draper, and plain helpers — and where ViewComponent draws the line.
Jun 4, 2026
Three background job systems, three different bets on storage and ops. The side-by-side I wish someone had given me before my last queue migration.
Jun 3, 2026
A single comment form, no JavaScript, appended to the page on submit. The minimum Turbo Streams setup that actually pays off.
Jun 1, 2026
Rails 8 made SQLite a first-class production database. I think the SQLite-everywhere movement is right about a lot — and wrong about the default.
May 31, 2026
Rails 8 ships a database-backed cache store. I break down where it earns its place over Redis and where Redis is still the right answer.
May 28, 2026
Time.current vs Time.now, Date.current vs Date.today, time zone parsing, and the rule I follow for every timestamp I touch in a Rails app.
May 27, 2026
Forem's ReactionHandler ships a tiny inner Result class that captures everything I want from a service object's return value. Walking through it line by line.
May 24, 2026
When current_user.admin? checks stop scaling, you reach for a policy object. I compare Pundit, Action Policy, and a plain PORO — and the bar each one earns.
May 21, 2026
The four Active Record association loaders, what SQL each generates, and the rule I apply at the keyboard to pick the right one.
May 20, 2026
A short, copy-pasteable walkthrough for swapping in Solid Queue as your Active Job backend, with the dev-mode Puma plugin and a real Job class at the end.
May 18, 2026
37signals' Vanilla Rails essay is mostly right and partially wrong. Here's the line I draw between the apps that prove the point and the ones that disprove it.
May 15, 2026
Rails 8 ships a built-in authentication generator. Here's what it actually produces, and where Devise still earns its place.
May 13, 2026
A line-by-line read of one of the cleanest service objects in Gumroad's open-source codebase, plus the two changes I'd make.
May 13, 2026
A reference card of the Active Record query methods that earn their place in my day-to-day Rails code, with one example each.
May 7, 2026
A presenter is the cheapest abstraction in Rails. Here's the bar I apply before reaching for one — and the bar before reaching past it to ViewComponent.
May 4, 2026
An opinionated take on the query object pattern: the shape that earns its file, the bar I apply, and the scopes that should stay scopes.
May 4, 2026
An opinionated take on form objects, with code from Forem and Mastodon. The bar I apply: a form has to do something the model can't.
May 4, 2026
An opinionated take on service objects, with code from Gumroad and Forem. The bar I apply: a service has to do something a model method can't.