DEV Community

Cover image for ViewComponent over Turbo Stream Broadcasts
Rails Designer
Rails Designer

Posted on • Updated on • Originally published at railsdesigner.com

ViewComponent over Turbo Stream Broadcasts

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.

  1. User clicks button to generate a report. In the controller a Report is created with a status of pending.
  2. 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.
  3. 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
Enter fullscreen mode Exit fullscreen mode

(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.

Top comments (0)