Building a Real Time Scoreboard with Ruby on Rails and CableReady

The release of Hotwire in late 2020 brought attention to a growing interest within the Rails community in building modern, reactive Rails applications without needing the complexity of an API + SPA.

Although Hotwire’s Turbo library garnered a lot of attention, the Rails community has been working for years to improve the toolset we have to build modern, full-stack Rails applications. Turbo isn’t the first attempt at giving Rails developers the tools they need.

One of the most important of these projects is CableReady, which powers StimulusReflex and Optimism, along with standing on its own as a tool to:

Create great real-time user experiences by triggering client-side DOM changes, events and notifications over ActionCable web sockets

Source: CableReady Welcome

Today we’re going to explore CableReady by using Rails, CableReady, and Stimulus to build a scoreboard that updates for viewers in real-time, with just a few lines of Ruby and JavaScript.

When we’re finished, our scoreboard will look like this:

A screen recording of a user with a web page and a terminal window open. On the page are the scores for two teams, Miami and Dallas. The user types a command in the terminal to update the home team's score to 95 and, after the command runs, the score on the web page for Miami updates to 95.

This article assumes that you’re comfortable working with Rails but you won’t need any prior knowledge of CableReady or ActionCable to follow along. If you’ve never used Rails before, this article isn’t the best place to start.

Let’s dive in!

Read the rest 19-minute read


Conditional Rendering With Turbo Stream Broadcasts

A very common pattern in Rails development is for a view to contain checks for things like current_user.can?(:take_some_action). These types of checks are common, especially in B2B applications that implement role-based permissions powered by a solution like Pundit.

So, naturally, when a Rails developer begins working with Turbo Stream broadcasts, they wonder how to access the current_user or other session-level variables. The short answer? You can’t.

Partials rendered via a stream broadcast have to be free of global variables or they’ll throw an error because they are not rendered within the context of a specific request. Without that request context variables like current_user will always be undefined.

While we can’t access global variables from a broadcast, we can, with creative use of Turbo Frames, still deliver real-time broadcasts that retain access to key variables like current_user.

To demonstrate the concept today we’re going to build a simple application that displays a list of Spies.

Each spy will have a mission; however, not everyone will be able to see the spy’s mission. Only visitors with secret clearance can see the mission field. Everyone else will see a “Classified” string in place of the mission.

When a new spy is created, we’ll broadcast an update to any viewers of the spy list. Viewers with clearance will see the mission for the newly created spy, viewers without won’t.

The end result will work like this:

A screen recording of a user with two windows open to the same webpage. The webpage displays a list of names, with a header that reads Spies. In one window the user sees a message that they have secret clearance, in the other they don't. The user creates a new spy by entering a name and the new spy ges added to the list of spies already on the page. In the window with secret clearance, the user sees newly created spy's mission, in the other, they don't.

This article will be most useful for folks who are already comfortable with Ruby on Rails and who have a little experience with Turbo already. If you’re comfortable with Rails but you’ve never used Turbo before, an article like this might be a better introduction.

As usual, you’ll find the full code for this article on GitHub.

Ready? Let’s get started.

Read the rest 18-minute read


Turbo Streams on Rails

Turbo, part of the Hotwire tripartite, helps you build modern, performant web applications with dramatically less custom JavaScript.

Turbo is composed of Turbo Drive, Turbo Frames, Turbo Streams, and Turbo Native. Each is a valuable piece of the puzzle but today we’re going to focus on Turbo Streams.

Turbo Streams “deliver page changes over WebSocket, Server-Sent Events, or in response to form submissions” and they might be the most exciting part of the Turbo package.

Streams allow you to deliver fast and efficient user experiences with minimal effort and, for Rails developers, you’ll find that streams fit comfortably into your existing toolkit.

With just a few lines of code, you can send tiny snippets of HTML over the wire and and use those snippets to update the DOM with no custom JavaScript.

For fancier use cases, you can broadcast changes over a WebSocket connection to keep every interested user updated without a refresh. No custom JavaScript to write, just HTML and a little bit of Ruby.

