Searching and filtering with Turbo 8

Today we are going to build on top of an article I published last week to expand our knowledge of Turbo 8’s page refreshes and, as a treat, we will write some beautiful Ruby code along the way.

In this article we are going to add searching and filtering to an existing sortable table interface. We will use Turbo 8 page refreshing, a tiny Stimulus controller, and regular old Rails code to build a solution that maintains the user’s page state and scroll position while they search and filter the results shown in a table, no Turbo Frames or Streams required.

When we are finished, the project will look like this:

This article assumes you are comfortable writing Rails code. You do not need any prior experience with Turbo or Stimulus to follow along. Reading the previous article first will help clarify some of the concepts that we move over quickly in this article. You really should read the previous article before you read this one, but I’m not the boss, live life on the edge if you want.

When you’re ready, dive in.

Read the rest 27-minute read

Building a sortable table with Turbo 8's page refreshes

Scroll-restoring, morphing page refreshes are one of the headline features of Turbo 8. Page refreshes make it easier than ever to build modern, SPA-like experiences with Turbo and Ruby on Rails.

One of the most immediate wins for page refreshes is making it simpler to build search and filter UIs, so today we are going to get practical with Turbo 8 by building a sortable table view with page refreshes. I wrote about building sortable tables with Turbo several years ago; back when that article was written we needed to lean heavily on Turbo Frames. With the new tools in Turbo 8 at our disposal, we can simplify our code to the point that we will be writing code that will look familiar to anyone that’s worked in Rails before. Turbo’s page refreshes blend into the background and let us write simple, efficient controllers and views without sacrificing the smooth feel of a single page application.

The application will allow users to sort a list of Players by their attributes. The players will be displayed in a table, and users will click on the table headers to apply their desired sort order. When we are finished, our project will work like this:

To follow along with this article, you should have be comfortable with Ruby on Rails and have Ruby 3 and Rails 7 ready to run locally. You do not need any experience with Turbo, I will fill you in as we work.

Let’s dive in.

Read the rest 20-minute read

Turbo 8 morphing refreshes on Rails

Turbo 8 was released in February of 2024, to much excitement in the Rails world, and the broader HTML-over-the-wire community. At the top of the list of new features was the combination of tooling that added support for morphing page refreshes and scroll position preservation, powered by idiomorph and the ability to broadcast page refreshes with a new Turbo Stream action.

This combination offers developers a “happier path” to partial page updates. Turbo Stream DOM manipulation actions (like prepend and replace) work well, but they require maintaining separate code paths and have limitations when broadcasting data in applications that need to care about authorization and access levels inside of a team or company setting.

Morphing refreshes are a powerful new tool in the Turbo (and turbo-rails) toolbox but they require a bit of a mental shift to understand and they are not without their drawbacks. Today we are going to explore Turbo 8’s new refresh feature in the context of a Rails application, learning how to use page refreshes, how to use broadcasted refreshes to push updates to all interested users at once, and dig into the pros and cons of refreshes compared to Turbo Stream actions that manipulate the DOM.

Before we begin, this article assumes you have written Rails code before and that you have a basic level of understanding with Turbo and how to use it within a Rails application. If you are not a Rails developer, you may have a hard time following the code at some points.

Let’s dive in.

Read the rest 26-minute read

Reclaiming Time

If all goes well, I have about 2,000 weeks left to live, roughly speaking. That’s 336,000 hours, which is both very many hours and a vanishingly small number of hours left to be alive. Last year — better late than never — I started to think more deeply about the time I have available, and what I do with that time. Not to achieve any grand plans, but to use the time I have remaining thoughtfully and intentionally.

I started by checking my iPhone’s Screen Time. It showed I was spending an average of three hours on my phone every day, but I realized I had no clear memory of those hours. How was I spending three hours per day staring at my phone? Was it scrolling through emails, Twitter, or logging into LinkedIn for unknowable reasons? Endless HackerNews pages and failed attempts to read The New York Times without a subscription? Those idle moments before, during, and after work, plus whole weekends, vanished into the abyss.

A soothing drawing of an individual engrossed in their smartphone, blissfully unaware of the vast, endless abyss that opens up just behind them

Read the rest Five-minute read

Building a modal form with Turbo Stream GET requests and custom stream actions

Turbo 7.2 brought major changes to what you can accomplish with Turbo Streams. To demonstrate those changes, today we are going to build a Turbo Stream-powered modal form without a single Turbo Frame. We will also create our own custom Turbo Stream action that emits a custom event on the browser.

The key technique we will use in this article is an update to the standard method of using Turbo to open and populate modals. Prior to Turbo 7.2, Turbo would not allow GET requests to respond directly with Turbo Streams. Smart folks devised a workaround to this limitation which involved using empty Turbo Frames to sneak in Turbo Stream actions. That workaround still works fine, but it is no longer necessary.

As part of our modal implementation, we will also have a chance to build a custom Turbo Stream action. Custom actions are an entirely new feature added in Turbo 7.2, and we will cover enough to get you started with this new tool in Turbo.

When we are finished our application work like this:

A screen recording of a user on a web page clicking a button to open a modal dialog window on the page. They fill in the sole text input on the form and submit the form. The modal dialog closes and the page beneath is updated with the record the user just created.

To follow along with this article, you will need to be comfortable with Ruby on Rails and you should have some experience using Stimulus. We will move quickly through the Turbo content, so previous exposure to using Turbo Streams will be helpful but is not required. As usual, you can review the complete code for this tutorial on Github.

Let’s get started!

Read the rest 25-minute read

Everyone GET in here! Infinite scroll with Rails, Turbo Streams, and Stimulus

