This article was originally published on Rails Designer
Turbo Stream Broadcasts allows you to broadcast real-time changes (to multiple users simultaneously). It uses WebSockets (typically via ActionCable) to deliver UI elements directly from the server without requiring custom JavaScript.
It’s often confused with Turbo Stream Responses: delivering UI elements based on responses, ie. fired on controller actions.
They work essentially the same—it’s just when and from where they are send which is different.
- Turbo Stream Broadcasts: through Websockets;
- Turbo Stream Responses: through HTTP responses.
This article focuses on the former: Turbo Stream Responses. I will reference them as Turbo Streams from here.
The official Rails way to send Turbo Streams is from Active Models. I find this in most cases quite elegant!
Examples of when this useful:
- User request a report that takes a few minutes to generate: send a notification when done.
- Another user opens a specific document: broadcast to the first user who is now watching.
- User moved a card, in a kanban board, from one column to the next column.
And the list goes on!
How to broadcast ViewComponent with Turbo Streams
Out-of-the box turbo-rails supports sending partials through websockets as it’s a first-class citizen. This made it initially tricky to send ViewComponents over websockets.
This PR made it possible to send html as the body now too.
So let’s go over the steps for the report generating example.
- User clicks button to generate a report. In the controller a
Report
is created with a status ofpending
. - After a successful create a
turbo_stream
response is send to the browser. Here you can send one of Rails Designer’s Empty States and replace the Create Report button with the Empty State. - Then once the report is created, the status changes to
ready
and a notification is send to the user.
How to do this last step? Like so:
# app/models/report.rb
class Report < ApplicationRecord after_update_commit :notify_user # Shortcut for `after_commit :notify_user, on: :update` private def notify_user # TODO: logic to check status changed from `pending` to `ready` broadcast_append_to( creator, html: ApplicationController.render( NotificationComponent.new( type: "success", data: { stacked: true, message: "New Report Ready", description: "''Rails Designer Intro' now available in your account.", primary_action: {title: "View Now", path: "#"}, secondary_action: {title: "Email to me", path: "#"} } ) ) end
end
(The NotificationComponent
is coming from Rails Designer.)
The important bits are:
- the
html
options that was introduced in this PR -
ApplicationController.render
method (it allows you to render content or templates directly)
And that is all what is needed to render your (Rails Designer) ViewComponents.
Discover more from Coursity
Subscribe to get the latest posts sent to your email.