What’s missing?

One of the challenges of new web development tools is that documentation can be sparse, and that’s no different with Hotwire and Turbo.

Official documentation exists, and the introduction video demoing Hotwire does a good job showing how Hotwire works, but comprehensive guides and documentation clearly outlining the various options you have when using Hotwire aren’t all the way there yet.

Streams are powerful but, with limited documentation, getting up to speed can be daunting.

So, today I’m going to share a bit of what I’ve learned from using Turbo Streams in a variety of applications, from small experiments to production-grade applications, to help you get value from Turbo Streams in your Rails application faster.

Read the rest 17-minute read


Instant search with Rails and Hotwire

Last year I wrote an article on building an instant search form with Rails and Stimulus. Since then, Turbo, the other half of Hotwire for the web has been released and the Hotwire stack is now the default for new applications in Rails 7.

Turbo opens the door for an even simpler, cleaner implementation of an instant search form.

So, today we’re taking another look at how to build a search-as-you-type interface that allows us to query our database for matches and update the UI with those matches (almost) instantly.

When we’re done, our code will look almost identical to what you’re used to writing to build Rails applications, and the only JavaScript we’ll need will be to trigger form submissions as the user types.

The finished product will work like this:

A screen recording of a user typing in a word to search a list of Dallas Mavericks basketball players. As they type, the list of players updates automatically.

I’m writing this assuming that you’re comfortable with Ruby on Rails - you won’t need any knowledge of the Hotwire stack and you’ll find the most value from this article if you’re new to Turbo. While this article uses Stimulus, its core focus is on Turbo, and specifically how to use Turbo Frames in a Rails application.

You can find the complete code for this guide on Github. Follow along with this guide from the main branch, or see the complete implementation in the instant search branch.

Let’s get started.

Read the rest 19-minute read


Handling modal forms with Rails, Tailwind CSS, and Hotwire

The release of the Hotwire package of Stimulus and Turbo has brought a tremendously powerful set of tools to Rails developers who want to bring the speed of a single page application to their users without sacrificing the development speed and happiness that Rails is known for.

Today we are using Hotwire, Rails, and Tailwind CSS to build a modal form submission flow.

With just a little bit of Stimulus and Turbo, we will create a user experience that opens a modal on click, retrieves modal content remotely, and cleanly handles successful form submission and form errors.

This modal flow will help us learn a few of the core concepts of Hotwire while demonstrating how to implement a very common user experience in modern web development.

The finished product will look something like this:

A screen recording of a user on a webpage clicking a link to create a comment, typing a message in the form that opens in a modal, and submitting the form successfully. After submission, the modal closes and the user's message appears in a list of messages on the page.

I am writing this guide assuming that you are comfortable with Ruby on Rails and that you have some level of familiarity with Stimulus. You do not need to be an expert on either.

While we use Tailwind CSS to make our modal implementation simple, you do not need experience with Tailwind. If you prefer, you can implement your own, non-Tailwind modal and still get value from this guide.

You can find the complete code for this project on Github.

Let’s get started.

Read the rest 24-minute read


Building a collapsible sidebar with Stimulus and Tailwind CSS

Today we’re building one of the most common elements in web design - a lefthand sidebar for navigation - using Tailwind CSS and Stimulus.js.

Our sidebar will always take up 100% of the height of the page and we’ll be able to expand and collapse the sidebar by clicking a button. The whole thing will be accomplished with just a bit of Stimulus for the expand/collapse action and a small amount of Tailwind in our markup.

Here’s what it will look like when we’re finished.

A screen recording of a user clicking an icon to collapse and expand a sidebar on a web page

To accomplish this, we’ll start with a plain HTML file, pull in Tailwind CSS to make things look nice, and use Stimulus for interactivity.

I’m writing this assuming a solid understanding of HTML and CSS, and some level of comfort with JavaScript.

If you’ve never seen Tailwind before, some of the classes we add for styling might feel a little odd. You don’t need any knowledge of how Stimulus works, but if you’re brand new you might want to read the Stimulus Handbook to help solidify some concepts as we go.

