Rails 7: Turbo Your Rails •WIP•

HotWire and Turbo Rails are now first-class citizens in Rails. That means that Hotwire is the default way to implement a Rails app. If you are using Rails as an API-only backend, this likely does not affect you. However, it’s important when structuring a new Rails app to think about how much navigational control you will want to delegate to Rails’s Turbo system and/or how much you want to implement as a single-page app (for example, using a front-end routing system instead of Turbo).

In this crash minicourse I’ll cover Rails 7 only, its major parts and key elements benefits, whats new, what’s changed, and why. Although Rails remains an excellent option for API-only backends (create your rails app with --api-only), Rails 7 major improvements are around the frontend and the new Turbo, Stimulus, and Hotwire paradigms. It is not recommended that you mix these paradigms with Javascript-heavy frontends, like React, Angular, Vue, etc. It’s either—or, and here’s my brief recommendation:

Most dashboard-like apps, apps like Facebook, Github, Shopify, Basecamp, etc will fly just fine using Rails Turbo. Paradigmatically, your business logic will remain on the server (primarily), and you won’t write much business logic into Javascript or the frontend layer.

That will cover 80% of apps out there. These apps need a lot of quick user interaction that treats the client as a dumb terminal and leaves the view rendering to Rails.

The kinds of apps that Turbo Rails will not be suitable for are apps which are necessarily data-heavy on the frontend or apps that require specific animations when flipping between views. (Turbo Rails handles your transitions and the options are limited.)

For example: charts & graphs, interactive gaming experiences, super interactive/immersive VR experiences, highly immersive mobile or browser experiences. Also, apps that need specific animations between steps (like games). For these apps, you need the data to be very close to the user, and you want to harness that fact to build highly interactive or animated experiences. For these kinds of apps you might do best to consider a more data-centric frontend paradigm.

Unless you want to split you app into different sections, I would not recommend mixing & matching React, Vue, Angular, etc with Turbo Rails. Turbo Rails is an all-in solution that takes over all link clicks and forms on your website. You must know how it works or else you will be thrown off and get unexpected errors. In this lesson, I will cover Turbo Rails, Hotwire, and Stimulus to set you up for success with Rails 7.

(For my apps, sometimes I build do build some sections of the app in React while still using Turbo Rails for the primary navigation. However, I am very careful to make sure to separate my React parts from the Turbo Rails interactions and it takes more work. To find out my about this, see Option B in my Rails Heart React Series.)


What is Turbo Rails?

Turbo Rails is a collection of Javascript that operations behind the scenes and also an implementation of pattern for how Rails responds to requests on the backend

Importantly, our Rails app is now made up of turbo-frames, that look like this:

<turbo-frame id="new_message">
<form action="/messages" method="post">
...
</form>
</turbo-frame>

Here’s the explanation of what a Turbo Frame is, from the Turbo manual:

Turbo Frames allow predefined parts of a page to be updated on request. Any links and forms inside a frame are captured, and the frame contents automatically updated after receiving a response. Regardless of whether the server provides a full document, or just a fragment containing an updated version of the requested frame, only that particular frame will be extracted from the response to replace the existing content.

https://turbo.hotwired.dev/handbook/frames

• Turbo will intercept your links and forms. Yes, you! Yes, all of them. Unless you explicitly specify to disable it, all of your forms sent to the backend and links to new pages will operate differently from a traditional web app. They will be sent as TURBO_STREAM requests and Turbo will manage the page to swap out the relevant pieces of content.

In the Rails console that looks like this:

When you submit the form, the controller will process a TURBO_STREAM response.

Importantly, when there’s a failure, Rails now sends back an HTTP status code 422 (Unprocessable Entity).

A standard Rails respond block in a Turbo app might look something like this:

respond_to do |format|
format.turbo_stream
format.html
end

You’ll need to have partials that end with .turbo_stream.erb

The trick to using Turbo Stream:

In the partial, make sure that you are explicitly naming a replace whose id exactly matches an existing turbo-frame on the page.

Do I have to use Turbo Rails?

You do not, and for a Rails API-only application, it probably is a good idea to disable it.