If you have worked with Turbo Streams, you have probably run into a frustrating limitation. From the beginning, Turbo Streams were designed exclusively for handling form submissions, and that was the way it worked. If you wanted to respond to a GET request with a Turbo Stream, you couldn’t, without a clunky workaround.

Until now.

In Turbo 7.2, you can respond to GET requests with Turbo Streams. No more empty Turbo Frame hacks.

To demonstrate, we are going to build a simple Rails application that supports infinite scrolling through a paginated resource using Pagy, Turbo Streams, and a tiny Stimulus controller.

When we are finished, our application will work like this, and we won’t use a single Turbo Frame:

A screen recording of a user scrolling down a web page. As they scroll, new records are appended to the list of records automatically.

Before we begin, you should be comfortable working with Rails and have at least a passing familiarity with Turbo. If you have never used Turbo before, this article will not be the best starting place. This article is an update to an article I published earlier this year. Reviewing the previous article will help you understand why GET Turbo Streams are such an exciting change.

As usual, you can find the completed code for this tutorial on Github.

Let’s get started!

Read the rest 16-minute read

Interactive charts with Ruby on Rails, StimulusReflex, and ApexCharts

Every B2B web app eventually gets charts. Users love them, buyers love them, sales teams love them. Look at all this data! Look how pretty it is! Charts!

I love charts too. So, let’s build a filterable pie chart with Rails and StimulusReflex. Our chart will rely on data from the database, and, because it is 2022, we will be able to update the chart as the user applies a filter without requiring a full page turn.

To render our charts, we will use ApexCharts, but the technique shown in this article will work fine with any other frontend charting library, I just like ApexCharts.

When we are finished, we will have a Rails app with a chart that looks like this:

A screen recording of a user on a web page with a select input and a pie chart visible. The user changes options on the select menu and the data in the pie chart updates to match the data for the newly selected option

(It looks nicer when it isn’t being captured as a low quality gif!)

Before beginning, this article assumes that you are comfortable with Ruby on Rails and that you have a passing familiarity with Stimulus and that you have written a Stimulus controller or two before. You won’t need any prior experience with StimulusReflex to follow along with this article.

As always, you can find the completed code accompanying this article on Github.

Let’s dive in!

Read the rest 15-minute read

Hotwiring Rails Newsletter - August 2022

This newsletter went out via email to the Hotwiring Rails subscriber list, but I know that not everyone wants another email cluttering up their inbox. For those folks, I’ll always publish the full content of the newletter here too, so you can get all the content with none of the emails.

Thoughts or feedback on how I can make this newsletter more valuable? Have something you’d like to include in next month’s edition? Send me an email, or find me on Twitter.

Read the rest Seven-minute read

Rails is back isn't enough

The article below is on a topic that has bothered me for a long time — the lack of opportunity for junior Rails developers — spurred by some recent Twitter energy around Ruby on Rails being “back”. I got mentioned in one of the viral threads about Rails being back which jump started my brain into writing this article, but I don’t write it to admonish folks who are excited about Rails and want to bring in more Rails developers with educational content. I love that work, and appreciate the positive energy, and the commitment to building great content. The Rails is back energy just happened to kick off this train of thought about what the long term outlook of the Rails world is when there are few paths for folks to make their living as junior Rails developers.

2022 is an exciting time for Rails developers.

The release of Rails 7 brought Hotwire into the default Rails package along with new asset bundling solutions to get applications off of the dreaded Webpacker. For fans of Redis, the new Kredis gem is a suggested default for Rails 7 applications, offering tools to make it easier for Rails devs to do fun stuff with Redis.

Outside of officially endorsed Rails projects, the StimulusReflex team is steadily making improvements to StimulusReflex, CableReady, and the related set of projects that make building modern, reactive applications in Rails easier than ever.

Despite all of that excitement, folks in the Rails community have gotten used to dealing with “Is Rails dead? Rails is dead.” questions and comments that discourage developers from choosing Rails for their next project.

“Is Rails dead?” questions are silly if you spend any time keeping up with the Rails ecosystem. Rails isn’t dead, it is alive and kicking, just like it has been for nearly 2 decades. Many billions of dollars have been earned riding the Rails and new businesses continue to be built on the foundation that Rails provides.

As a reaction to “Is Rails dead?”, Rails enthusiasts are leaning into a “Rails is back!” narrative — we aren’t dead, we’ve got all this cool new stuff to share!

I don’t think the noise of “Rails is dead!” and “Rails is back” is particularly interesting. Neither narrative adds any value to the conversation. As a Rails enthusiast (and sometime Rails content creator), I love the idea of “Rails is back”, but I don’t think it gets us where we are trying to go.

Read the rest Eight-minute read

Writing effective coding tutorials

Writing about what you learn, when done well, is a great way to solidify your own knowledge of a topic, stretch yourself professionally, and establish credibility in your field.

In 2020, I started writing tutorial-style articles for Ruby on Rails developers. Writing these articles began as a fun distraction from a stressful job, and as a way to reconnect with web development as a discipline as my day job pulled me further away from regularly writing code. From that beginning as a distracting hobby, I grew to have a passion for writing tutorials as a way to share my knowledge with internet strangers.

Over the last 18 months, my writing has helped me grow my professional network, find new consulting clients, earn a few thousand dollars in (self-published) book sales, and to feel much more confident in my technical skills.

As I’ve worked to improve my own writing, I have read many, many articles from other developers. Many of those articles have been valuable but I also see very common, correctable mistakes from folks who have knowledge to share but struggle with sharing that knowledge effectively.

Today, I’m sharing some of the most common mistakes I see tutorial writers make and how to correct those mistakes to write more effective tutorials. I will also share the simple formula I use when writing new tutorials.

Read the rest 13-minute read