You can find the complete code for this project on Github.

Let’s dive in.

Read the rest 19-minute read


Remotely loading tabbed content with Ruby on Rails and Hotwire

Hotwire is a set of tools for building web applications by sending HTML instead of JSON over the wire. Hotwire gives us a framework for making DOM updates without writing much, or any, JavaScript while delivering fast, modern-feeling web applications.

In today’s example, we’re building a interface that remotely retrieves a portion of the page content from an endpoint and replaces a targeted portion of the DOM with the response from the endpoint. We’ll build this without writing any JavaScript and with only minor additions to the standard Rails code you already know how to write.

Here is what it will look like when we are finished. We won’t be focused on styling today but our “tabs” will be fully functional and ready for you to add a nice looking Bootstrap or Tailwind skin.

A screen recording of a user toggling between an Awards and Credits tab on a web page, with the content changing on each click

To accomplish this, we will start with a new Rails 6.1 application, install Hotwire in the application, and then walk through the basics of adding Turbo Drive to our views.

I’m writing this assuming that you are comfortable with the basics of Ruby on Rails development and that you’ve never used Hotwire before.

You can find the complete source code for this tutorial on Github.

Let’s dive in.

Read the rest 11-minute read


Using Hotwire and Rails to build a live commenting system

Today we’re exploring Hotwire, a new-old way of building web applications by sending HTML instead of JSON over the wire.

We’ll learn how Hotwire works with Ruby on Rails by building a simple application that allows users to leave comments on a project and see those comments in real-time, without requiring full page turns.

This guide presents an alternative approach to a guide I wrote last year which guides you through creating a similar experience using Stimulus. Either approach is valid and works well. The approach presented today presents a way of delivering the experience without writing any JavaScript code, and should feel very natural for any Ruby on Rails developer.

Here is what it will look like when we are finished. It won’t be pretty, but it will work and we won’t write a single line of JavaScript.

A screen recording of a user typing in a comment in a text input and the comment being added to a list of comments

To accomplish this, we will start with a new Rails 6.1 application, install Hotwire in the application, and then walk through the basics of adding Hotwire to our views and controllers.

I’m writing this assuming that you are comfortable with the basics of Ruby on Rails development and that you’ve never used Hotwire before.

You can find the complete source code for this tutorial on Github.

Let’s dive in.

Read the rest 15-minute read


Building a horizontal slider with Stimulus and Tailwind CSS

Today we’re building a component that is common but deceptively tricky to get right - a horizontal slider with a position indicator and navigation buttons.

We’ll have a list of items of an arbitrary length, and our slider will allow folks to scroll to see every item in the list. As they scroll, indicators below the slider will update to show which items are visible on the screen. Clicking on the indicators will scroll the corresponding item into view. The whole thing is pretty fancy.

Here’s what it will look like when we’re finished.

A screen recording of a user scrolling a web page horizontally across an image gallery with identical images of red shoes

To accomplish this, we’ll start with a plain HTML file, pull in Tailwind CSS to make things look nice, and use Stimulus to build interactivity for our position indicators and navigation buttons.

I’m writing this assuming a solid understanding of HTML and CSS, and some level of comfort with JavaScript. If you’ve never seen Tailwind before, some of the classes we add for styling might feel a little odd. You don’t need any knowledge of how Stimulus works, but if you’re brand new you might want to read the Stimulus Handbook to help solidify some concepts.

Let’s dive in.

Read the rest 20-minute read


Building a video converter with Rails 6 and FFmpeg

Today’s project pulls together a number of built-in Rails tools, plus a couple of incredibly useful open source projects to build a web application that can convert user-uploaded video files to MP4.

To demonstrate some of the modern parts of the standard Rail stack, we’re going to go further than just building a converter. We will enhance the user experience during the upload and conversion process with Active Storage to handle direct file uploads, Action Cable for real-time updates on the video conversion, and Stimulus to dynamically update the DOM without needing a heavy Javascript framework.

Read the rest 33-minute read