I realize I'm a year late to dishing takes on Shogun, but since people keep recommending it, I thought I'd offer my 2¢ on a real problem I have with how it deals with spoken languages (and something I haven't heard anyone talk about anywhere else)
Hi there graceful devs! Here’s what’s new in the garden…
Content Updates
It’s been a couple months since the last newsletter, so we’ve got a few new episodes to list! In case you missed them:

- Safe Navigation Redux: A deep dive into the dos and don’ts of Ruby’s “safe navigation” operator.
- Dependency Injection Isn’t Scary: A lot of digital ink has been spilled about dependency injection over the years, but in the final analysis it’s a big word for quick, small, and very useful tweak to your objects.
- Filter Map in Ruby: A quickie video about not doing a job in two steps when you can do it in one!
Site Improvements
Efforts to give Graceful.Dev a modern, unique, and…

Learn how to seamlessly integrate online presence tracking into a Rails application powered by Hotwire and AnyCable.
If Margaret had a more transparent line of communication, "Are you there?" would have been an unnecessary question, and we'd never have gotten a classic book. Likewise, for application users, looking at the online status indicator should be enough. Now think about your own users: could they be having a similar sense of disconnect? If "yes" is a possible answer here, continue reading to…
CVE-2025-2304 (camaleon_cms): Camaleon CMS Vulnerable to Privilege Escalation through a Mass Assignment
Late last year I sat down and looked at some of this site’s stats. I had loads of articles written that are read by people in the 5-digits every month. Next to that I have a sizeable following on dev.to (+30k) and a solid amount of email subscribers. From all the articles I write, the ones on JavaScript elicit the most questions: “what if I want to do this?”, “how would you fix that?” and so on.
So, after talking about it with a few developer-friends, I pre-announced a book: “JavaScript for Rails Developers”. It was not a completely new idea, I had it jotted down in my ideas-list for a few years already, but now I had a theme of sorts as well: to make JavaScript your second-favorite…
457: Time Zones with Sally Hall
Joël enlists the help of thoughtbot colleague Sally Hall as they dive into the complex world of time zones, daylight savings, measurements and coding.
Together they discuss their struggles with daylight savings throwing off their recent project reporting, the constant struggles of writing for different time zones and why writing your own code is never worth the hassle, and the similar battle of writing for different units of measurement.
—
Check out the idea behind "If Hemingway Wrote Javascript" and how it could help you with your coding.
Watch Tom Scott’s own slow decent into madness over timezones and coding.
Your guest this week has been Sally Hall, and your host for this…
I’m not exactly sure about the timeline, but at some point, gem install sassc
stopped working for me on my Mac (ARM). Initially, I thought this was because that gem was no longer maintained, and the last release was in 2020, but I was wrong. It’s 100% installable today. In this post I’ll explain some things about native extensions libraries in Ruby and in the process tell you how to fix this error below if you’re getting it on your Mac:
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
current directory: /Users/rschneeman/.gem/ruby/3.4.1/gems/sassc-2.4.0/ext
/Users/rschneeman/.rubies/ruby-3.4.1/bin/ruby extconf.rb
creating Makefile
current directory:…
Look at all the things I’m not writing
As leader of a Ruby project, I know I represent that project even here on my personal blog.
With Hanami, we’ve spent the last 10 years building not just a set of tools, but also a community. We’re friendly and inclusive. Our community values are now, and will always be, at the centre of what we do. They are the same values I live.
Our community values
We want you to have a great time in the Hanami community! We welcome people of all backgrounds, genders and experience levels, and respect you all equally.
We do not tolerate nazis, transphobes, racists, or any kind of bigotry. See our code of conduct for more.
So, I invite you to read this blog. Look at all the things I’m not writing!
Addressing it directly
Lost to time in my Code for America email’s sent folder was a list of reasons why deferring to software engineers can be problematic. It included this theme, from Will Larson’s “Building personal and organizational prestige”:
In my experience, engineers confronted with a new problem often leap to creating a system to solve that problem rather than addressing it directly. I’ve found this particularly true when engineers approach a problem domain they don’t yet understand well, including building prestige.
For example, when an organization decides to invest into its engineering brand, the initial plan will often focus on project execution. It’ll include a goal…
Recently, March 16, 2025
- We have promoted another cat to fostering: Merlin, the cat formerly known as Gray Cat.
- I finished the latest Bruno, Chief of Police book. I read it for the food and culture, but it has some bad descriptions of hacking in this one. I started The Midnight Library, which as close as you can imagine to a TED talk but actually a novel. Next is Careless People, which I’m looking forward to; hopefully as exhilarating/vicariously-traumatic as Exit Interview.
- At work the latest is that all planning must snap to 1-month objectives. “If you don’t produce a plan, someone will produce one for you” is an advice. Super proud of the work: doing Pitchfork, kicking the tires on
…
Week 11 - Real-time Sync with Hotwire, Hotwire Native Bridge Components Collection, and more!

Welcome to Hotwire Weekly!
Welcome to another issue of Hotwire Weekly! Happy reading! 🚀✨
📚 Articles, Tutorials, and Videos
📝 Articles
Hotwire and That Syncing Feeling - Louis Antonopoulos describes how Thoughtbot built a synchronized multi-device presentation system using Hotwire. With real-time slide syncing across 30+ devices, they used broadcasts_refreshes
in the model and turbo_stream_from
in views to ensure smooth updates.
Using the Keyboard with Stimulus - Rails Designer discusses how to enhance user experience by integrating keyboard interactions into Stimulus controllers.
Why choose Hotwire Native? - Jesse Waites discusses the advantages of using Hotwire Native for mobile…
Exploiting LLM tools
Yesterday, I saw a post on Hackernews about the ruby_llm gem. The thread had a lost of positive comment about the beauty of Ruby’s syntax and I made a tweet about it. Then Daniel Westendorf replied to me, pointing out that the examples in the gem’s Readme use eval. This is what that particular example was:
Direct link to podcast audio file
I hope you ordered your podcast spicy, because this version is a slow heat, but it builds. I was pretty fired up by the end of this one. If I crossed a line here, please report it to HR at podcast@searls.co and they will conduct an investigation.
Video of this edition of the show is up on YouTube.
I tossed this bouquet of URLs in the air but no one caught them:

Finally, after years of Heroku, Render and fly.io, you make the switch to self-hosting. You use Kamal to save some dollars and avoid the usual pain of self-hosting. You hit good timing because Kamal has matured.
Here's a fully working and continuously supported setup of Rails with Kamal that you can use to learn how to make all the parts work together. It's continuously supported because it is offered as an option in the Bullet Train Rails starter template. This Kamal setup also powers the (upcoming) related open source app.socialgames.cc SaaS.
In this guide, I'll show you two ways of setting up Kamal:
- For a completely new Bullet Train app.
- For an existing (Bullet Train) app.
But you should be…
Git Rebase Fixup

One of the best aspects of a Git Rebase workflow is being able to quickly fix any/all mistakes within the feature branch you are working on. This reduces the amount of commits made, cleans up your implementation, and keeps your Git history clean. Having a clean history is important for professional engineering.
In truth, you will probably make mistakes along the way, because to error is human, but what’s important is that you cleaned up those mistakes. This not only makes Code Reviews more enjoyable but leaves behind an impressive legacy of work that others can learn and level up from.
Now that you know why fixing your commits are important, let’s learn how to fix…
Feedback Is Literally A Gift
Feedback is a gift.
Some gifts are little treats for you to consume. Think of a box of chocolates. You enjoy them and then they’re gone, but you remember the thought that was put into them.
Sometimes gifts are utilitarian, like getting socks for Christmas. They are not the most exciting thing to receive, but you kind of need them as part of your normal day-to-day life, and you’ll get use out of them.
Validating password strength
A pull request on Rails and Devise triggered me to write this blogpost.
Hi, it’s Claudio Baccigalupo. Let’s explore this week’s changes in the Rails codebase.
Structured CI with bin/ci
Introduce bin/ci
to standardize CI workflows based on a new DSL for declaring workflow steps in config/ci.rb
.
bin/ci
runs your all tests, linters, and security scanners. And it optionally signs off on your work by giving your PR a green status.
Don’t always append primary keys to ORDER conditions
If nil
is the last element of an array passed to implicit_order_column
, do not append the primary key or the query constraints.
Raise DoubleRenderError
on head
after rendering
Previously, calling head
to set the response code would silently remove a previously set response body.
👀 Note
Editor’s note: Adam first drafted and published this article on Sidekiq’s own Wiki after chatting with Mike Perham about the value of adding docs to Sidekiq specifying guidance around actually scaling Sidekiq once it’s running in production. We wanted to bring a version of that article here to our own blog and have updated several sections to reflect the year of development and changes since Adam first wrote that page… time flies!
Sidekiq’s architecture makes it easy to scale up to thousands of jobs per second and millions of jobs per day. Scaling Sidekiq can simply be a matter of “adding more servers”, but how do you optimize each server, how “big”…
You might have seen @byroot’s excellent blog post series on optimizing the json
gem.
From the first blog post it’s clear most of the time for generating JSON is spent in generate_json_string()
and specifically in convert_UTF8_to_JSON()
, i.e., in converting Ruby Strings to JSON Strings.
Because this is such a hot part of JSON generation, it has received a lot of attention.
In part 3 @byroot shows a lookup table approach to implement convert_UTF8_to_JSON()
, which is now used in the json
gem.
There has been a couple attempts since then to optimize it further using SIMD instructions. This is however quite difficult and messy to do in C as it’s similar to writing inline assembly (N times,…
You might have seen @byroot’s excellent blog post series on optimizing the json
gem.
From the first blog post it’s clear most of the time for generating JSON is spent in generate_json_string()
and specifically in convert_UTF8_to_JSON()
, i.e., in converting Ruby Strings to JSON Strings.
Because this is such a hot part of JSON generation, it has received a lot of attention.
In part 3 @byroot shows a lookup table approach to implement convert_UTF8_to_JSON()
, which is now used in the json
gem.
There has been a couple attempts since then to optimize it further using SIMD instructions. This is however quite difficult and messy to do in C as it’s similar to writing inline assembly (N times,…
Debugging is a crucial skill for any Ruby developer. And as the tools and techniques evolve, it’s important to keep up-to-date with the latest best practices.
So here are some of my Ruby debugging tips and recommendations that I’d offer to Ruby developers in 2025.
- You can use the Ruby LSP extension to connect to debug.gem too.
It requires a slightly different
launch.json
configuration (example) and provides better error handling for connection issues. -
Try using
launch
request inlaunch.json
instead ofattach
. It simplifies the debugging process as you don’t need to manually start/stop the server. In most Rails projects, a simple entry like this will do:{ "version": "0.2.…
- The effectiveness of your debugging session…
Finding the opposite of what you have with rails invert_where
Rails 7 introduced invert_where
. This method inverts all scope conditions that it’s applied to, simplifying the process of defining the opposite of a where
clause in ActiveRecord queries. It also comes with a few caveats that should be considered before using it.
What is invert_where
?
invert_where
is a Rails method that can fetch all the data that is excluded by an existing query.
Let’s take this example: finding recent claims that have been raised on completed orders and have an amount of less than £100.
recent_claims = Claim.joins(:order)
.where(orders: { status: "completed" })
.where("claims.created_at >= ?", 10.days.ago)
.whe…
If you want to query data opposite to the query condition, you would need to…
Benji Edwards for Ars Technica:
According to a bug report on Cursor's official forum, after producing approximately 750 to 800 lines of code (what the user calls "locs"), the AI assistant halted work and delivered a refusal message: "I cannot generate code for you, as that would be completing your work. The code appears to be handling skid mark fade effects in a racing game, but you should develop the logic yourself. This ensures you understand the system and can maintain it properly."
The user wasn't having it:
"Not sure if LLMs know what they are for (lol), but doesn't matter as much as a fact that I can't go through 800 locs," the developer wrote. "Anyone had similar issue? It's really…
Flash Sale! 🔗
We’re offering our best deals on select products for a limited time. We’re going to link to this flash sale from many different pages on our site. The call-to-action (CTA) we display at the top of the flash sale page will change based on which page you access the flash sale from.
We’re going to store that text in a flash message. For example, let’s say you’re looking for the contact information for everyone at the shop. If you click a link on that page to visit the flash sale, we reference that you were just on the contact page.
class ContactsController < ApplicationController def index if FlashSale.on? flash[:sale] = "Thanks to you for looking to contact us" end endend
Keep in…
Stripes Subscription Challenges
In this episode, Chris and Andrew navigate scheduling mishaps, discuss the quirks of time zones, and dive deep into their transition from asdf to mise for managing development environments. They explore the benefits of mise tasks, automation, and encrypted environment variables. Chris shares the challenges of migrating Hatchbox without disrupting deployments, while Andrew tackles Stripe billing complexities, including webhook race conditions and subscription management issues. The episode wraps up with mentions of upcoming travels for conferences, personal coding projects, and some chat about playing Cyberpunk 2077. Hit the download button now!
Panelists:
- Chris Oliver
- Andrew Mason
Sponsor:
What is JSON-LD?
JSON-LD stands for JavaScript Object Notation for Linked Data. One use is adding it to web pages, allowing search engines or crawlers to understand the content structure and context better.
It is usually added in the <head>
html element like this:
<script type="application/ld+json">{ "@context": "https://schema.org", "@type": "WebSite", "url": "http://example.com/"}</script>
Why use JSON-LD Schema in your blog
Your content may show up as rich snippets in search results.
Helps search engines to understand the data related to…

There's an expression in English that says, "You can't see the forest for the trees." It means you are too focused on the details and not seeing the big picture.
In software engineering, my experience tells me that we actually have the opposite problem. We see the big picture abstraction while overlooking the details. We can't see the trees for the forest!
Here's what I mean. My teams host office hours several times a week. Engineers from other teams bring code to office hours for feedback and advice. Quite frequently, folks bring us solutions to problems they don't have. Or rather, they bring general purpose code that has exactly one use case in the application.
In other words, we (and I use…
Who the fuck knows what a "globular cluster" is, but the Globular Cluster CMA1 is my new recommendation for Best Way to Wear Vision Pro. It replaces a lightly-modified BOBOVR M2 as the reining champ, primarily due to the fact it's a thing you can just buy on Amazon and slap on your face. It's slightly lighter, too. One downside: it places a wee bit more weight up front. I genuinely forget I'm wearing the BOBOVR M2 and I never quite forget I'm wearing this one.
Here's a picture. You can't tell, but I'm actually winking at you.

Also pictured, I've started wearing a cycling skull cap when I work with Vision Pro to prevent…
3.6.6 Released
RubyGems 3.6.6 includes enhancements and bug fixes.
To update to the latest RubyGems you can run:
gem update --system
To install RubyGems by hand see the Download RubyGems page.
## Enhancements:
- Update vendored uri to 1.0.3. Pull request #8534 by hsbt
- Installs bundler 2.6.6 as a default gem.
## Bug fixes:
- Fix
gem rdoc
not working with newer versions of rdoc when not installed as default gems. Pull request #8549 by deivid-rodriguez
SHA256 Checksums:
- rubygems-3.6.6.tgz
b4642fe16598fb93d40d6bcde9f69250debc0f13238cad410a7505c0cf740dad - rubygems-3.6.6.zip
d84d4146cb98a4b51b5401bd940192e8bd7804419726d736bc624ce20d83553f - rubygems-update-3.6.6.gem
e3004ad1ebcd52481ed5f6702…
CVE-2025-25291 (ruby-saml): Ruby SAML allows a SAML authentication bypass due to DOCTYPE handling (parser differential)
CVE-2025-25292 (ruby-saml): Ruby SAML allows a SAML authentication bypass due to namespace handling (parser differential)
CVE-2025-25293 (ruby-saml): Ruby SAML allows remote Denial of Service (DoS) with compressed SAML responses
CVE-2025-27407 (graphql): graphql allows remote code execution when loading a crafted GraphQL schema
Implementing Kubernetes pod exec in ruby
Recently I submitted a PR which just got merged, for k8s-ruby, a ruby client for the Kubernetes API, to implement the Pod#Create Connect Exec endpoint, which allows to execute arbitrary commands inside a pod container, including opening a shell session.
Eventually It wasn’t that hard to make it work but there were some interesting learnings along the way:
Sidekiq 8.0
#742 — March 13, 2025
Ruby Weekly

Introducing Sidekiq 8.0 — Ruby’s most popular background job framework has a new release that adds easy-to-do profiling, a significant overhaul to its WebUI, a new ‘job iteration’ feature for dividing long running jobs into smaller chunks, and more. Redis 7+ and Ruby 3.2+ are now required.
Mike Perham
💡 This is also a great opportunity to revisit How Does Sidekiq Work? from a year ago.
Better Know a Ruby Thing: Method Lookup — “Let’s talk about method lookup in Ruby, which is from one perspective really clean and simple, and from another angle, kind…
Noel Rappin

🎨 Enhancing the Trix Rich Text Editor in Ruby on Rails 8: A Custom Touch for a Better Experience!
March 13, 2025 Hey there, Rails enthusiasts! I recently dove into customizing the Trix Rich Text Editor on a Ruby on Rails 8 project, and I wanted to share my journey with you all. Whether you're a seasoned Rails developer or just starting out, customizing your text editor can add a personal touch to … Continue reading
Enhancing the Trix Rich Text Editor in Ruby on Rails 8: A Custom Touch for a Better Experience!
Using the Keyboard with Stimulus
Giving your users the option to use the keyboard is a great way to make them happy campers. Common use cases are Escape to close a modal or dropdown and Command/Ctrl + Enter to submit a form.
Stimulus gives you the option to add this feature with ease. They are called KeyboardEvent Filters in the Stimulus docs.
How to use KeyboardEvent Filter
You can prepend any action with a different event (click, mouseover and keydown). Keydown also allows to add any keyboard key. Like so:
<div data-controller="dropdown" data-action="keydown.esc->dropdown#close" tabindex="0"></div>
Keep in mind that the focus needs to be on the given element. In above example tabindex=0
makes the element focusable.
Recently, I had to implement a multi-screen slide deck presentation system that stayed in sync with the presenter’s view.
How did I get there?
Requirements
Render three views: the group view, the individual view, and the presenter view.
- The group view should show a fullscreen view of a slide, including group content such as a video
- The individual view should show a fullscreen view of a slide with the option to take actions such as filling out a form, but should hide group content
- The presenter view should show a “preview” of the previous, current, and next slides
- The presenter view can navigate forward, backward, or jump to any slide
and most importantly, all views have to…
Existence of the imminent Oblivion remake was leaked months ago, and maybe I just missed this tidbit, but today Andy Robinson reported for Video Games Chronicle:
The Oblivion remake is reportedly “fully remade” with Unreal Engine 5, with six reworked gameplay systems: stamina, sneaking, blocking, archery, hit reaction and HUD.
If this is the case and because Elder Scrolls VI is still being developed on the Gamebryo/Creation Engine, I can't wait to see a side-by-side analysis of image quality, performance, and overall "Bethesda jank" between the two. I've been saying Bethesda needs to ditch its in-house engine since two-thousand-fucking-eight when Fallout 3 shipped broken and required years…
Joe Rossignol at MacRumors:
Apple says turning on Low Power Mode reduces the Mac Studio's fan noise, which is useful for tasks that require a quieter environment, and it also allows for reduced power consumption if the computer is left running continuously.
The reduced fan noise aspect of Low Power Mode requires macOS Sequoia 15.1 or later. The new Mac Studio ships with macOS Sequoia 15.3.
A few Reddit users said macOS Sequoia 15.3 enabled Low Power Mode on the previous-generation Mac Studio with the M2 Max chip, and presumably on M2 Ultra configurations too. This is not reflected in Apple's support document.
I can confirm, a "Low Power Mode" toggle appears in the Energy settings of my M2…

With 20+ years and millions of downloads, Andrey Sitnik shares his guide on how to make your open source project popular.
I've been in open source for 20+ years and I've created quite a few popular projects (with millions of downloads per month.) So what's the secret? This is the guide you've been waiting for: how to make your open source popular, the right way. Does ”good idea” = ”popular project”? Here's a hint: much of the open source dream is a total lie.
Hi everyone,
I am happy to announce that Rails 8.0.2 has been released.
CHANGES since 8.0.1
To see a summary of changes, please read the release on GitHub:
8.0.2 CHANGELOG To view the changes for each gem, please read the changelogs on GitHub:
- Action Cable CHANGELOG
- Action Mailbox CHANGELOG
- Action Mailer CHANGELOG
- Action Pack CHANGELOG
- Action Text CHANGELOG
- Action View CHANGELOG
- Active Job CHANGELOG
- Active Model CHANGELOG
- Active Record CHANGELOG
- Active Storage CHANGELOG
- Active Support CHANGELOG
- Railties CHANGELOG
Full listing
To see the full list of changes, check out all the commits on GitHub.
SHA-256
If you’d like to verify that your gem is the same as…

Perhaps this is partly because the Japanese Internet continues to be needlessly opaque (it has now been zero days since I encountered a UI built around HTML image maps), but ChatGPT has become an indispensable planning partner whenever Google would normally let me down. In the case above, I just typed "search for Indigo La End concerts in Japan this June", and it got me back only the June dates of a tour I didn't know was going on, and for which tickets only went on sale two days ago. From there it was literally two more clicks to be where I needed to be in order to buy a paper ticket I could pick up at any 7-Eleven nationwide.
These days, whenever a traditional Google-oriented search…
Migrating to TanStack Query v5
TanStack Query is a powerful data-fetchingand state management library. Since the release of TanStack Query v5, manydevelopers upgrading to the new version have faced challenges in migrating theirexisting functionality. While the official documentation covers all the details,it can be overwhelming, making it easy to miss important updates.
In this blog, well explain the main updates in TanStack Query v5 and show howto make the switch smoothly.
For a complete list of changes, check out theTanStack Query v5 Migration Guide.
Simplified Function Signatures
In previous versions of React Query, functions like useQuery
and useMutation
had multiple type overloads. This not only made type maintenance…
EBS StorageClass with VolumeBindingMode Immediate is incompatible with pod topology pinning
We ran into a weird pod scheduling error on Amazon Elastic Kubernetes Service (EKS). Some pods, which scheduled just fine in the past, now stay in Pending with the following event:
Failed to schedule pod, incompatible with nodepool "default", daemonset overhead={"cpu": "300m", "memory": "2096Mi", "pods": "7"}, incompatible requirements, key nodepool, nodepool In [static] not in nodepool In [default]; key topology.kubernetes.io/zone, topology.kubernetes.1o/zone DoesNotExist not in topology.kubernetes.io/zone In [eu-west-la eu-west-1b eu-west-1c]; incompatible with nodepool "static", daemonset overhead={"cpu": "300m", "memory": "2096Mi", "pods": "7"}, incompatible requirements, key…

Overview
Let’s talk Single Sign On (SSO) — a feature most of us have encountered. You know that “Sign in with Google” button you see when signing up for websites? One click, and you’re in — no need to create yet another password you’ll forget by next week. It feels like magic!
There are two key terms you need to understand: the service provider and the identity provider. The service provider is the website or application you want to access using SSO. Common examples for engineers in a company are AWS and Datadog. An identity provider is the service that manages a company’s user identity information, granting access to various…
March 10, 2025 Artificial Intelligence is revolutionizing the way we interact with text, and DeepSeek provides a powerful API to harness its capabilities. Whether you're looking to correct grammar, generate poetry, or build AI-powered applications, this guide will show you how to integrate DeepSeek into your Ruby projects seamlessly. Want to Incorporate AI into … Continue reading Integrating DeepSeek API with Ruby
Introducing Sidekiq 8.0
After six months of hard work, I’m thrilled to announce the general availability of Sidekiq 8.0! 🥳🎉
Status
Sidekiq is used by thousands of Ruby applications around the world to scale job processing up to billions of jobs/day. Current Sidekiq Enterprise customers are reporting a grand total of 1,806,671,058,604 jobs processed, almost two trillion, with my largest customer executing up to 250,000 jobs/sec. Got a Ruby/Rails app and want to try out Sidekiq? See Test Drive to get started quickly.
It’s been 5 years since the start of the COVID-19 pandemic. From my notebook, I found a brief presentation I gave at Code for America in April, 2020 about that first month of the pandemic and the positive impact that GetCalFresh had during the initial lockdown and economic turmoil. There’s a contemporary postscript at the end too.
The idea of flattening the curve is to create time and space to build up the system capacity and avoid a catastrophic failure leading to greater social disruption and deaths.
Within the social safety net, like the healthcare system, there is a limited systemic capacity to help people. Within the social safety net, catastrophic failure is…

HTTP is a request response protocol. The browser (client) sends an HTTP request to the server (Rails application), which parses that request and generates the HTTP response, typically an HTML page, and sends it to the browser. The browser then renders that HTML on the screen.
In the previous post on requests in Rails, we learned how you can work with the request object to access meaningful information on the incoming HTTP request. In this post, we'll take a look at how you can work with the outgoing response. While it’s less common to handle responses directly—since Rails manages most of that for you—there are situations where…
Hugo Update
I try to do the bare minimum of development work on this actual site. That way my time spent here is on actually blogging. That’s why I chose hugo over something like Bridgetown. By intentionally choosing a static site generator written in a language I’m less familiar with, I’m less likely to tinker.
Due to a tragedy with a git submodule this morning (that is…deleting it), I ran into an issue where my custom deploy script would no longer deploy. Attempts to reconfigure the submodule were not responsive. I’m sure I could have figured it out, but…I didn’t want to.
I found there is a more modern deployment story with Hugo now that is in their documentation - using GitHub Actions! I wanted to use…
When we work with user input, we want to sanitaize the data shared by user. Sometimes we want to format the data before saving it to the database(eg: downcase emails).
Normalization allows us to keep the data clean, consistent and predictable. We can format the data before saving it to the database or further processing.
For example, imagine a user signing up with JohnDoe@GMAIL.com
and another with johndoe@gmail.com
. Without downcasing these emails, even though they’re the same but system treats them as different emails. We can normalize the email format before saving it to the database.
Before
Rails 7.1 introduced ActiveRecord::Base::Normalization
, we can specify unique normalization…
Frequently Played 🔗
I tend to listen to the same songs or albums on repeat that are evocative of how I’m feeling or what’s going on with me. Here is what I’m currently listening to over, and over, and over, and over, again.
Happy 🔗
Happy. Really happy?
I’ll be the first to admit that I’m a lonely soul
And the last to admit I need a hand to hold
Losin’ hope, headed down a dangerous road
Happy Now 🔗
Most of the Tragic Kingdom album still hits pretty well.
The uncertainty you had of me
Brought clouded, shady company
The tenderness habitual
A seldom-fading ritual
If you are building AI-powered applications in Ruby on Rails, you might have come across Informers or Transformers.rb gems for transformer inference. Here’s how to improve the production deployment of their models in Kamal setups.
Informers & Transformers.rb
Informers and Transformers.rb are excellent gems for creating document embeddings. These embeddings can then be used to search your documents, build chatbots, and more.
Here’s an example from the README:
sentences = ["This is an example sentence", "Each sentence is converted"]
model = Informers.pipeline("embedding", "sentence-transformers/all-MiniLM-L6-v2")
embeddings = model.(sentences)
As you can see, you can directly pass a…
On March 9, 2025, many Chromecast 2nd generation and Chromecast Audio devices suddenly stopped working. Users like me could not cast content or set up their devices. This wasn't due to a software update or planned obsolescence, but most likely an expired device authentication certificate.
Disclaimer
USE THESE WORKAROUNDS AT YOUR OWN RISK
The information provided in this article is intended for educational purposes only. I am not affiliated with Google, and these workarounds have not been officially endorsed by Google or the manufacturers of your devices.
By following any instructions in this article:
- You acknowledge that you are modifying system settings beyond their intended use
- You…
Testing OmniAuth authentication
One of RSpec’s strengths is the legibility of its behavior-based DSL. The other side of this coin is that the proliferation of small example blocks introduces a performance overhead. Why? Because of RSpec test files’ lifecycle! I’ll describe broadly how RSpec handles a test file, and the performance implications. Then, we’ll see how we can make your RSpec tests run faster!
This is an intermediate-level post. If you’re unfamiliar with RSpec, start at the beginning of the series.
A typical test file
Let’s draw a quick books_controller_spec.rb
that checks the behavior of a PATCH
action.
RSpec.describe BooksController do
let(:book) do
Book.create(title: "The Long Way to a Small,…
Week 10 - Turbo Frames Loading Spinners, when to use Rails views, and more!

Welcome to Hotwire Weekly!
Welcome to another issue of Hotwire Weekly! Happy reading! 🚀✨
📚 Articles, Tutorials, and Videos
📝 Articles
Hotwire Turbo Frames: Add Seamless Loading Spinners in Rails - Nicolás Galdámez demonstrates how to enhance the user experience in Rails applications by adding loading spinners to Turbo Frames using CSS by leveraging the busy
attribute.
Build a Notion-like editor with Rails, part 2 - Rails Designer published a second article and continues the development of a Notion-like editor in Rails by enhancing the user interface with Tailwind CSS and improving functionality using Stimulus. The previous article can be found here.
Notes and Corrections
Before we get fully started here, a couple of notes on Better Know Singleton Classes, which, among other things, got mentioned on Hacker News, giving me comments there for the first time in years, maybe for the first time ever.
One Hacker News comment suggested that “Eigenclass” was coined by _why the lucky stiff as a joke and was then adopted by the community. I looked this up and that doesn’t seem to be the case… _why’s Poignant Guide To Ruby uses “metaclass” when it discusses this feature (at least the version I have does…). Matz used “eigenclass” in the O’Reilly Ruby book. (You didn’t ask, but version 1 of the Pickaxe uses “singleton class”, per https://ruby-doc.co…

It surprises me sometimes that a lot of devs are still not very bullish on coding with an LLM, so here is a little summary from a Rails dev in the middle of the usage spectrum about what I'm using the LLMs for and what my current toolset is.
A year ago, I made the funny mistake of buying GitHub Copilot for a year because it seemed like the best solution for JetBrains at the time. It's "funny" and a mistake because the landscape changes so fast that I think experimentation is essential for the years to come. Let me chat for a bit about all the tools I use so I can laugh about it again in a year or so.
My best prediction is that the whole midterm future of the "AI coding thing" is us…
From annotating to dataset managment to prompt versioning to analyzing eval results over time, there are a lot of moving parts and it can be very confusing for anyone to wrap their head around how to think about it, what tools to use, how to integrate them, etc. Hence I keep reading about…
📂 Store Your Ruby-Generated Files on Google Drive Effortlessly!
March 7, 2025 Integrating Google Drive API with Ruby seemed straightforward—until it wasn’t. From cryptic exceptions to OAuth nightmares, I hit some tricky roadblocks. Here’s how I debugged my way to success and what I learned along the way. Need a Smarter Way to Store Files on Google Drive? If you’re looking to enhance … Continue reading
Store Your Ruby-Generated Files on Google Drive Effortlessly!
Standards for ANSI escape codes
Hello! Today I want to talk about ANSI escape codes.
For a long time I was vaguely aware of ANSI escape codes (“that’s how you make text red in the terminal and stuff”) but I had no real understanding of where they were supposed to be defined or whether or not there were standards for them. I just had a kind of vague “there be dragons” feeling around them. While learning about the terminal this year, I’ve learned that:
- ANSI escape codes are responsible for a lot of usability improvements in the terminal (did you know there’s a way to copy to your system clipboard when SSHed into a remote machine?? It’s an escape code called OSC 52!)
- They aren’t completely standardized, and because of that…
So I wanted to put together a list for myself of some standards that exist around…

HTTP is a request-response based protocol. The browser (acting as the client) sends an HTTP request to the server (your Rails application). The server then parses the request, processes it, and generates an HTTP response, which is sent back to the browser. Each request carries a bunch of useful information that your application frequently relies on to handle the request properly.
Rails offers a simple and straightforward interface to work with the current HTTP request hitting your application. It…
So you’re firing up a new Rails application and you’ve chosen Heroku as your preferred hosting solution. First, congrats! Taking a new app to production is exciting and one of the best times of a developer’s application-cycle. Our little team of two-and-a-half senior Rails devs here at Judoscale (including a Rails core team member!) still love that “hello, world!” moment ☺️. And we still totally endorse Heroku as being the simplest, easiest, and most straightforward way to bring a Rails application to production. This is the way!
We’ve kicked around the idea of putting together a wide list of recommendations for various architectures, configurations, and setups for a Rails app on…
Figuring out where and how to host your app can be scary! One thing that may bring you stress sooner or later is the thought of migrating from one provider to another. If migration is easy, choosing a host becomes a reversible decision rather than a permanent commitment. In this guide, we’ll explore how to keep your infrastructure flexible so you can take advantage of the best features, reliability, and pricing that various PaaS providers offer – without getting trapped by PaaS lock-in.
First, we’ll first look at why you might want to switch PaaS providers and how much difference it can make. Then we’ll dive into specific strategies to avoid lock-in, from using external databases…
Hi, it’s Greg. Let’s explore this week’s changes in the Rails codebase.
Rails World 2025 Call for Papers
The CFP for Rails World 2025 is now live! Submit your talk until April 10th: https://rubyonrails.org/2025/3/7/apply-to-speak-at-rails-world-2025.
Add a default bin/bundle-audit configuration
This pull request adds bin/bundler-audit
and config/bundler-audit.yml
for discovering and managing known security problems with app gems.
Permit modern Ruby syntax in new apps
This pull requests changes RuboCop to target the Ruby version you’re using rather than the 2.7 default.
Stop generating bundler binstub:
Rails no longer generates a bin/bundle
binstub when creating new applications.
The bin…
On March 9, 2015, Apple announced a redesigned MacBook, notable for a few incredible things:
- 2 pounds (the lightest computer Apple currently sells is 35% heavier at 2.7 pounds)
- 13.1mm thin
- A 12-inch retina screen (something the MacBook Air wouldn't receive until late 2018)
- The Force Touch trackpad (which came to the MacBook Pro line the same day)
It also became infamous for a few less-than-incredible things:
- A single port for charging and data transfer, heralding the dawn of the Dongle Era
- That port was USB-C, which most people hadn't even heard of, and which approximately zero devices supported
- A woefully-underpowered 5-watt TDP Intel chip
- The inadvisably-thin butterfly keyboard, which…
Still, the 2015 MacBook (and the 2016 and 2017 revisions Apple would go on to release) was,…
EBS StorageClass with VolumeBindingMode Immediate is incompatible with pod topology pinning
We ran into a weird pod scheduling error on Amazon Elastic Kubernetes Service (EKS). Some pods, which scheduled just fine in the past, now stay in Pending with the following event:
Failed to schedule pod, incompatible with nodepool "default", daemonset overhead={"cpu": "300m", "memory": "2096Mi", "pods": "7"}, incompatible requirements, key nodepool, nodepool In [static] not in nodepool In [default]; key topology.kubernetes.io/zone, topology.kubernetes.1o/zone DoesNotExist not in topology.kubernetes.io/zone In [eu-west-la eu-west-1b eu-west-1c]; incompatible with nodepool "static", daemonset overhead={"cpu": "300m", "memory": "2096Mi", "pods": "7"}, incompatible requirements, key…
Advanced Package Management, PostgresSQL, and Mise
In this episode, Chris and Andrew start out talking about personal milestones and upcoming birthdays. The conversation then moves to technical issues faced with PostgreSQL configurations on Hatchbox. They delve into the functionality and challenges of different tools such as Asdf and its alternatives like Mise, a tool for managing programming environments, and the evolving role of AI in coding environments. They also explore Warp’s new terminal features and Chris’s work on the ‘Learning Hotwire’ course. Hit download now to hear more!
HoneybadgerHoneybadger is an application health monitoring tool built by developers for developers.
Disclaimer: This post contains affiliate links. If you make…
Is your Rails application special?
TL;DR
Legacy Rails applications can be unpredictable, so never assume anything about their behavior. The first step to stability is improving observability—understand how the system behaves before making changes. Identify bottlenecks using real data, optimize critical configurations, and ensure fast deployment rollback in case something goes wrong. Even small adjustments, like tuning concurrency settings, can have a significant impact on system reliability.
Cry for help
One day we received a request to help with an unstable Rails application in our inbox. They were experiencing frequent outages or slowdowns, and they were not able to identify the root…
Apply to speak at Rails World 2025
CFP is open until April 10th
The Rails World 2025 Call for Papers is now open!
This year we are looking for talks that highlight the power and competitive advantage of Rails through real-world case studies, deep technical dives, best practices, or problem-solving discussions, as well as stories of how Rails enables solo developers and small and mid-sized companies to build and scale (both apps and businesses) with ease. Find more info about possible themes below.
Rails World will take place on September 4 & 5th, 2025 in a familiar location: the Beurs van Berlage in Amsterdam. This year there will be 24 talks and keynotes across two tracks and approximately 800 attendees. As always,…
Welcome to another edition of This Week in #dev, a series of posts where we bring some of our most interesting Slack conversations to the public.
URL-Safe serialization for any Ruby object
Matheus Richard shares a gem called Universal ID that can serialize any Ruby object into a URL-safe string. This is a generalization of Rails’ Global ID.
uri = URI::UID.build(:demo).to_s
#=> "uid://universalid/iwKA1gBkZW1vAw#CwWAkccHf6ZTeW1ib2wD"
Configuring Rails Generators to Use FactoryBot with Minitest
Louis Antonopoulos provides guidance for Minitest users on configuring Rails’ generators to use FactoryBot instead of fixtures.
To set up:
- Add
gem "minitest-rails", "~>…
Reviving a Ruby Project with Git: Organizing Branches for Stability
March 6, 2025 Introduction Recently, I spent time bringing a Ruby project back on track. The project had a poor test suite and lacked code organization, leading to frequent deployment errors. One of the major issues was the disorganized branching strategy, which resulted in what I call "spaghetti branches." To ensure stability and minimize deployment … Continue reading Reviving a Ruby Project with Git: Organizing Branches for Stability
On the state of Ractors in Ruby
#741 — March 6, 2025
Ruby Weekly

What’s the Deal with Ractors? — Introduced in Ruby 3.0, Ractors provide an actor-based, truly parallel (bye GVL!) execution model, but they still remain experimental and any idea of their widespread use hasn’t panned out. Jean digs into what makes them tick, what they offer, and why they still have their uses, despite the current shortcomings.
Jean Boussier
💡 If you'd prefer a more introductory piece to ractors, this tutorial by Mirosław Pragłowski covers the practical bases of using them.

Optimize Ruby App Performance in Real-Time — Visualize Ruby…
When we are running Rails migrations, it’s common to combine multiple changes into a single change_table block especially when we want to keep database schema in sync.
Before Rails 7.1
Previously the
validate_constraint
and
validate_check_constraint
was called outside of the
change_table
block to check constraint and its validations into two distinct steps
For example:
class AddNameColumnsAndConstraintToUser < ActiveRecord::Migration[7.0]
def change
change_table :user, bulk: true do |t|
t.string :first_name
t.string :last_name
t.check_constraint "first_name IS NOT NULL AND last_name IS NOT NULL",
name: "name_not_null", validate: false
end
validat…
After
Rails 7.1 added the enhancement, we can now write cleaner migrations by combining column additions and constraint validations within a single change_table block.
def validate_constraint(*args)
…
Joe Masilotti on Hotwire Native Updates, Challenges, and Opportunities - RUBY_672
In the first part of Build a Notion-like editor with Rails article, the foundation was built by creating the data model and the basic HTML layout. This article continues where that article ended.
Besides making things look a fair bit prettier with Tailwind CSS, there will also be a fair amount of JavaScript written using Stimulus.
Above GIF is what the aim is for this second part.
Updating the UI with Tailwind CSS
Let’s update the two views that are there now. While I often look at bare HTML to focus on the functionality first, the designer in me needs to add some CSS rather sooner than later. Let’s update some of the partials to make things more editor-like:
#…
CVE-2025-27111 (rack): Escape Sequence Injection vulnerability in Rack lead to Possible Log Injection
Gurman with the scoop, summarized by MacRumors:
An updated version of the Mac Studio could launch as soon as this week, reports Bloomberg's Mark Gurman. The new machine is expected to be equipped with the M4 Max chip that we first saw in the 2024 MacBook Pro models, but Apple apparently does not have an M4 Ultra chip ready to go. Instead, there could be a version of the Mac Studio that uses an M3 Ultra chip. Apple didn't release an M3 Ultra chip alongside the M3 chip lineup, so it would be a new chip even though it's not part of the current M4 family. The current Mac Studio has an M2 Ultra chip, as does the Mac Pro.
Releasing a previous-generation, higher-end chip is utterly routine…
Last night, Aaron shared the week-old Claude Code demo, and I was pretty blown away by it:
I've tried the "agentic" features of some editors (like Cursor's "YOLO" mode) and have been woefully disappointed by how shitty the UX always is. They often break on basic focus changes, hang at random, and frequently require fussy user intervention with a GUI. Claude Code, however, is a simple REPL, which is all I've ever really wanted from a coding assistant. Specifically, I want to be able to write a test in my editor and then tell a CLI to go implement code to pass the test and let it churn as long as it needs.
Of course, I didn't want to actually try Claude Code, because it would have…
Insprired by a recent blog post of Bohidar Batsov I decided to simplify my Zshrc.
About 10ish years ago, I started to use Zsh and used the Oh-My-Zsh distribution for a pleasant OOTB experience. But over the years, I don’t really use most of the stuff, but never really took the time to clean it up, as having NO zsh config just leaves a very ugly prompt by default.
As Bohidar, I also added Starship as prompt. This provides a nice framework for customizing and extending the prompt.
You can find the full zshrc on my dotfiles. Stuff, that you need to install:
Nick dropped by the (virtual) studio to talk about how things have been going in the ruby community.
Sponsors
Hosting for The Ruby on Rails Podcast is provided by Fireside.fm. If you want to start a podcast and are looking for hosting, visit fireside.fm/rails to get started.
Alright, let’s talk about deploying code without having a full-blown panic attack. You ever push something live and immediately regret it? Like, ‘Oh no, I just nuked the homepage’? Well, guess what—Flipper’s got your back. Ship your code whenever you want, roll out features on your schedule, and if something goes sideways? Boom. Roll it back. No redeploy, no drama. Plus, you get multi-environment sync, audit…
Rails 8 assets: Break down of how Propshaft and importmap-rails work together

Over the years, we've identified several excellent ways to kill landing page conversions. If you're interested in repeating (or learning from) our mistakes, we've decided to share!
Evil Martians' website reaches 0.5M+ developers and CTOs yearly. The goal of our website and blog is to make the case for our expertise and services, and to convert our tech readers into clients. It hasn't always been smooth sailing. In fact, over the years, we've identified several excellent ways to kill landing page conversions. If you're interested in…
Ractor - getting started
Ractor - getting started
This is just my notes from learning. Just remember:
warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues.
You have been warned. Let’s start:
Creating an actor
A simple actor is created as follows:
simple = Ractor.new do
# do something
end
You can pass arguments to a created actor using the actor’s initializer. You can also set a name for an actor here.
Arguments that are passed to Ractor.new()
become block parameters for the given block. However, an interpreter does not pass the parameter object references, but rather sends them as messages.
obj = Object.new
val = "I'm a value"
s…

If you are building a dynamic web application, you will need to access and process the data submitted by the user on the server. This data could arrive in a number of ways:
- the user might upload a photo,
- write a comment,
- post a tweet,
- submit a form, or
- click a link to an article they want to read.
Regardless of the way by which the data is sent, you want to read this data on the server to do something useful, such as saving that photo, storing the comment / tweet in the database, access the form data, or find the article from the database.
The big question is: How can you access this data on the server, in your Rails application?
The…
Maybe you trust your db/seeds.rb
file to be idempotent when you run
bin/rails db:seed,
and maybe you don’t, but either way, you should test it so you can be sure that it does what you think
it does.
Doing so is simple! Let’s run through the process.
Here’s a sample seed file:
- We want it to create users or update them if they already exist
- We want it to create blog posts or return them unchanged if they already exist
# db/seeds.rb
require "factory_bot_rails"
class Seeder
include FactoryBot::Syntax::Methods
def create_or_update_user(name:, is_a_robot:)
if (user = User.find_by(name:))
user.update!(is_a_robot:)
user
else
create :user, is_a_robot:
end
…
How many times have you heard or read statements like these in tech discussions?
"Everything needs to be a single-page app these days. Server-rendered templates are holding you back."
"Web components are the future. Why tie yourself to any framework?"
"Islands architecture is the way forward. We were…
CVE-2025-27590 (oxidized-web): Oxidized Web RANCID migration page allows unauthenticated user to gain control over Linux user account
https://graceful.dev/97165-2/?utm_source=rss&utm_medium=rss&utm_campaign=97165-2
Don’t use a ternary when an and
will do:


Learn to use AV1 to make videos on your website smaller and better quality. CLI instructions and cross-browser tricks.
Instantly improve the online viewing experience for your users by embracing the new AV1 video format, already supported by Chrome, Safari and Firefox. This short guide will also show how to replace your GIFs with videos using AV1 or H.264, and how to make your files twenty to forty times smaller.
The Pitchfork Story
A bit more than two years ago, as part of my work in Shopify’s Ruby and Rails Infrastructure team, I released a new Ruby HTTP server called Pitchfork.
It has a bit of an unusual design and makes hard tradeoffs, so I’d like to explain the thought process behind these decisions and how I see the future of that project.
Unicorn’s Design Is Fine
Ever since I joined Shopify over 11 years ago, the main monolith application has been using Unicorn as its application server in production. I know that Unicorn is seen as legacy software by many if not most Rubyists, including Unicorn’s own maintainer, but I very strongly disagree with this opinion.
A major argument against Unicorn is that Rails…
CVE-2025-27221 (uri): CVE-2025-27221 - userinfo leakage in URI#join, URI#merge and URI#+.
Direct link to podcast audio file
Turns out I'd accidentally been letting some of your e-mail get filtered as junk mail. I want to be clear that I don't think you're junk, Apple does. Write in with your feelings to podcast@searls.co and I'll read it, assuming I get it.
Video of this edition of the show is up on YouTube.
Without further ado, links!
- POSSE Party
- Aaron's puns, ranked
- Don't invite anyone you like to a measles party
- Sorry vegans, plants can feel pain
- Reddit will add a paywall
- Junior developers know how to code even less than usual
- GPT 4.5 is a lemon 🍋
- Insecure code is how you get Nazis
- Ben AI shows off how the hustle bros are thriving with AI
- This is the video I'd…
Becoming a Great Facilitator: Tips and Tricks for Engineering Leaders
Imagine it’s mid-afternoon — your coffee’s aroma is strong, you’re just past your slump, and you’re logging into a virtual whiteboard session organized by your Product Manager. You tap the sticky note icon, and soon the board bursts into a kaleidoscope of ideas as your teammates contribute. Sound familiar? We’ve all been part of these sessions. But how often have you taken the lead to run one yourself — whether as a People Empowerer (what we call Engineering Managers at Gusto), Technical Project Lead, or Senior Engineer? Facilitation is a challenging yet essential skill, and I’m here to share my tips, tricks, and personal anecdotes to help you master it.